@@ -82,9 +82,10 @@ struct Install: SwiftlyCommand {
8282 }
8383
8484 mutating func run( _ ctx: SwiftlyCoreContext ) async throws {
85- try await validateSwiftly ( ctx)
85+ try await validatedConfig ( ctx)
8686
8787 var config = try await Config . load ( ctx)
88+ let toolchainVersion = try await Self . determineToolchainVersion ( ctx, version: self . version, config: & config)
8889
8990 let ( postInstallScript, pathChanged) = try await Self . execute (
9091 ctx,
@@ -106,20 +107,37 @@ struct Install: SwiftlyCommand {
106107
107108 // Fish doesn't cache its path, so this instruction is not necessary.
108109 if pathChanged && !shell. hasSuffix ( " fish " ) {
109- await ctx. print ( Messages . refreshShell)
110+ await ctx. print (
111+ """
112+ NOTE: Swiftly has updated some elements in your path and your shell may not yet be
113+ aware of the changes. You can update your shell's environment by running
114+
115+ hash -r
116+
117+ or restarting your shell.
118+
119+ """ )
110120 }
111121
112122 if let postInstallScript {
113123 guard let postInstallFile = self . postInstallFile else {
114- throw SwiftlyError ( message: Messages . postInstall ( postInstallScript) )
124+ throw SwiftlyError (
125+ message: """
126+
127+ There are some dependencies that should be installed before using this toolchain.
128+ You can run the following script as the system administrator (e.g. root) to prepare
129+ your system:
130+
131+ \( postInstallScript)
132+ """ )
115133 }
116134
117135 try Data ( postInstallScript. utf8) . write (
118136 to: postInstallFile, options: . atomic
119137 )
120138 }
121- }
122-
139+ }
140+
123141 public static func setupProxies(
124142 _ ctx: SwiftlyCoreContext ,
125143 version: ToolchainVersion ,
@@ -129,21 +147,23 @@ struct Install: SwiftlyCommand {
129147 var pathChanged = false
130148
131149 // Create proxies if we have a location where we can point them
132- if let proxyTo = try ? Swiftly . currentPlatform. findSwiftlyBin ( ctx) {
150+ if let proxyTo = try ? await Swiftly . currentPlatform. findSwiftlyBin ( ctx) {
133151 // Ensure swiftly doesn't overwrite any existing executables without getting confirmation first.
134152 let swiftlyBinDir = Swiftly . currentPlatform. swiftlyBinDir ( ctx)
135153 let swiftlyBinDirContents =
136- ( try ? FileManager . default . contentsOfDirectory ( atPath: swiftlyBinDir. path ) ) ?? [ String] ( )
154+ ( try ? await fs . ls ( atPath: swiftlyBinDir) ) ?? [ String] ( )
137155 let toolchainBinDir = Swiftly . currentPlatform. findToolchainBinDir ( ctx, version)
138- let toolchainBinDirContents = try FileManager . default. contentsOfDirectory (
139- atPath: toolchainBinDir. path)
156+ let toolchainBinDirContents = try await fs. ls ( atPath: toolchainBinDir)
157+
158+ var existingProxies : [ String ] = [ ]
140159
141- let existingProxies = swiftlyBinDirContents. filter { bin in
160+ for bin in swiftlyBinDirContents {
142161 do {
143- let linkTarget = try FileManager . default. destinationOfSymbolicLink (
144- atPath: swiftlyBinDir. appendingPathComponent ( bin) . path)
145- return linkTarget == proxyTo
146- } catch { return false }
162+ let linkTarget = try await fs. readlink ( atPath: swiftlyBinDir / bin)
163+ if linkTarget == proxyTo {
164+ existingProxies. append ( bin)
165+ }
166+ } catch { continue }
147167 }
148168
149169 let overwrite = Set ( toolchainBinDirContents) . subtracting ( existingProxies) . intersection (
@@ -152,7 +172,7 @@ struct Install: SwiftlyCommand {
152172 await ctx. print ( " The following existing executables will be overwritten: " )
153173
154174 for executable in overwrite {
155- await ctx. print ( " \( swiftlyBinDir. appendingPathComponent ( executable) . path ) " )
175+ await ctx. print ( " \( swiftlyBinDir / executable) " )
156176 }
157177
158178 guard await ctx. promptForConfirmation ( defaultBehavior: false ) else {
@@ -168,16 +188,13 @@ struct Install: SwiftlyCommand {
168188 overwrite)
169189
170190 for p in proxiesToCreate {
171- let proxy = Swiftly . currentPlatform. swiftlyBinDir ( ctx) . appendingPathComponent ( p )
191+ let proxy = Swiftly . currentPlatform. swiftlyBinDir ( ctx) / p
172192
173- if proxy . fileExists ( ) {
174- try FileManager . default . removeItem ( at : proxy)
193+ if try await fs . exists ( atPath : proxy ) {
194+ try await fs . remove ( atPath : proxy)
175195 }
176196
177- try FileManager . default. createSymbolicLink (
178- atPath: proxy. path,
179- withDestinationPath: proxyTo
180- )
197+ try await fs. symlink ( atPath: proxy, linkPath: proxyTo)
181198
182199 pathChanged = true
183200 }
@@ -196,8 +213,7 @@ struct Install: SwiftlyCommand {
196213 selector = try ToolchainSelector ( parsing: version)
197214 } else {
198215 if case let ( _, result) = try await selectToolchain ( ctx, config: & config) ,
199- case let . swiftVersionFile( _, sel, error) = result
200- {
216+ case let . swiftVersionFile( _, sel, error) = result {
201217 if let sel = sel {
202218 selector = sel
203219 } else if let error = error {
@@ -327,120 +343,15 @@ struct Install: SwiftlyCommand {
327343
328344 try await Swiftly . currentPlatform. install ( ctx, from: tmpFile, version: version, verbose: verbose)
329345
330- var pathChanged = false
331-
332- // Create proxies if we have a location where we can point them
333- if let proxyTo = try ? await Swiftly . currentPlatform. findSwiftlyBin( ctx) {
334- // Ensure swiftly doesn't overwrite any existing executables without getting confirmation first.
335- let swiftlyBinDir = Swiftly . currentPlatform. swiftlyBinDir ( ctx)
336- let swiftlyBinDirContents =
337- ( try ? await fs. ls ( atPath: swiftlyBinDir) ) ?? [ String] ( )
338- let toolchainBinDir = Swiftly . currentPlatform. findToolchainBinDir ( ctx, version)
339- let toolchainBinDirContents = try await fs. ls ( atPath: toolchainBinDir)
340-
341- var existingProxies : [ String ] = [ ]
342-
343- for bin in swiftlyBinDirContents {
344- do {
345- let linkTarget = try await fs. readlink ( atPath: swiftlyBinDir / bin)
346- if linkTarget == proxyTo {
347- existingProxies. append ( bin)
348- }
349- } catch { continue }
350- }
351-
352- let overwrite = Set ( toolchainBinDirContents) . subtracting ( existingProxies) . intersection (
353- swiftlyBinDirContents)
354- if !overwrite. isEmpty && !assumeYes {
355- await ctx. print ( " The following existing executables will be overwritten: " )
356-
357- for executable in overwrite {
358- await ctx. print ( " \( swiftlyBinDir / executable) " )
359- }
360-
361- <<<<<<< HEAD
362- guard await ctx. promptForConfirmation ( defaultBehavior: false ) else {
363- throw SwiftlyError ( message: " Toolchain installation has been cancelled " )
364- }
365- }
366-
367- if verbose {
368- await ctx. print ( " Setting up toolchain proxies... " )
369- }
370-
371- let proxiesToCreate = Set ( toolchainBinDirContents) . subtracting ( swiftlyBinDirContents) . union (
372- overwrite)
373-
374- for p in proxiesToCreate {
375- let proxy = Swiftly . currentPlatform. swiftlyBinDir ( ctx) / p
376-
377- if try await fs. exists ( atPath: proxy) {
378- try await fs. remove ( atPath: proxy)
379- }
380-
381- try await fs. symlink ( atPath: proxy, linkPath: proxyTo)
382-
383- pathChanged = true
384- }
385- }
386-
387- config. installedToolchains. insert ( version)
388-
389- =======
390- let do wnloadedMiB = Double ( progress. receivedBytes) / ( 1024.0 * 1024.0 )
391- let totalMiB = Double ( progress. totalBytes!) / ( 1024.0 * 1024.0 )
392-
393- lastUpdate = Date ( )
394-
395- animation. update (
396- step: progress. receivedBytes,
397- total: progress. totalBytes!,
398- text:
399- " Downloaded \( String ( format: " %.1f " , downloadedMiB) ) MiB of \( String ( format: " %.1f " , totalMiB) ) MiB "
400- )
401- }
402- )
403- } catch let notFound as DownloadNotFoundError {
404- throw SwiftlyError ( message: " \( version) does not exist at URL \( notFound. url) , exiting " )
405- } catch {
406- animation. complete ( success: false )
407- throw error
408- }
409- animation. complete ( success: true )
410-
411- if verifySignature {
412- try await Swiftly . currentPlatform. verifyToolchainSignature (
346+ let pathChanged = try await Self . setupProxies (
413347 ctx,
414- toolchainFile : toolchainFile ,
415- archive : tmpFile ,
416- verbose : verbose
348+ version : version ,
349+ verbose : verbose ,
350+ assumeYes : assumeYes
417351 )
418- }
419-
420- try await Swiftly. currentPlatform. install ( ctx, from: tmpFile, version: version, verbose: verbose)
421-
422- let pathChanged = try await Self . setupProxies (
423- ctx,
424- version: version,
425- verbose: verbose,
426- assumeYes: assumeYes
427- )
428-
429- config. installedToolchains. insert ( version)
430352
431- try config. save ( ctx)
432-
433- // If this is the first installed toolchain, mark it as in-use regardless of whether the
434- // --use argument was provided.
435- if useInstalledToolchain {
436- try await Use . execute ( ctx, version, globalDefault: false , & config)
437- }
353+ config. installedToolchains. insert ( version)
438354
439- // We always update the global default toolchain if there is none set. This could
440- // be the only toolchain that is installed, which makes it the only choice.
441- if config. inUse == nil {
442- config. inUse = version
443- >>>>>>> 5 d7 eb2 d ( Add ability to temporarily disable swiftly)
444355 try config. save ( ctx)
445356
446357 // If this is the first installed toolchain, mark it as in-use regardless of whether the
0 commit comments