From 1d837ce5d389673015c9ead64adfa8752b972a95 Mon Sep 17 00:00:00 2001 From: Dima Hutsuliak Date: Wed, 3 Jul 2024 16:34:37 +0200 Subject: [PATCH 1/4] Introduce a custom Hashable implementation for BuildProduct --- Sources/ScipioKit/DescriptionPackage.swift | 18 +++++++++++++ .../DescriptionPackageTests.swift | 4 ++- .../Fixtures/TestingPackage/Package.swift | 26 ++++++++++++++++--- .../Plugins/MyPlugin/MyPlugin.swift | 6 +++++ .../ExternalExecutableTarget.swift | 4 +++ .../BasicPackage.swift | 0 6 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Plugins/MyPlugin/MyPlugin.swift create mode 100644 Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/ExecutableTarget/ExternalExecutableTarget.swift rename Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/{TestingPackage => MyTarget}/BasicPackage.swift (100%) diff --git a/Sources/ScipioKit/DescriptionPackage.swift b/Sources/ScipioKit/DescriptionPackage.swift index 74d6ac10..44daf01d 100644 --- a/Sources/ScipioKit/DescriptionPackage.swift +++ b/Sources/ScipioKit/DescriptionPackage.swift @@ -241,4 +241,22 @@ struct BuildProduct: Hashable, Sendable { var binaryTarget: BinaryTarget? { target.underlyingTarget as? BinaryTarget } + + func hash(into hasher: inout Hasher) { + // Important: Relevant for swift-6.0+ toolchain versions. For the versions below + // this change has no effect as SwiftPM provides its own proper `Hashable` + // implementations for both `ResolvedPackage` and `ResolvedTarget`. + // + // We cannot directly use `ResolvedModule.id` here as `id` also includes `BuildTriple`. + // The reason for this is that `ResolvedModule.buildTriple` is parent-dependent; more + // specifically, the same `ResolvedModule` will have a different build triple depending + // on whether it is in a root or dependency position. + // For more context, see `ResolvedModule.updateBuildTriplesOfDependencies`. + // + // At the same time, build triples remain irrelevant for the `Scipio` use case where the + // build product must be the same regardless of the triple. Meanwhile, the target name and + // package identity remain relevant and unambiguously identify the build product. + hasher.combine(target.name) + hasher.combine(package.identity) + } } diff --git a/Tests/ScipioKitTests/DescriptionPackageTests.swift b/Tests/ScipioKitTests/DescriptionPackageTests.swift index 1f57a8d5..2621013b 100644 --- a/Tests/ScipioKitTests/DescriptionPackageTests.swift +++ b/Tests/ScipioKitTests/DescriptionPackageTests.swift @@ -74,10 +74,12 @@ final class DescriptionPackageTests: XCTestCase { XCTAssertEqual(package.name, "TestingPackage") XCTAssertEqual( - Set(try package.resolveBuildProducts().map(\.target.name)), + try package.resolveBuildProducts().map(\.target.name), [ "Logging", "TestingPackage", + "ExecutableTarget", + "MyPlugin" ] ) } diff --git a/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Package.swift b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Package.swift index 67a25eb1..25a0ae2d 100644 --- a/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Package.swift +++ b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Package.swift @@ -10,20 +10,38 @@ let package = Package( // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "TestingPackage", - targets: ["TestingPackage"]), + targets: ["MyTarget"] + ), + .plugin( + name: "MyPlugin", + targets: ["MyPlugin"] + ) ], dependencies: [ .package(url: "https://github.com/apple/swift-log.git", .upToNextMinor(from: "1.4.4")), ], targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. + // Directly exported targets .target( - name: "TestingPackage", + name: "MyTarget", dependencies: [ .product(name: "Logging", package: "swift-log"), ] ), + .plugin( + name: "MyPlugin", + capability: .command( + intent: .custom( + verb: "my-plugin-verb", + description: "my-plugin-description")), + dependencies: ["ExecutableTarget"] + ), + // Transitevly exported targets + .executableTarget( + name: "ExecutableTarget", + dependencies: ["MyTarget"] + ), + // Not exported (internal) targets .executableTarget( name: "InternalExecutableTarget", dependencies: ["InternalRegularTarget"] diff --git a/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Plugins/MyPlugin/MyPlugin.swift b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Plugins/MyPlugin/MyPlugin.swift new file mode 100644 index 00000000..4d1e40a6 --- /dev/null +++ b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Plugins/MyPlugin/MyPlugin.swift @@ -0,0 +1,6 @@ +import PackagePlugin + +@main +struct MyPlugin: CommandPlugin { + func performCommand(context: PluginContext, arguments: [String]) async throws {} +} diff --git a/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/ExecutableTarget/ExternalExecutableTarget.swift b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/ExecutableTarget/ExternalExecutableTarget.swift new file mode 100644 index 00000000..07c0ee18 --- /dev/null +++ b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/ExecutableTarget/ExternalExecutableTarget.swift @@ -0,0 +1,4 @@ +@main +public struct ExecutableTarget { + static func main() {} +} diff --git a/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/TestingPackage/BasicPackage.swift b/Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/MyTarget/BasicPackage.swift similarity index 100% rename from Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/TestingPackage/BasicPackage.swift rename to Tests/ScipioKitTests/Resources/Fixtures/TestingPackage/Sources/MyTarget/BasicPackage.swift From a002d2e09301b761df5551bd21b8281b93068414 Mon Sep 17 00:00:00 2001 From: Dima Hutsuliak Date: Sat, 6 Jul 2024 18:04:31 +0200 Subject: [PATCH 2/4] Fix linting issue --- Tests/ScipioKitTests/DescriptionPackageTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ScipioKitTests/DescriptionPackageTests.swift b/Tests/ScipioKitTests/DescriptionPackageTests.swift index 2621013b..88130900 100644 --- a/Tests/ScipioKitTests/DescriptionPackageTests.swift +++ b/Tests/ScipioKitTests/DescriptionPackageTests.swift @@ -79,7 +79,7 @@ final class DescriptionPackageTests: XCTestCase { "Logging", "TestingPackage", "ExecutableTarget", - "MyPlugin" + "MyPlugin", ] ) } From 5b78303617478e8ce859e04cc5cfe59d999dc0da Mon Sep 17 00:00:00 2001 From: Dima Hutsuliak Date: Sun, 7 Jul 2024 09:14:16 +0200 Subject: [PATCH 3/4] Use the correct target name in a test --- Tests/ScipioKitTests/DescriptionPackageTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/ScipioKitTests/DescriptionPackageTests.swift b/Tests/ScipioKitTests/DescriptionPackageTests.swift index 88130900..1fa49708 100644 --- a/Tests/ScipioKitTests/DescriptionPackageTests.swift +++ b/Tests/ScipioKitTests/DescriptionPackageTests.swift @@ -77,7 +77,7 @@ final class DescriptionPackageTests: XCTestCase { try package.resolveBuildProducts().map(\.target.name), [ "Logging", - "TestingPackage", + "MyTarget", "ExecutableTarget", "MyPlugin", ] From e471c99d5f0847ae577839e72c7c91b6a1ab34a0 Mon Sep 17 00:00:00 2001 From: Dima Hutsuliak Date: Sun, 7 Jul 2024 11:18:38 +0200 Subject: [PATCH 4/4] Update Tests/ScipioKitTests/DescriptionPackageTests.swift Co-authored-by: Kohki Miki --- Tests/ScipioKitTests/DescriptionPackageTests.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/ScipioKitTests/DescriptionPackageTests.swift b/Tests/ScipioKitTests/DescriptionPackageTests.swift index 1fa49708..c4e74a27 100644 --- a/Tests/ScipioKitTests/DescriptionPackageTests.swift +++ b/Tests/ScipioKitTests/DescriptionPackageTests.swift @@ -80,7 +80,8 @@ final class DescriptionPackageTests: XCTestCase { "MyTarget", "ExecutableTarget", "MyPlugin", - ] + ], + "Order of the resolved products should be correct" ) }