Skip to content

Fix two small issues with handling of plugin triples #5945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Sources/SPMBuildCore/BinaryTarget+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,14 @@ extension BinaryTarget {
// Filter supported triples with versionLessTriple and pass into
// ExecutableInfo; empty if non matching triples found.
try entry.value.variants.map{
ExecutableInfo(name: entry.key, executablePath: try AbsolutePath(validating: $0.path, relativeTo: self.artifactPath), supportedTriples: $0.supportedTriples.filter({$0 == versionLessTriple}))
let filteredSupportedTriples = try $0.supportedTriples.filter({try $0.withoutVersion() == versionLessTriple})
return ExecutableInfo(name: entry.key, executablePath: try AbsolutePath(validating: $0.path, relativeTo: self.artifactPath), supportedTriples: filteredSupportedTriples)
}
}
}
}

fileprivate extension Triple {
extension Triple {
func withoutVersion() throws -> Triple {
if isDarwin() {
let stringWithoutVersion = tripleString(forPlatformVersion: "")
Expand Down
6 changes: 3 additions & 3 deletions Sources/SPMBuildCore/PluginInvocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,8 @@ extension PackageGraph {

let toolNamesToTriples = accessibleTools.reduce(into: [String: [String]](), { dict, tool in
switch tool {
case .vendedTool(let name, _, let triple):
dict[name] = triple
case .vendedTool(let name, _, let triples):
dict[name, default: []].append(contentsOf: triples)
default: break
}
})
Expand Down Expand Up @@ -533,7 +533,7 @@ public extension PluginTarget {
if let target = executableOrBinaryTarget as? BinaryTarget {
// TODO: Memoize this result for the host triple
let execInfos = try target.parseArtifactArchives(for: hostTriple, fileSystem: fileSystem)
return execInfos.map{ .vendedTool(name: $0.name, path: $0.executablePath, supportedTriples: $0.supportedTriples.map{$0.tripleString}) }
return try execInfos.map{ .vendedTool(name: $0.name, path: $0.executablePath, supportedTriples: try $0.supportedTriples.map{ try $0.withoutVersion().tripleString }) }
}
// For an executable target we create a `builtTool`.
else if executableOrBinaryTarget.type == .executable {
Expand Down
65 changes: 56 additions & 9 deletions Tests/SPMBuildCoreTests/PluginInvocationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1056,8 +1056,7 @@ class PluginInvocationTests: XCTestCase {
}
}


func testParseArtifactNotSupportedOnTargetPlatform() throws {
func checkParseArtifactsPlatformCompatibility(artifactSupportedTriples: [Triple], hostTriple: Triple, pluginResultChecker: ([ResolvedTarget: [BuildToolPluginInvocationResult]]) throws -> ()) throws {
// Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require).
try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency")

Expand Down Expand Up @@ -1119,7 +1118,12 @@ class PluginInvocationTests: XCTestCase {
}
"""
try localFileSystem.writeFileContents(myPluginTargetDir.appending(component: "plugin.swift"), string: content)
let tripleString = "x86_64-apple-macos15"
let artifactVariants = artifactSupportedTriples.map {
"""
{ "path": "LocalBinaryTool.sh", "supportedTriples": ["\($0.tripleString)"] }
"""
}

try localFileSystem.writeFileContents(packageDir.appending(components: "Binaries", "LocalBinaryTool.artifactbundle", "info.json")) {
$0 <<< """
{ "schemaVersion": "1.0",
Expand All @@ -1128,9 +1132,7 @@ class PluginInvocationTests: XCTestCase {
"type": "executable",
"version": "1.2.3",
"variants": [
{ "path": "LocalBinaryTool.sh",
"supportedTriples": ["\(tripleString)"]
},
\(artifactVariants.joined(separator: ","))
]
}
}
Expand Down Expand Up @@ -1166,12 +1168,16 @@ class PluginInvocationTests: XCTestCase {
XCTAssertEqual(buildToolPlugin.name, "Foo")
XCTAssertEqual(buildToolPlugin.capability, .buildTool)

// Construct a toolchain with a made-up host/target triple
let destination = try Destination.default
let toolchain = try UserToolchain(destination: Destination(hostTriple: hostTriple, targetTriple: hostTriple, sdkRootDir: destination.sdkRootDir, toolchainBinDir: destination.toolchainBinDir))

// Create a plugin script runner for the duration of the test.
let pluginCacheDir = tmpPath.appending(component: "plugin-cache")
let pluginScriptRunner = DefaultPluginScriptRunner(
fileSystem: localFileSystem,
cacheDir: pluginCacheDir,
toolchain: try UserToolchain.default
toolchain: toolchain
)

// Invoke build tool plugin
Expand All @@ -1186,13 +1192,54 @@ class PluginInvocationTests: XCTestCase {
observabilityScope: observability.topScope,
fileSystem: localFileSystem
)
var checked = false
try pluginResultChecker(result)
}
}

func testParseArtifactNotSupportedOnTargetPlatform() throws {
let hostTriple = try UserToolchain.default.triple
let artifactSupportedTriples = try [Triple("riscv64-apple-windows-android")]

var checked = false
try checkParseArtifactsPlatformCompatibility(artifactSupportedTriples: artifactSupportedTriples, hostTriple: hostTriple) { result in
if let pluginResult = result.first,
let diag = pluginResult.value.first?.diagnostics,
diag.description == "[[error]: Tool ‘LocalBinaryTool’ is not supported on the target platform]" {
checked = true
}
XCTAssertTrue(checked)
}
XCTAssertTrue(checked)
}

func testParseArtifactsDoesNotCheckPlatformVersion() throws {
#if !os(macOS)
throw XCTSkip("platform versions are only available if the host is macOS")
#else
let hostTriple = try UserToolchain.default.triple
let artifactSupportedTriples = try [Triple("\(hostTriple.withoutVersion().tripleString)20.0")]

try checkParseArtifactsPlatformCompatibility(artifactSupportedTriples: artifactSupportedTriples, hostTriple: hostTriple) { result in
result.forEach {
$0.value.forEach {
XCTAssertTrue($0.succeeded, "plugin unexpectedly failed")
XCTAssertEqual($0.diagnostics.map { $0.message }, [], "plugin produced unexpected diagnostics")
}
}
}
#endif
}

func testParseArtifactsConsidersAllSupportedTriples() throws {
let hostTriple = try UserToolchain.default.triple
let artifactSupportedTriples = [hostTriple, try Triple("riscv64-apple-windows-android")]

try checkParseArtifactsPlatformCompatibility(artifactSupportedTriples: artifactSupportedTriples, hostTriple: hostTriple) { result in
result.forEach {
$0.value.forEach {
XCTAssertTrue($0.succeeded, "plugin unexpectedly failed")
XCTAssertEqual($0.diagnostics.map { $0.message }, [], "plugin produced unexpected diagnostics")
}
}
}
}
}