@@ -20,7 +20,7 @@ import * as vscode from "vscode";
2020import configuration from "../configuration" ;
2121import { SwiftOutputChannel } from "../ui/SwiftOutputChannel" ;
2222import { execFile , ExecFileError , execSwift } from "../utilities/utilities" ;
23- import { expandFilePathTilde , pathExists } from "../utilities/filesystem" ;
23+ import { expandFilePathTilde , fileExists , pathExists } from "../utilities/filesystem" ;
2424import { Version } from "../utilities/version" ;
2525import { BuildFlags } from "./BuildFlags" ;
2626import { 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