Skip to content

Commit 9232257

Browse files
committed
Deeper integration of swift.disableSwiftPMIntegration setting
The `disableSwiftPMIntegration` setting prevented `Package.swift` files from activating the extension, but if the extension is activated via compile_commands or bsp integration we still attempt package operations like `swift package describe` when setting up a `FolderContext`. If SwiftPM integration has been disabled, return an empty package representation with no targets or dependencies so that the extension still activates quickly and provides language features from sourcekit-lsp without attempting to use SwiftPM. Issue: #1925
1 parent 92c28e6 commit 9232257

File tree

4 files changed

+97
-20
lines changed

4 files changed

+97
-20
lines changed

src/FolderContext.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { TestExplorer } from "./TestExplorer/TestExplorer";
2222
import { TestRunManager } from "./TestExplorer/TestRunManager";
2323
import { TestRunProxy } from "./TestExplorer/TestRunner";
2424
import { FolderOperation, WorkspaceContext } from "./WorkspaceContext";
25+
import configuration from "./configuration";
2526
import { SwiftLogger } from "./logging/SwiftLogger";
2627
import { TaskQueue } from "./tasks/TaskQueue";
2728
import { SwiftToolchain } from "./toolchain/toolchain";
@@ -135,7 +136,11 @@ export class FolderContext implements vscode.Disposable {
135136
const { linuxMain, swiftPackage } =
136137
await workspaceContext.statusItem.showStatusWhileRunning(statusItemText, async () => {
137138
const linuxMain = await LinuxMain.create(folder);
138-
const swiftPackage = await SwiftPackage.create(folder, toolchain);
139+
const swiftPackage = await SwiftPackage.create(
140+
folder,
141+
toolchain,
142+
configuration.disableSwiftPMIntegration
143+
);
139144
return { linuxMain, swiftPackage };
140145
});
141146
workspaceContext.statusItem.end(statusItemText);
@@ -193,7 +198,7 @@ export class FolderContext implements vscode.Disposable {
193198

194199
/** reload swift package for this folder */
195200
async reload() {
196-
await this.swiftPackage.reload(this.toolchain);
201+
await this.swiftPackage.reload(this.toolchain, configuration.disableSwiftPMIntegration);
197202
}
198203

199204
/** reload Package.resolved for this folder */
@@ -208,7 +213,11 @@ export class FolderContext implements vscode.Disposable {
208213

209214
/** Load Swift Plugins and store in Package */
210215
async loadSwiftPlugins(logger: SwiftLogger) {
211-
await this.swiftPackage.loadSwiftPlugins(this.toolchain, logger);
216+
await this.swiftPackage.loadSwiftPlugins(
217+
this.toolchain,
218+
logger,
219+
configuration.disableSwiftPMIntegration
220+
);
212221
}
213222

214223
/**

src/SwiftPackage.ts

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,19 +211,22 @@ export class SwiftPackage {
211211
/**
212212
* Create a SwiftPackage from a folder
213213
* @param folder folder package is in
214+
* @param toolchain Swift toolchain to use
215+
* @param disableSwiftPMIntegration Whether to disable SwiftPM integration
214216
* @returns new SwiftPackage
215217
*/
216218
public static async create(
217219
folder: vscode.Uri,
218-
toolchain: SwiftToolchain
220+
toolchain: SwiftToolchain,
221+
disableSwiftPMIntegration: boolean = false
219222
): Promise<SwiftPackage> {
220223
const [resolved, workspaceState] = await Promise.all([
221224
SwiftPackage.loadPackageResolved(folder),
222225
SwiftPackage.loadWorkspaceState(folder),
223226
]);
224227
return new SwiftPackage(
225228
folder,
226-
SwiftPackage.loadPackage(folder, toolchain),
229+
SwiftPackage.loadPackage(folder, toolchain, disableSwiftPMIntegration),
227230
resolved,
228231
workspaceState
229232
);
@@ -250,12 +253,25 @@ export class SwiftPackage {
250253
/**
251254
* Run `swift package describe` and return results
252255
* @param folder folder package is in
256+
* @param toolchain Swift toolchain to use
257+
* @param disableSwiftPMIntegration Whether to disable SwiftPM integration
253258
* @returns results of `swift package describe`
254259
*/
255260
static async loadPackage(
256261
folder: vscode.Uri,
257-
toolchain: SwiftToolchain
262+
toolchain: SwiftToolchain,
263+
disableSwiftPMIntegration: boolean = false
258264
): Promise<SwiftPackageState> {
265+
// When SwiftPM integration is disabled, return empty package structure
266+
if (disableSwiftPMIntegration) {
267+
return {
268+
name: path.basename(folder.fsPath),
269+
products: [],
270+
dependencies: [],
271+
targets: [],
272+
};
273+
}
274+
259275
try {
260276
// Use swift package describe to describe the package targets, products, and platforms
261277
const describe = await execSwift(["package", "describe", "--type", "json"], toolchain, {
@@ -312,17 +328,23 @@ export class SwiftPackage {
312328
private static async loadPlugins(
313329
folder: vscode.Uri,
314330
toolchain: SwiftToolchain,
315-
logger: SwiftLogger
331+
logger: SwiftLogger,
332+
disableSwiftPMIntegration: boolean = false
316333
): Promise<PackagePlugin[]> {
334+
// When SwiftPM integration is disabled, return empty plugin list
335+
if (disableSwiftPMIntegration) {
336+
return [];
337+
}
338+
317339
try {
318340
const { stdout } = await execSwift(["package", "plugin", "--list"], toolchain, {
319341
cwd: folder.fsPath,
320342
});
321343
const plugins: PackagePlugin[] = [];
322344
const lines = stdout.split(lineBreakRegex).map(item => item.trim());
323345
for (const line of lines) {
324-
// generate-documentation (plugin Swift-DocC in package SwiftDocCPlugin)
325-
const pluginMatch = /^(.*) \(plugin (.*) in package (.*)\)/.exec(line);
346+
// 'generate-documentation' (plugin 'Swift-DocC' in package 'SwiftDocCPlugin')
347+
const pluginMatch = /^'(.*)' \(plugin '(.*)' in package '(.*)'\)/.exec(line);
326348
if (pluginMatch) {
327349
plugins.push({
328350
command: pluginMatch[1],
@@ -360,8 +382,12 @@ export class SwiftPackage {
360382
}
361383

362384
/** Reload swift package */
363-
public async reload(toolchain: SwiftToolchain) {
364-
const loadedContents = await SwiftPackage.loadPackage(this.folder, toolchain);
385+
public async reload(toolchain: SwiftToolchain, disableSwiftPMIntegration: boolean = false) {
386+
const loadedContents = await SwiftPackage.loadPackage(
387+
this.folder,
388+
toolchain,
389+
disableSwiftPMIntegration
390+
);
365391
this._contents = loadedContents;
366392
this.contentsPromise = Promise.resolve(loadedContents);
367393
}
@@ -375,8 +401,17 @@ export class SwiftPackage {
375401
this.workspaceState = await SwiftPackage.loadWorkspaceState(this.folder);
376402
}
377403

378-
public async loadSwiftPlugins(toolchain: SwiftToolchain, logger: SwiftLogger) {
379-
this.plugins = await SwiftPackage.loadPlugins(this.folder, toolchain, logger);
404+
public async loadSwiftPlugins(
405+
toolchain: SwiftToolchain,
406+
logger: SwiftLogger,
407+
disableSwiftPMIntegration: boolean = false
408+
) {
409+
this.plugins = await SwiftPackage.loadPlugins(
410+
this.folder,
411+
toolchain,
412+
logger,
413+
disableSwiftPMIntegration
414+
);
380415
}
381416

382417
/** Return if has valid contents */

src/ui/ProjectPanelProvider.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,8 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
672672
const dependencies = await this.dependencies();
673673
const snippets = await this.snippets();
674674
const commands = await this.commands();
675+
const targets = await this.targets();
676+
const tasks = await this.tasks(folderContext);
675677

676678
// TODO: Control ordering
677679
return [
@@ -685,13 +687,16 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
685687
),
686688
]
687689
: []),
688-
new HeaderNode("targets", "Targets", "book", this.targets.bind(this)),
689-
new HeaderNode(
690-
"tasks",
691-
"Tasks",
692-
"debug-continue-small",
693-
this.tasks.bind(this, folderContext)
694-
),
690+
...(targets.length > 0
691+
? [new HeaderNode("targets", "Targets", "book", () => Promise.resolve(targets))]
692+
: []),
693+
...(tasks.length > 0
694+
? [
695+
new HeaderNode("tasks", "Tasks", "debug-continue-small", () =>
696+
Promise.resolve(tasks)
697+
),
698+
]
699+
: []),
695700
...(snippets.length > 0
696701
? [
697702
new HeaderNode("snippets", "Snippets", "notebook", () =>

test/integration-tests/SwiftPackage.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,32 @@ tag("medium").suite("SwiftPackage Test Suite", function () {
8080
assert.strictEqual(spmPackage.resolved.pins.length, 1);
8181
assert.strictEqual(spmPackage.resolved.pins[0].identity, "swift-log");
8282
});
83+
84+
test("Disabled SwiftPM integration returns empty package", async () => {
85+
const spmPackage = await SwiftPackage.create(
86+
testAssetUri("package2"),
87+
toolchain,
88+
true // disableSwiftPMIntegration
89+
);
90+
assert.strictEqual(await spmPackage.isValid, true);
91+
assert.strictEqual(await spmPackage.name, "package2"); // derived from folder name
92+
assert.strictEqual((await spmPackage.executableProducts).length, 0);
93+
assert.strictEqual((await spmPackage.libraryProducts).length, 0);
94+
assert.strictEqual((await spmPackage.dependencies).length, 0);
95+
assert.strictEqual((await spmPackage.targets).length, 0);
96+
});
97+
98+
test("Reload with disabled SwiftPM integration returns empty package", async () => {
99+
const spmPackage = await SwiftPackage.create(testAssetUri("package2"), toolchain, false);
100+
// First verify it loaded normally
101+
assert.strictEqual(await spmPackage.isValid, true);
102+
assert.strictEqual((await spmPackage.libraryProducts).length, 1);
103+
104+
// Now reload with disabled integration
105+
await spmPackage.reload(toolchain, true);
106+
assert.strictEqual(await spmPackage.isValid, true);
107+
assert.strictEqual((await spmPackage.libraryProducts).length, 0);
108+
assert.strictEqual((await spmPackage.dependencies).length, 0);
109+
assert.strictEqual((await spmPackage.targets).length, 0);
110+
});
83111
});

0 commit comments

Comments
 (0)