Skip to content

Commit 28243d9

Browse files
committed
Extract common lookup logic
1 parent 8d37f6a commit 28243d9

File tree

1 file changed

+46
-75
lines changed

1 file changed

+46
-75
lines changed

Sources/SwiftlyCore/Platform.swift

Lines changed: 46 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -169,44 +169,14 @@ extension Platform {
169169

170170
// Install ourselves in the final location
171171
public func installSwiftlyBin(_ ctx: SwiftlyCoreContext) async throws {
172-
// First, let's find out where we are.
173-
let cmd = CommandLine.arguments[0]
174-
175-
var cmdAbsolute: FilePath?
176-
177-
if cmd.hasPrefix("/") {
178-
cmdAbsolute = FilePath(cmd)
179-
} else {
180-
let pathEntries = ([fs.cwd.string] + (ProcessInfo.processInfo.environment["PATH"]?.components(separatedBy: ":") ?? [])).map
181-
{
182-
FilePath($0) / cmd
183-
}
184-
185-
for pathEntry in pathEntries {
186-
if try await fs.exists(atPath: pathEntry) {
187-
cmdAbsolute = pathEntry
188-
break
189-
}
190-
}
191-
}
192-
193172
// We couldn't find ourselves in the usual places. Assume that no installation is necessary
194173
// since we were most likely invoked at SWIFTLY_BIN_DIR already.
195-
guard let cmdAbsolute else {
196-
return
197-
}
198-
199-
// If swiftly is symlinked then we leave it where it is, such as in a homebrew installation.
200-
if let _ = try? FileManager.default.destinationOfSymbolicLink(atPath: cmdAbsolute) {
174+
guard let cmdAbsolute = try await self.absoluteCommandPath() else {
201175
return
202176
}
203177

204-
// Proceed to installation only if we're in the user home directory, or a non-system location.
205-
let userHome = fs.home
206-
207-
let systemRoots: [FilePath] = ["/usr", "/opt", "/bin"]
208-
209-
guard cmdAbsolute.starts(with: userHome) || systemRoots.filter({ cmdAbsolute.starts(with: $0) }).first == nil else {
178+
// Make sure swiftly is not system managed.
179+
if try await self.isSystemManaged(cmdAbsolute) {
210180
return
211181
}
212182

@@ -242,55 +212,24 @@ extension Platform {
242212
// Find the location where swiftly should be executed.
243213
public func findSwiftlyBin(_ ctx: SwiftlyCoreContext) async throws -> FilePath? {
244214
let swiftlyHomeBin = self.swiftlyBinDir(ctx) / "swiftly"
245-
246-
// First, let's find out where we are.
247-
let cmd = CommandLine.arguments[0]
248-
var cmdAbsolute: FilePath?
249-
if cmd.hasPrefix("/") {
250-
cmdAbsolute = FilePath(cmd)
251-
} else {
252-
let pathEntries = ([fs.cwd.string] + (ProcessInfo.processInfo.environment["PATH"]?.components(separatedBy: ":") ?? [])).map
253-
{
254-
FilePath($0) / cmd
255-
}
256-
257-
for pathEntry in pathEntries {
258-
if try await fs.exists(atPath: pathEntry) {
259-
cmdAbsolute = pathEntry
260-
break
261-
}
262-
}
263-
}
264-
265-
// We couldn't find ourselves in the usual places, so if we're not going to be installing
266-
// swiftly then we can assume that we are running from the final location.
267-
let homeBinExists = try await fs.exists(atPath: swiftlyHomeBin)
268-
if cmdAbsolute == nil && homeBinExists {
269-
return swiftlyHomeBin
270-
}
271-
272-
// If swiftly is a symlink then something else, such as homebrew, is managing it.
273-
if cmdAbsolute != nil {
274-
if let _ = try? FileManager.default.destinationOfSymbolicLink(atPath: cmdAbsolute!) {
275-
return cmdAbsolute
215+
guard let cmdAbsolute = try await self.absoluteCommandPath() else {
216+
if try await fs.exists(atPath: swiftlyHomeBin) {
217+
// We couldn't find ourselves in the usual places, so if we're not going to be installing
218+
// swiftly then we can assume that we are running from the final location.
219+
return swiftlyHomeBin
276220
}
221+
return nil
277222
}
278223

279-
let systemRoots: [FilePath] = ["/usr", "/opt", "/bin"]
280-
281-
// If we are system managed then we know where swiftly should be.
282-
let userHome = fs.home
283-
284-
if let cmdAbsolute, !cmdAbsolute.starts(with: userHome) && systemRoots.filter({ cmdAbsolute.starts(with: $0) }).first != nil {
224+
if try await self.isSystemManaged(cmdAbsolute) {
285225
return cmdAbsolute
286226
}
287227

288228
// If we're running inside an xctest then we don't have a location for this swiftly.
289-
guard let cmdAbsolute,
290-
!(
291-
(cmdAbsolute.string.hasSuffix("xctest") || cmdAbsolute.string.hasSuffix("swiftpm-testing-helper"))
292-
&& CommandLine.arguments.contains { $0.contains("InstallTests") }
293-
)
229+
guard !(
230+
(cmdAbsolute.string.hasSuffix("xctest") || cmdAbsolute.string.hasSuffix("swiftpm-testing-helper"))
231+
&& CommandLine.arguments.contains { $0.contains("InstallTests") }
232+
)
294233
else {
295234
return nil
296235
}
@@ -303,5 +242,37 @@ extension Platform {
303242
(try await self.findToolchainLocation(ctx, toolchain)) / "usr/bin"
304243
}
305244

245+
private func absoluteCommandPath() async throws -> FilePath? {
246+
let cmd = CommandLine.arguments[0]
247+
if cmd.hasPrefix("/") {
248+
return FilePath(cmd)
249+
}
250+
let localCmd = FilePath(fs.cwd.string) / cmd
251+
if try await fs.exists(atPath: localCmd) {
252+
return localCmd
253+
}
254+
guard let path = ProcessInfo.processInfo.environment["PATH"] else {
255+
return nil
256+
}
257+
let pathEntries = path.components(separatedBy: ":").map { FilePath($0) / cmd }
258+
for pathEntry in pathEntries where try await fs.exists(atPath: pathEntry) {
259+
return pathEntry
260+
}
261+
return nil
262+
}
263+
264+
private func isSystemManaged(_ path: FilePath) async throws -> Bool {
265+
// If swiftly is symlinked then we leave it where it is, such as in a Homebrew installation.
266+
if try await fs.isSymLink(atPath: path) {
267+
return true
268+
}
269+
if path.starts(with: fs.home) {
270+
// In user's home directory, so not system managed.
271+
return false
272+
}
273+
// With a system prefix?
274+
return ["/usr", "/opt", "/bin"].contains { path.starts(with: $0) }
275+
}
276+
306277
#endif
307278
}

0 commit comments

Comments
 (0)