Skip to content

Commit e07804d

Browse files
authored
PackageModel/Toolset: fix support for relative rootPath (#6195)
Currently `DecodedToolset` only decodes `AbsolutePath` directly, while it should be able to support relative paths as well. Let's fix that by decoding to `String` first and then resolving to `AbsolutePath` when creating a `Toolset` value from `DecodedToolset`. Also added a corresponding test assertion that verifies that applied fix works.
1 parent 760ec39 commit e07804d

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

Sources/PackageModel/Toolset.swift

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ extension Toolset {
7676
)
7777
}
7878

79+
let rootPaths = try decoded.rootPath.map {
80+
[try AbsolutePath(validating: $0, relativeTo: toolsetPath.parentDirectory)]
81+
} ?? []
82+
7983
var knownTools = [KnownTool: ToolProperties]()
8084
var hasEmptyToolConfiguration = false
8185
for (tool, properties) in decoded.tools {
@@ -89,7 +93,7 @@ extension Toolset {
8993
if let absolutePath = try? AbsolutePath(validating: path) {
9094
toolPath = absolutePath
9195
} else {
92-
let rootPath = decoded.rootPath ?? toolsetPath.parentDirectory
96+
let rootPath = rootPaths.first ?? toolsetPath.parentDirectory
9397
toolPath = rootPath.appending(RelativePath(path))
9498
}
9599
} else {
@@ -119,13 +123,6 @@ extension Toolset {
119123
throw StringError("Toolset configuration at `\(toolsetPath)` has at least one tool with no properties.")
120124
}
121125

122-
let rootPaths: [AbsolutePath]
123-
if let rootPath = decoded.rootPath {
124-
rootPaths = [rootPath]
125-
} else {
126-
rootPaths = []
127-
}
128-
129126
self.init(knownTools: knownTools, rootPaths: rootPaths)
130127
}
131128

@@ -174,7 +171,7 @@ private struct DecodedToolset {
174171

175172
/// Root path of the toolset, if present. When filling in ``Toolset.ToolProperties/path``, if a raw path string in
176173
/// ``DecodedToolset`` is inferred to be relative, it's resolved as absolute path relatively to `rootPath`.
177-
let rootPath: AbsolutePath?
174+
let rootPath: String?
178175

179176
/// Dictionary of raw tools that haven't been validated yet to match ``Toolset.KnownTool``.
180177
var tools: [String: ToolProperties]
@@ -206,7 +203,7 @@ extension DecodedToolset: Decodable {
206203
versionString: container.decode(String.self, forKey: .schemaVersion),
207204
usesLenientParsing: true
208205
)
209-
self.rootPath = try container.decodeIfPresent(AbsolutePath.self, forKey: .rootPath)
206+
self.rootPath = try container.decodeIfPresent(String.self, forKey: .rootPath)
210207

211208
self.tools = [String: DecodedToolset.ToolProperties]()
212209
for key in container.allKeys {

Tests/PackageModelTests/ToolsetTests.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,22 @@ private let someToolsWithRoot = (
8585
"""#
8686
)
8787

88+
private let someToolsWithRelativeRoot = (
89+
path: try! AbsolutePath(validating: "/tools/someToolsWithRelativeRoot.json"),
90+
json: #"""
91+
{
92+
"schemaVersion": "1.0",
93+
"rootPath": "relative/custom",
94+
"cCompiler": { "extraCLIOptions": \#(newCCompilerOptions) }
95+
}
96+
"""#
97+
)
98+
8899
final class ToolsetTests: XCTestCase {
89100
func testToolset() throws {
90101
let fileSystem = InMemoryFileSystem()
91102
try fileSystem.createDirectory(.init(validating: "/tools"))
92-
for testFile in [compilersNoRoot, noValidToolsNoRoot, unknownToolsNoRoot, otherToolsNoRoot, someToolsWithRoot] {
103+
for testFile in [compilersNoRoot, noValidToolsNoRoot, unknownToolsNoRoot, otherToolsNoRoot, someToolsWithRoot, someToolsWithRelativeRoot] {
93104
try fileSystem.writeFileContents(testFile.path, data: .init(testFile.json.utf8))
94105
}
95106
let observability = ObservabilitySystem.makeForTesting()
@@ -190,5 +201,14 @@ final class ToolsetTests: XCTestCase {
190201
otherToolsToolset.knownTools[.debugger],
191202
Toolset.ToolProperties(path: usrBinTools[.debugger]!)
192203
)
204+
205+
let someToolsWithRelativeRoot = try Toolset(from: someToolsWithRelativeRoot.path, at: fileSystem, observability.topScope)
206+
XCTAssertEqual(
207+
someToolsWithRelativeRoot,
208+
Toolset(
209+
knownTools: [.cCompiler: .init(extraCLIOptions: newCCompilerOptions)],
210+
rootPaths: [try AbsolutePath(validating: "/tools/relative/custom")]
211+
)
212+
)
193213
}
194214
}

0 commit comments

Comments
 (0)