Skip to content

Commit 1c833b1

Browse files
authored
Resolve the swiftly bin path (#1632)
* Resolve the swiftly bin path Was failing to compute the correct lldb-dap path because the user had pointed `swift.path` to `~/.swiftly/bin`. When resolving the path, lldb-dap path ends up being computed as `$PWD/lldb-dap`. To get around this, if we know the provided path is a swiftly bin directory, then resolve the correct swift path and toolchain path using built-in swiftly commands Issue: #1619 * Fix formatting * Address review comment Only use the "use --print-location" approach and share this code * CHANGELOG entry * Don't set environment
1 parent 0190644 commit 1c833b1

File tree

2 files changed

+40
-18
lines changed

2 files changed

+40
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- Make sure activation does not fail when `swift.path` is `null` ([#1616](https://github.com/swiftlang/vscode-swift/pull/1616))
1414
- Fix `Swift: Reset Package Dependencies` command on Windows ([#1614](https://github.com/swiftlang/vscode-swift/pull/1614))
1515
- Activate extension when a .swift source file exists in a subfolder ([#1635](https://github.com/swiftlang/vscode-swift/pull/1635))
16+
- Resolve Swiftly toolchain path ([#1632](https://github.com/swiftlang/vscode-swift/pull/1632))
1617

1718
## 2.4.0 - 2025-06-11
1819

src/toolchain/toolchain.ts

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import * as vscode from "vscode";
2020
import configuration from "../configuration";
2121
import { SwiftOutputChannel } from "../ui/SwiftOutputChannel";
2222
import { execFile, ExecFileError, execSwift } from "../utilities/utilities";
23-
import { expandFilePathTilde, pathExists } from "../utilities/filesystem";
23+
import { expandFilePathTilde, fileExists, pathExists } from "../utilities/filesystem";
2424
import { Version } from "../utilities/version";
2525
import { BuildFlags } from "./BuildFlags";
2626
import { Sanitizer } from "./Sanitizer";
@@ -119,7 +119,7 @@ export class SwiftToolchain {
119119
}
120120

121121
static async create(folder?: vscode.Uri): Promise<SwiftToolchain> {
122-
const swiftFolderPath = await this.getSwiftFolderPath();
122+
const swiftFolderPath = await this.getSwiftFolderPath(folder);
123123
const toolchainPath = await this.getToolchainPath(swiftFolderPath, folder);
124124
const targetInfo = await this.getSwiftTargetInfo(
125125
this._getToolchainExecutable(toolchainPath, "swift")
@@ -562,7 +562,7 @@ export class SwiftToolchain {
562562
channel.logDiagnostic(this.diagnostics);
563563
}
564564

565-
private static async getSwiftFolderPath(): Promise<string> {
565+
private static async getSwiftFolderPath(cwd?: vscode.Uri): Promise<string> {
566566
try {
567567
let swift: string;
568568
if (configuration.path !== "") {
@@ -605,7 +605,17 @@ export class SwiftToolchain {
605605
}
606606
}
607607
// swift may be a symbolic link
608-
const realSwift = await fs.realpath(swift);
608+
let realSwift = await fs.realpath(swift);
609+
if (path.basename(realSwift) === "swiftly") {
610+
try {
611+
const inUse = await this.swiftlyInUseLocation(realSwift, cwd);
612+
if (inUse) {
613+
realSwift = path.join(inUse, "usr", "bin", "swift");
614+
}
615+
} catch {
616+
// Ignore, will fall back to original path
617+
}
618+
}
609619
const swiftPath = expandFilePathTilde(path.dirname(realSwift));
610620
return await this.getSwiftEnvPath(swiftPath);
611621
} catch {
@@ -645,11 +655,23 @@ export class SwiftToolchain {
645655
try {
646656
switch (process.platform) {
647657
case "darwin": {
648-
if (configuration.path !== "") {
658+
const configPath = configuration.path;
659+
if (configPath !== "") {
660+
const swiftlyPath = path.join(configPath, "swiftly");
661+
if (await fileExists(swiftlyPath)) {
662+
try {
663+
const inUse = await this.swiftlyInUseLocation(swiftlyPath, cwd);
664+
if (inUse) {
665+
return path.join(inUse, "usr");
666+
}
667+
} catch {
668+
// Ignore, will fall back to original path
669+
}
670+
}
649671
return path.dirname(configuration.path);
650672
}
651673

652-
const swiftlyToolchainLocation = await this.swiftlyToolchainLocation(cwd);
674+
const swiftlyToolchainLocation = await this.swiftlyToolchain(cwd);
653675
if (swiftlyToolchainLocation) {
654676
return swiftlyToolchainLocation;
655677
}
@@ -669,12 +691,19 @@ export class SwiftToolchain {
669691
}
670692
}
671693

694+
private static async swiftlyInUseLocation(swiftlyPath: string, cwd?: vscode.Uri) {
695+
const { stdout: inUse } = await execFile(swiftlyPath, ["use", "--print-location"], {
696+
cwd: cwd?.fsPath,
697+
});
698+
return inUse.trimEnd();
699+
}
700+
672701
/**
673702
* Determine if Swiftly is being used to manage the active toolchain and if so, return
674703
* the path to the active toolchain.
675704
* @returns The location of the active toolchain if swiftly is being used to manage it.
676705
*/
677-
private static async swiftlyToolchainLocation(cwd?: vscode.Uri): Promise<string | undefined> {
706+
private static async swiftlyToolchain(cwd?: vscode.Uri): Promise<string | undefined> {
678707
const swiftlyHomeDir: string | undefined = process.env["SWIFTLY_HOME_DIR"];
679708
if (swiftlyHomeDir) {
680709
const { stdout: swiftLocation } = await execFile("which", ["swift"]);
@@ -683,17 +712,9 @@ export class SwiftToolchain {
683712
// is no cwd specified then it returns the global "inUse" toolchain otherwise
684713
// it respects the .swift-version file in the cwd and resolves using that.
685714
try {
686-
const { stdout: swiftlyLocation } = await execFile(
687-
"swiftly",
688-
["use", "--print-location"],
689-
{
690-
cwd: cwd?.fsPath,
691-
}
692-
);
693-
694-
const trimmedLocation = swiftlyLocation.trimEnd();
695-
if (trimmedLocation.length > 0) {
696-
return path.join(trimmedLocation, "usr");
715+
const inUse = await this.swiftlyInUseLocation("swiftly", cwd);
716+
if (inUse.length > 0) {
717+
return path.join(inUse, "usr");
697718
}
698719
} catch (err: unknown) {
699720
const error = err as ExecFileError;

0 commit comments

Comments
 (0)