diff --git a/Sources/Swiftly/Install.swift b/Sources/Swiftly/Install.swift index f59e9f69..057b9e99 100644 --- a/Sources/Swiftly/Install.swift +++ b/Sources/Swiftly/Install.swift @@ -165,7 +165,7 @@ struct Install: SwiftlyCommand { for bin in swiftlyBinDirContents { do { - let linkTarget = try await fs.readlink(atPath: swiftlyBinDir / bin) + let linkTarget = try await fs.readlink(atPath: swiftlyBinDir / bin, follow: false) if linkTarget == proxyTo { existingProxies.append(bin) } diff --git a/Sources/Swiftly/SelfUninstall.swift b/Sources/Swiftly/SelfUninstall.swift index cc4417af..efc4d670 100644 --- a/Sources/Swiftly/SelfUninstall.swift +++ b/Sources/Swiftly/SelfUninstall.swift @@ -110,7 +110,7 @@ struct SelfUninstall: SwiftlyCommand { let fullPath = swiftlyBin / entry guard try await fs.exists(atPath: fullPath) else { continue } if try await fs.isSymLink(atPath: fullPath) { - let dest = try await fs.readlink(atPath: fullPath) + let dest = try await fs.readlink(atPath: fullPath, follow: false) if dest == swiftlyBinary { if verbose { await ctx.print("Removing symlink: \(fullPath) -> \(dest)") diff --git a/Sources/Swiftly/Unlink.swift b/Sources/Swiftly/Unlink.swift index 02d820ca..472948c9 100644 --- a/Sources/Swiftly/Unlink.swift +++ b/Sources/Swiftly/Unlink.swift @@ -55,7 +55,7 @@ struct Unlink: SwiftlyCommand { let swiftlyBinDirContents = (try? await fs.ls(atPath: swiftlyBinDir)) ?? [String]() var proxies = [String]() for file in swiftlyBinDirContents { - let linkTarget = try? await fs.readlink(atPath: swiftlyBinDir / file) + let linkTarget = try? await fs.readlink(atPath: swiftlyBinDir / file, follow: true) if linkTarget == proxyTo { proxies.append(file) } @@ -93,7 +93,7 @@ extension SwiftlyCommand { } let potentialProxyPath = swiftlyBinDir / file - if let linkTarget = try? await fs.readlink(atPath: potentialProxyPath), linkTarget == proxyTo { + if let linkTarget = try? await fs.readlink(atPath: potentialProxyPath, follow: true), linkTarget == proxyTo { return true } } diff --git a/Sources/Swiftly/Use.swift b/Sources/Swiftly/Use.swift index 1462c974..332b9c66 100644 --- a/Sources/Swiftly/Use.swift +++ b/Sources/Swiftly/Use.swift @@ -76,7 +76,10 @@ struct Use: SwiftlyCommand { var config = try await Config.load(ctx) - try await validateLinked(ctx) + // Only validate linked state if we're not printing the location + if !self.printLocation { + try await validateLinked(ctx) + } // This is the bare use command where we print the selected toolchain version (or the path to it) guard let toolchain = self.toolchain else { diff --git a/Sources/SwiftlyCore/FileManager+FilePath.swift b/Sources/SwiftlyCore/FileManager+FilePath.swift index 56a03d06..9a1421e1 100644 --- a/Sources/SwiftlyCore/FileManager+FilePath.swift +++ b/Sources/SwiftlyCore/FileManager+FilePath.swift @@ -79,8 +79,13 @@ public enum FileSystem { try FileManager.default.contentsOfDir(atPath: atPath) } - public static func readlink(atPath: FilePath) async throws -> FilePath { - try FileManager.default.destinationOfSymbolicLink(atPath: atPath) + public static func readlink(atPath: FilePath, follow: Bool) async throws -> FilePath { + let path = try FileManager.default.destinationOfSymbolicLink(atPath: atPath) + if follow { + return FilePath(URL(fileURLWithPath: path.string).resolvingSymlinksInPath().path) + } else { + return path + } } public static func isSymLink(atPath: FilePath) async throws -> Bool {