diff --git a/Sources/xcodes/App.swift b/Sources/xcodes/App.swift index 36ee7e5e..d2f4fb23 100644 --- a/Sources/xcodes/App.swift +++ b/Sources/xcodes/App.swift @@ -22,6 +22,11 @@ func getDirectory(possibleDirectory: String?, default: Path = Path.root.join("Ap return directory } +/// Resolves the `--path` argument of `install`, treating relative paths as relative to the current directory. +func xipPath(from pathString: String?) -> Path? { + pathString.map { Path($0) ?? Path.cwd/$0 } +} + struct GlobalDirectoryOption: ParsableArguments { @Option(help: "The directory where your Xcodes are installed. Defaults to /Applications.", completion: .directory) @@ -277,7 +282,7 @@ struct Xcodes: AsyncParsableCommand { installation = .latest } else if latestPrerelease { installation = .latestPrerelease - } else if let pathString = pathString, let path = Path(pathString) { + } else if let path = xipPath(from: pathString) { installation = .path(versionString, path) } else { installation = .version(versionString) diff --git a/Tests/xcodesTests/XipPathTests.swift b/Tests/xcodesTests/XipPathTests.swift new file mode 100644 index 00000000..4ef7fc19 --- /dev/null +++ b/Tests/xcodesTests/XipPathTests.swift @@ -0,0 +1,18 @@ +import XCTest +import Path +@testable import xcodes + +final class XipPathTests: XCTestCase { + func test_xipPath_nilWhenNoPathIsGiven() { + XCTAssertNil(xipPath(from: nil)) + } + + func test_xipPath_keepsAbsolutePath() { + XCTAssertEqual(xipPath(from: "/tmp/Xcode-14.0.0.xip"), Path.root/"tmp/Xcode-14.0.0.xip") + } + + func test_xipPath_resolvesRelativePathAgainstCurrentDirectory() { + XCTAssertEqual(xipPath(from: "Xcode-14.0.0.xip"), Path.cwd/"Xcode-14.0.0.xip") + XCTAssertEqual(xipPath(from: "Downloads/Xcode-14.0.0.xip"), Path.cwd/"Downloads/Xcode-14.0.0.xip") + } +}