Skip to content

Commit aa08975

Browse files
authored
Merge toolNamesToPaths and toolNamesToTriples (#5976)
These started out as separate dictionaries, this merges them into one dictionary with a tuple value.
1 parent 6231a75 commit aa08975

File tree

6 files changed

+41
-48
lines changed

6 files changed

+41
-48
lines changed

Sources/Commands/PackageTools/PluginCommand.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ struct PluginCommand: SwiftCommand {
161161

162162
// Build or bring up-to-date any executable host-side tools on which this plugin depends. Add them and any binary dependencies to the tool-names-to-path map.
163163
let buildSystem = try swiftTool.createBuildSystem(explicitBuildSystem: .native, cacheBuildManifest: false)
164-
let (toolNamesToPaths, toolNamesToTriples) = try plugin.processAccessibleTools(packageGraph: packageGraph, fileSystem: swiftTool.fileSystem, environment: try swiftTool.buildParameters().buildEnvironment, for: try pluginScriptRunner.hostTriple) { name, path in
164+
let accessibleTools = try plugin.processAccessibleTools(packageGraph: packageGraph, fileSystem: swiftTool.fileSystem, environment: try swiftTool.buildParameters().buildEnvironment, for: try pluginScriptRunner.hostTriple) { name, path in
165165
// Build the product referenced by the tool, and add the executable to the tool map. Product dependencies are not supported within a package, so if the tool happens to be from the same package, we instead find the executable that corresponds to the product. There is always one, because of autogeneration of implicit executables with the same name as the target if there isn't an explicit one.
166166
try buildSystem.build(subset: .product(name))
167167
if let builtTool = try buildSystem.buildPlan.buildProducts.first(where: { $0.product.name == name}) {
@@ -184,8 +184,7 @@ struct PluginCommand: SwiftCommand {
184184
workingDirectory: swiftTool.originalWorkingDirectory,
185185
outputDirectory: outputDir,
186186
toolSearchDirectories: toolSearchDirs,
187-
toolNamesToPaths: toolNamesToPaths,
188-
toolNamesToTriples: toolNamesToTriples,
187+
accessibleTools: accessibleTools,
189188
writableDirectories: writableDirectories,
190189
readOnlyDirectories: readOnlyDirectories,
191190
fileSystem: swiftTool.fileSystem,

Sources/PackagePlugin/Context.swift

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ public struct PluginContext {
3838
/// target on which the package plugin target depends. This function throws
3939
/// an error if the tool cannot be found. The lookup is case sensitive.
4040
public func tool(named name: String) throws -> Tool {
41-
if let path = self.toolNamesToPaths[name] {
41+
if let tool = self.accessibleTools[name] {
4242
// For PluginAccessibleTool.builtTool, the triples value is not saved, thus
4343
// the value is always nil; this is intentional since if we are able to
4444
// build the tool, it is by definition supporting the target platform.
4545
// For PluginAccessibleTool.vendedTool, only supported triples are saved,
4646
// so empty triples means the tool is not supported on the target platform.
47-
if let triples = toolNamesToTriples[name], triples.isEmpty {
47+
if let triples = tool.triples, triples.isEmpty {
4848
throw PluginContextError.toolNotSupportedOnTargetPlatform(name: name)
4949
}
50-
return Tool(name: name, path: path)
50+
return Tool(name: name, path: tool.path)
5151
} else {
5252
for dir in toolSearchDirectories {
5353
#if os(Windows)
@@ -64,12 +64,9 @@ public struct PluginContext {
6464
throw PluginContextError.toolNotFound(name: name)
6565
}
6666

67-
/// A mapping from tool names to their definitions. Not directly available
67+
/// A mapping from tool names to their paths and triples. Not directly available
6868
/// to the plugin, but used by the `tool(named:)` API.
69-
let toolNamesToPaths: [String: Path]
70-
71-
/// Supported triples per tool name; looked up in `tool(named:)`
72-
let toolNamesToTriples: [String: [String]]
69+
let accessibleTools: [String: (path: Path, triples: [String]?)]
7370

7471
/// The paths of directories of in which to search for tools that aren't in
7572
/// the `toolNamesToPaths` map.

Sources/PackagePlugin/Plugin.swift

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,15 @@ extension Plugin {
130130
let toolSearchDirectories = try wireInput.toolSearchDirIds.map {
131131
try deserializer.path(for: $0)
132132
}
133-
let toolNamesToPaths = try wireInput.toolNamesToPathIds.mapValues {
134-
try deserializer.path(for: $0)
133+
let accessibleTools = try wireInput.accessibleTools.mapValues { (tool: HostToPluginMessage.InputContext.Tool) -> (Path, [String]?) in
134+
let path = try deserializer.path(for: tool.path)
135+
return (path, tool.triples)
135136
}
136-
let toolNamesToTriples = wireInput.toolNamesToTriples
137137

138138
context = PluginContext(
139139
package: package,
140140
pluginWorkDirectory: pluginWorkDirectory,
141-
toolNamesToPaths: toolNamesToPaths,
142-
toolNamesToTriples: toolNamesToTriples,
141+
accessibleTools: accessibleTools,
143142
toolSearchDirectories: toolSearchDirectories)
144143
target = try deserializer.target(for: targetId)
145144
}
@@ -211,16 +210,14 @@ extension Plugin {
211210
let toolSearchDirectories = try wireInput.toolSearchDirIds.map {
212211
try deserializer.path(for: $0)
213212
}
214-
let toolNamesToPaths = try wireInput.toolNamesToPathIds.mapValues {
215-
try deserializer.path(for: $0)
213+
let accessibleTools = try wireInput.accessibleTools.mapValues { (tool: HostToPluginMessage.InputContext.Tool) -> (Path, [String]?) in
214+
let path = try deserializer.path(for: tool.path)
215+
return (path, tool.triples)
216216
}
217-
218-
let toolNamesToTriples = wireInput.toolNamesToTriples
219217
context = PluginContext(
220218
package: package,
221219
pluginWorkDirectory: pluginWorkDirectory,
222-
toolNamesToPaths: toolNamesToPaths,
223-
toolNamesToTriples: toolNamesToTriples,
220+
accessibleTools: accessibleTools,
224221
toolSearchDirectories: toolSearchDirectories)
225222
}
226223
catch {

Sources/PackagePlugin/PluginMessages.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,13 @@ enum HostToPluginMessage: Codable {
2626
let packages: [Package]
2727
let pluginWorkDirId: Path.Id
2828
let toolSearchDirIds: [Path.Id]
29-
let toolNamesToPathIds: [String: Path.Id]
30-
let toolNamesToTriples: [String: [String]]
29+
let accessibleTools: [String: Tool]
30+
31+
// Wrapper struct for encoding information about a tool that's accessible to the plugin.
32+
struct Tool: Codable {
33+
let path: Path.Id
34+
let triples: [String]?
35+
}
3136

3237
/// A single absolute path in the wire structure, represented as a tuple
3338
/// consisting of the ID of the base path and subpath off of that path.

Sources/SPMBuildCore/PluginInvocation.swift

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ extension PluginTarget {
5454
workingDirectory: AbsolutePath,
5555
outputDirectory: AbsolutePath,
5656
toolSearchDirectories: [AbsolutePath],
57-
toolNamesToPaths: [String: AbsolutePath],
58-
toolNamesToTriples: [String: [String]],
57+
accessibleTools: [String: (path: AbsolutePath, triples: [String]?)],
5958
writableDirectories: [AbsolutePath],
6059
readOnlyDirectories: [AbsolutePath],
6160
fileSystem: FileSystem,
@@ -78,8 +77,10 @@ extension PluginTarget {
7877
var serializer = PluginContextSerializer(fileSystem: fileSystem, buildEnvironment: buildEnvironment)
7978
let pluginWorkDirId = try serializer.serialize(path: outputDirectory)
8079
let toolSearchDirIds = try toolSearchDirectories.map{ try serializer.serialize(path: $0) }
81-
let toolNamesToPathIds = try toolNamesToPaths.mapValues{ try serializer.serialize(path: $0) }
82-
let toolNamesToTriplesDict = toolNamesToTriples
80+
let accessibleTools = try accessibleTools.mapValues { (tool: (AbsolutePath, [String]?)) -> HostToPluginMessage.InputContext.Tool in
81+
let path = try serializer.serialize(path: tool.0)
82+
return .init(path: path, triples: tool.1)
83+
}
8384
let actionMessage: HostToPluginMessage
8485
switch action {
8586

@@ -95,8 +96,7 @@ extension PluginTarget {
9596
packages: serializer.packages,
9697
pluginWorkDirId: pluginWorkDirId,
9798
toolSearchDirIds: toolSearchDirIds,
98-
toolNamesToPathIds: toolNamesToPathIds,
99-
toolNamesToTriples: toolNamesToTriplesDict)
99+
accessibleTools: accessibleTools)
100100
actionMessage = .createBuildToolCommands(
101101
context: wireInput,
102102
rootPackageId: rootPackageId,
@@ -110,8 +110,7 @@ extension PluginTarget {
110110
packages: serializer.packages,
111111
pluginWorkDirId: pluginWorkDirId,
112112
toolSearchDirIds: toolSearchDirIds,
113-
toolNamesToPathIds: toolNamesToPathIds,
114-
toolNamesToTriples: toolNamesToTriples)
113+
accessibleTools: accessibleTools)
115114
actionMessage = .performCommand(
116115
context: wireInput,
117116
rootPackageId: rootPackageId,
@@ -365,13 +364,13 @@ extension PackageGraph {
365364
// Determine the tools to which this plugin has access, and create a name-to-path mapping from tool
366365
// names to the corresponding paths. Built tools are assumed to be in the build tools directory.
367366
var builtToolNames: [String] = []
368-
let (toolNamesToPaths, toolNamesToTriples) = try pluginTarget.processAccessibleTools(packageGraph: self, fileSystem: fileSystem, environment: buildEnvironment, for: try pluginScriptRunner.hostTriple) { name, path in
367+
let accessibleTools = try pluginTarget.processAccessibleTools(packageGraph: self, fileSystem: fileSystem, environment: buildEnvironment, for: try pluginScriptRunner.hostTriple) { name, path in
369368
builtToolNames.append(name)
370369
return builtToolsDir.appending(path)
371370
}
372371

373372
// Determine additional input dependencies for any plugin commands, based on any executables the plugin target depends on.
374-
let toolPaths = toolNamesToPaths.values.sorted()
373+
let toolPaths = accessibleTools.values.map { $0.path }.sorted()
375374

376375
// Assign a plugin working directory based on the package, target, and plugin.
377376
let pluginOutputDir = outputDir.appending(components: package.identity.description, target.name, pluginTarget.name)
@@ -462,8 +461,7 @@ extension PackageGraph {
462461
workingDirectory: package.path,
463462
outputDirectory: pluginOutputDir,
464463
toolSearchDirectories: toolSearchDirectories,
465-
toolNamesToPaths: toolNamesToPaths,
466-
toolNamesToTriples: toolNamesToTriples,
464+
accessibleTools: accessibleTools,
467465
writableDirectories: writableDirectories,
468466
readOnlyDirectories: readOnlyDirectories,
469467
fileSystem: fileSystem,
@@ -543,29 +541,26 @@ public extension PluginTarget {
543541
})
544542
}
545543

546-
func processAccessibleTools(packageGraph: PackageGraph, fileSystem: FileSystem, environment: BuildEnvironment, for hostTriple: Triple, builtToolHandler: (_ name: String, _ path: RelativePath) throws -> AbsolutePath?) throws -> (toolNamesToPaths: [String: AbsolutePath], toolNamesToTriples: [String: [String]]) {
547-
var toolNamesToPaths: [String: AbsolutePath] = [:]
548-
// Add supported triples info per tool so they can be looked up when running the tool
549-
var toolNamesToTriples: [String: [String]] = [:]
544+
func processAccessibleTools(packageGraph: PackageGraph, fileSystem: FileSystem, environment: BuildEnvironment, for hostTriple: Triple, builtToolHandler: (_ name: String, _ path: RelativePath) throws -> AbsolutePath?) throws -> [String: (path: AbsolutePath, triples: [String]?)] {
545+
var pluginAccessibleTools: [String: (path: AbsolutePath, triples: [String]?)] = [:]
550546

551547
for dep in try accessibleTools(packageGraph: packageGraph, fileSystem: fileSystem, environment: environment, for: hostTriple) {
552548
switch dep {
553549
case .builtTool(let name, let path):
554550
if let path = try builtToolHandler(name, path) {
555-
toolNamesToPaths[name] = path
551+
pluginAccessibleTools[name] = (path, nil)
556552
}
557553
case .vendedTool(let name, let path, let triples):
558554
// Avoid having the path of an unsupported tool overwrite a supported one.
559-
guard !triples.isEmpty || toolNamesToPaths[name] == nil else {
555+
guard !triples.isEmpty || pluginAccessibleTools[name] == nil else {
560556
continue
561557
}
562-
toolNamesToPaths[name] = path
563-
// Need triples info for .vendedTool
564-
toolNamesToTriples[name, default: []].append(contentsOf: triples)
558+
let priorTriples = pluginAccessibleTools[name]?.triples ?? []
559+
pluginAccessibleTools[name] = (path, priorTriples + triples)
565560
}
566561
}
567562

568-
return (toolNamesToPaths, toolNamesToTriples)
563+
return pluginAccessibleTools
569564
}
570565
}
571566

Tests/FunctionalTests/PluginTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ class PluginTests: XCTestCase {
460460
workingDirectory: package.path,
461461
outputDirectory: pluginDir.appending(component: "output"),
462462
toolSearchDirectories: toolSearchDirectories,
463-
toolNamesToPaths: [:],
463+
accessibleTools: [:],
464464
writableDirectories: [pluginDir.appending(component: "output")],
465465
readOnlyDirectories: [package.path],
466466
fileSystem: localFileSystem,
@@ -721,7 +721,7 @@ class PluginTests: XCTestCase {
721721
workingDirectory: package.path,
722722
outputDirectory: pluginDir.appending(component: "output"),
723723
toolSearchDirectories: [try UserToolchain.default.swiftCompilerPath.parentDirectory],
724-
toolNamesToPaths: [:],
724+
accessibleTools: [:],
725725
writableDirectories: [pluginDir.appending(component: "output")],
726726
readOnlyDirectories: [package.path],
727727
fileSystem: localFileSystem,

0 commit comments

Comments
 (0)