@@ -20,7 +20,7 @@ import * as vscode from "vscode";
20
20
import configuration from "../configuration" ;
21
21
import { SwiftOutputChannel } from "../ui/SwiftOutputChannel" ;
22
22
import { execFile , ExecFileError , execSwift } from "../utilities/utilities" ;
23
- import { expandFilePathTilde , pathExists } from "../utilities/filesystem" ;
23
+ import { expandFilePathTilde , fileExists , pathExists } from "../utilities/filesystem" ;
24
24
import { Version } from "../utilities/version" ;
25
25
import { BuildFlags } from "./BuildFlags" ;
26
26
import { Sanitizer } from "./Sanitizer" ;
@@ -119,7 +119,7 @@ export class SwiftToolchain {
119
119
}
120
120
121
121
static async create ( folder ?: vscode . Uri ) : Promise < SwiftToolchain > {
122
- const swiftFolderPath = await this . getSwiftFolderPath ( ) ;
122
+ const swiftFolderPath = await this . getSwiftFolderPath ( folder ) ;
123
123
const toolchainPath = await this . getToolchainPath ( swiftFolderPath , folder ) ;
124
124
const targetInfo = await this . getSwiftTargetInfo (
125
125
this . _getToolchainExecutable ( toolchainPath , "swift" )
@@ -562,7 +562,7 @@ export class SwiftToolchain {
562
562
channel . logDiagnostic ( this . diagnostics ) ;
563
563
}
564
564
565
- private static async getSwiftFolderPath ( ) : Promise < string > {
565
+ private static async getSwiftFolderPath ( cwd ?: vscode . Uri ) : Promise < string > {
566
566
try {
567
567
let swift : string ;
568
568
if ( configuration . path !== "" ) {
@@ -605,7 +605,17 @@ export class SwiftToolchain {
605
605
}
606
606
}
607
607
// 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
+ }
609
619
const swiftPath = expandFilePathTilde ( path . dirname ( realSwift ) ) ;
610
620
return await this . getSwiftEnvPath ( swiftPath ) ;
611
621
} catch {
@@ -645,11 +655,23 @@ export class SwiftToolchain {
645
655
try {
646
656
switch ( process . platform ) {
647
657
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
+ }
649
671
return path . dirname ( configuration . path ) ;
650
672
}
651
673
652
- const swiftlyToolchainLocation = await this . swiftlyToolchainLocation ( cwd ) ;
674
+ const swiftlyToolchainLocation = await this . swiftlyToolchain ( cwd ) ;
653
675
if ( swiftlyToolchainLocation ) {
654
676
return swiftlyToolchainLocation ;
655
677
}
@@ -669,12 +691,19 @@ export class SwiftToolchain {
669
691
}
670
692
}
671
693
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
+
672
701
/**
673
702
* Determine if Swiftly is being used to manage the active toolchain and if so, return
674
703
* the path to the active toolchain.
675
704
* @returns The location of the active toolchain if swiftly is being used to manage it.
676
705
*/
677
- private static async swiftlyToolchainLocation ( cwd ?: vscode . Uri ) : Promise < string | undefined > {
706
+ private static async swiftlyToolchain ( cwd ?: vscode . Uri ) : Promise < string | undefined > {
678
707
const swiftlyHomeDir : string | undefined = process . env [ "SWIFTLY_HOME_DIR" ] ;
679
708
if ( swiftlyHomeDir ) {
680
709
const { stdout : swiftLocation } = await execFile ( "which" , [ "swift" ] ) ;
@@ -683,17 +712,9 @@ export class SwiftToolchain {
683
712
// is no cwd specified then it returns the global "inUse" toolchain otherwise
684
713
// it respects the .swift-version file in the cwd and resolves using that.
685
714
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" ) ;
697
718
}
698
719
} catch ( err : unknown ) {
699
720
const error = err as ExecFileError ;
0 commit comments