Skip to content

Commit c2116fc

Browse files
detect xcrun shims
1 parent a19d0b1 commit c2116fc

File tree

10 files changed

+344
-399
lines changed

10 files changed

+344
-399
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@
492492
"swift.path": {
493493
"type": "string",
494494
"default": "",
495-
"markdownDescription": "Override the default path of the folder containing the Swift executables. The default is to look in the `PATH` environment variable. This path is also used to search for other executables used by the extension like `sourcekit-lsp` and `lldb`.",
495+
"markdownDescription": "Override the default path of the folder containing the Swift executables. The default is to look in the `PATH` environment variable.",
496496
"scope": "machine-overridable"
497497
},
498498
"swift.buildArguments": {

src/debugger/lldb.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@ export async function getLLDBLibPath(toolchain: SwiftToolchain): Promise<Result<
5252
} catch (error) {
5353
return Result.makeFailure(error);
5454
}
55-
let pathHint = path.dirname(toolchain.swiftFolderPath);
55+
let pathHint = toolchain.toolchainPath;
5656
try {
57-
const statement = `print('<!' + lldb.SBHostOS.GetLLDBPath(lldb.ePathTypeLLDBShlibDir).fullpath + '!>')`;
58-
const args = ["-b", "-O", `script ${statement}`];
57+
const args = [
58+
"-b",
59+
"-O",
60+
`script print('<!' + lldb.SBHostOS.GetLLDBPath(lldb.ePathTypeLLDBShlibDir).fullpath + '!>')`,
61+
];
5962
const { stdout } = await execFile(executable, args);
6063
const m = /^<!([^!]*)!>/m.exec(stdout);
6164
if (m) {
@@ -65,7 +68,7 @@ export async function getLLDBLibPath(toolchain: SwiftToolchain): Promise<Result<
6568
// If we get an error on Windows here we should not attempt to use the fallback path. If it failed
6669
// it is most likely due to lldb failing to run because $PYHTONHOME environment variable is setup
6770
// incorrectly (this is the case in Swift < 5.7). In this situation swift lldb does not work so we
68-
// should just the version of lldb that comes with CodeLLDB. We return a failure with no message
71+
// should just use the version of lldb that comes with CodeLLDB. We return a failure with no message
6972
// to indicate we want it to fail silently.
7073
if (process.platform === "win32") {
7174
return Result.makeFailure(undefined);
@@ -79,7 +82,7 @@ export async function getLLDBLibPath(toolchain: SwiftToolchain): Promise<Result<
7982
}
8083
}
8184

82-
export async function findLibLLDB(pathHint: string): Promise<string | undefined> {
85+
async function findLibLLDB(pathHint: string): Promise<string | undefined> {
8386
const stat = await fs.stat(pathHint);
8487
if (stat.isFile()) {
8588
return pathHint;
@@ -109,7 +112,7 @@ export async function findLibLLDB(pathHint: string): Promise<string | undefined>
109112
return undefined;
110113
}
111114

112-
export async function findFileByPattern(path: string, pattern: RegExp): Promise<string | null> {
115+
async function findFileByPattern(path: string, pattern: RegExp): Promise<string | null> {
113116
try {
114117
const files = await fs.readdir(path);
115118
for (const file of files) {

src/toolchain/swiftly.ts

Lines changed: 37 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { ContextKeys } from "../contextKeys";
2727
import { SwiftLogger } from "../logging/SwiftLogger";
2828
import { showMissingToolchainDialog } from "../ui/ToolchainSelection";
2929
import { touch } from "../utilities/filesystem";
30-
import { findBinaryPath } from "../utilities/shell";
30+
import { findBinaryInPath } from "../utilities/shell";
3131
import { ExecFileError, execFile, execFileStreamOutput } from "../utilities/utilities";
3232
import { Version } from "../utilities/version";
3333
import { SwiftlyConfig } from "./ToolchainVersion";
@@ -359,72 +359,49 @@ export class Swiftly {
359359
}
360360

361361
/**
362-
* Determine if Swiftly is being used to manage the active toolchain and if so, return
363-
* the path to the active toolchain.
362+
* Determine whether or not the given swift binary is managed by swiftly.
364363
*
365-
* @returns The location of the active toolchain if swiftly is being used to manage it.
364+
* @param swiftBinaryPath The path to the swift binary.
365+
* @returns A boolean indicating whether or not the swift binary is managed by swiftly.
366366
*/
367-
public static async toolchain(
368-
extensionRoot: string,
369-
logger?: SwiftLogger,
370-
cwd?: vscode.Uri
371-
): Promise<string | undefined> {
367+
public static async isManagedBySwiftly(swiftBinaryPath: string): Promise<boolean> {
372368
const swiftlyHomeDir: string | undefined = process.env["SWIFTLY_HOME_DIR"];
373-
if (swiftlyHomeDir) {
374-
const { stdout: swiftLocation } = await execFile("which", ["swift"]);
375-
if (swiftLocation.startsWith(swiftlyHomeDir)) {
376-
// Print the location of the toolchain that swiftly is using. If there
377-
// is no cwd specified then it returns the global "inUse" toolchain otherwise
378-
// it respects the .swift-version file in the cwd and resolves using that.
379-
try {
380-
const inUse = await Swiftly.inUseLocation("swiftly", cwd);
381-
if (inUse.length > 0) {
382-
return path.join(inUse, "usr");
383-
}
384-
} catch (err: unknown) {
385-
logger?.error(`Failed to retrieve Swiftly installations: ${err}`);
386-
const error = err as ExecFileError;
387-
388-
// Check if this is a missing toolchain error
389-
const missingToolchainError = parseSwiftlyMissingToolchainError(error.stderr);
390-
if (missingToolchainError) {
391-
// Attempt automatic installation
392-
const installed = await handleMissingSwiftlyToolchain(
393-
missingToolchainError.version,
394-
extensionRoot,
395-
logger,
396-
cwd
397-
);
398-
399-
if (installed) {
400-
// Retry toolchain location after successful installation
401-
try {
402-
const retryInUse = await Swiftly.inUseLocation("swiftly", cwd);
403-
if (retryInUse.length > 0) {
404-
return path.join(retryInUse, "usr");
405-
}
406-
} catch (retryError) {
407-
logger?.error(
408-
`Failed to use toolchain after installation: ${retryError}`
409-
);
410-
}
411-
} else {
412-
// User declined installation - gracefully fall back to global toolchain
413-
logger?.info(
414-
`Falling back to global toolchain after user declined installation of missing toolchain: ${missingToolchainError.version}`
415-
);
416-
return undefined;
417-
}
418-
}
369+
if (!swiftlyHomeDir) {
370+
return false;
371+
}
372+
return swiftBinaryPath.startsWith(swiftlyHomeDir);
373+
}
419374

420-
// Fall back to original error handling for non-missing-toolchain errors
421-
void vscode.window.showErrorMessage(
422-
`Failed to load toolchain from Swiftly: ${error.stderr}`
375+
public static async getActiveToolchain(
376+
extensionRoot: string,
377+
cwd?: vscode.Uri,
378+
logger?: SwiftLogger
379+
): Promise<string> {
380+
try {
381+
return await Swiftly.inUseLocation("swiftly", cwd);
382+
} catch (error: unknown) {
383+
if (error instanceof ExecFileError) {
384+
// Check if this is a missing toolchain error
385+
const missingToolchainError = parseSwiftlyMissingToolchainError(error.stderr);
386+
if (missingToolchainError) {
387+
// Attempt automatic installation
388+
const installed = await handleMissingSwiftlyToolchain(
389+
missingToolchainError.version,
390+
extensionRoot,
391+
logger,
392+
cwd
423393
);
394+
if (installed) {
395+
// Retry toolchain location after successful installation
396+
return await this.getActiveToolchain(extensionRoot, cwd, logger);
397+
}
424398
}
425399
}
400+
// We were unable to resolve the active swift toolchain.
401+
throw Error("Failed to determine the active swift toolchain via swiftly.", {
402+
cause: error,
403+
});
426404
}
427-
return undefined;
428405
}
429406

430407
/**
@@ -901,8 +878,7 @@ export class Swiftly {
901878
return false;
902879
}
903880
try {
904-
await findBinaryPath("swiftly");
905-
return true;
881+
return (await findBinaryInPath("swiftly")).length > 0;
906882
} catch (error) {
907883
return false;
908884
}

0 commit comments

Comments
 (0)