Skip to content

Commit 55fc274

Browse files
committed
Refactor find/install swiftly binary into two functions
1 parent 34e4021 commit 55fc274

File tree

3 files changed

+59
-28
lines changed

3 files changed

+59
-28
lines changed

Sources/Swiftly/Init.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ internal struct Init: SwiftlyCommand {
139139
guard var config else { throw Error(message: "Configuration could not be set") }
140140

141141
// Move our executable over to the correct place
142-
let _ = try Swiftly.currentPlatform.findSwiftlyBin(installSwiftly: true)
142+
try Swiftly.currentPlatform.installSwiftlyBin()
143143

144144
if overwrite || !FileManager.default.fileExists(atPath: envFile.path) {
145145
SwiftlyCore.print("Creating shell environment file for the user...")

Sources/Swiftly/Install.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ struct Install: SwiftlyCommand {
244244
var pathChanged = false
245245

246246
// Create proxies if we have a location where we can point them
247-
if let proxyTo = try? Swiftly.currentPlatform.findSwiftlyBin(installSwiftly: false) {
247+
if let proxyTo = try? Swiftly.currentPlatform.findSwiftlyBin() {
248248
// Ensure swiftly doesn't overwrite any existing executables without getting confirmation first.
249249
let swiftlyBinDir = Swiftly.currentPlatform.swiftlyBinDir
250250
let swiftlyBinDirContents = (try? FileManager.default.contentsOfDirectory(atPath: swiftlyBinDir.path)) ?? [String]()

Sources/SwiftlyCore/Platform.swift

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,60 @@ extension Platform {
267267
}
268268
}
269269

270-
// Find the resting place for the swiftly binary, installing ourselves there if possible.
271-
public func findSwiftlyBin(installSwiftly: Bool) throws -> String? {
270+
// Install ourselves in the final location
271+
public func installSwiftlyBin() throws {
272+
// First, let's find out where we are.
273+
let cmd = CommandLine.arguments[0]
274+
let cmdAbsolute = if cmd.hasPrefix("/") {
275+
cmd
276+
} else {
277+
([FileManager.default.currentDirectoryPath] + (ProcessInfo.processInfo.environment["PATH"]?.components(separatedBy: ":") ?? [])).map {
278+
$0 + "/" + cmd
279+
}.filter {
280+
FileManager.default.fileExists(atPath: $0)
281+
}.first
282+
}
283+
284+
// We couldn't find ourselves in the usual places. Assume that no installation is necessary
285+
// since we were most likely invoked at SWIFTLY_BIN_DIR already.
286+
guard let cmdAbsolute else {
287+
return
288+
}
289+
290+
// Proceed to installation only if we're in the user home directory, or a non-system location.
291+
let userHome = FileManager.default.homeDirectoryForCurrentUser
292+
guard cmdAbsolute.hasPrefix(userHome.path + "/") ||
293+
(!cmdAbsolute.hasPrefix("/usr/") && !cmdAbsolute.hasPrefix("/opt/") && !cmdAbsolute.hasPrefix("/bin/"))
294+
else {
295+
return
296+
}
297+
298+
// Proceed only if we're not running in the context of a test.
299+
guard !cmdAbsolute.hasSuffix("xctest") else {
300+
return
301+
}
302+
303+
// We're already running from where we would be installing ourselves.
304+
guard case let swiftlyHomeBin = self.swiftlyBinDir.appendingPathComponent("swiftly", isDirectory: false).path, cmdAbsolute != swiftlyHomeBin else {
305+
return
306+
}
307+
308+
SwiftlyCore.print("Installing swiftly in \(swiftlyHomeBin)...")
309+
310+
if FileManager.default.fileExists(atPath: swiftlyHomeBin) {
311+
try FileManager.default.removeItem(atPath: swiftlyHomeBin)
312+
}
313+
314+
do {
315+
try FileManager.default.moveItem(atPath: cmdAbsolute, toPath: swiftlyHomeBin)
316+
} catch {
317+
try FileManager.default.copyItem(atPath: cmdAbsolute, toPath: swiftlyHomeBin)
318+
SwiftlyCore.print("Swiftly has been copied into the installation directory. You can remove '\(cmdAbsolute)'. It is no longer needed.")
319+
}
320+
}
321+
322+
// Find the location where swiftly should be executed.
323+
public func findSwiftlyBin() throws -> String? {
272324
let swiftlyHomeBin = self.swiftlyBinDir.appendingPathComponent("swiftly", isDirectory: false).path
273325

274326
// First, let's find out where we are.
@@ -285,42 +337,21 @@ extension Platform {
285337

286338
// We couldn't find ourselves in the usual places, so if we're not going to be installing
287339
// swiftly then we can assume that we are running from the final location.
288-
if cmdAbsolute == nil && !installSwiftly && FileManager.default.fileExists(atPath: swiftlyHomeBin) {
340+
if cmdAbsolute == nil && FileManager.default.fileExists(atPath: swiftlyHomeBin) {
289341
return swiftlyHomeBin
290342
}
291343

292-
// If we are system managed then we know where swiftly should be, no installation necessary.
344+
// If we are system managed then we know where swiftly should be.
293345
let userHome = FileManager.default.homeDirectoryForCurrentUser
294346
if let cmdAbsolute, !cmdAbsolute.hasPrefix(userHome.path + "/") && (cmdAbsolute.hasPrefix("/usr/") || cmdAbsolute.hasPrefix("/opt/") || cmdAbsolute.hasPrefix("/bin/")) {
295347
return cmdAbsolute
296348
}
297349

298-
// If we're running inside an xctest or we couldn't determine our absolute path then
299-
// we don't install nor do we have a swiftly location for the proxies.
350+
// If we're running inside an xctest then we don't have a location for this swiftly.
300351
guard let cmdAbsolute, !cmdAbsolute.hasSuffix("xctest") else {
301352
return nil
302353
}
303354

304-
// We're installed and running in our bin directory, return our location
305-
if cmdAbsolute == swiftlyHomeBin {
306-
return swiftlyHomeBin
307-
}
308-
309-
if installSwiftly {
310-
SwiftlyCore.print("Installing swiftly in \(swiftlyHomeBin)...")
311-
312-
if FileManager.default.fileExists(atPath: swiftlyHomeBin) {
313-
try FileManager.default.removeItem(atPath: swiftlyHomeBin)
314-
}
315-
316-
do {
317-
try FileManager.default.moveItem(atPath: cmdAbsolute, toPath: swiftlyHomeBin)
318-
} catch {
319-
try FileManager.default.copyItem(atPath: cmdAbsolute, toPath: swiftlyHomeBin)
320-
SwiftlyCore.print("Swiftly has been copied into the installation directory. You can remove '\(cmd)'. It is no longer needed.")
321-
}
322-
}
323-
324355
return FileManager.default.fileExists(atPath: swiftlyHomeBin) ? swiftlyHomeBin : nil
325356
}
326357

0 commit comments

Comments
 (0)