Description
Scenario
You have a Swift package for iOS only with some dependencies including algoliasearch-client-swift.
let package = Package(
name: "ExamplePackage",
platforms: [
.iOS(.v16),
],
dependencies: [
.package(url: "https://github.com/algolia/algoliasearch-client-swift", exact: "9.27.0"),
.package(url: "https://github.com/getsentry/sentry-cocoa", exact: "8.53.2"),
]
)
If you open this package in Xcode the os directive will be macOS and the Linux specific dependencies will be excluded on manifest compilation:
|
#if os(Linux) |
|
extraPackageDependencies.append(contentsOf: [ |
|
.package(url: "https://github.com/apple/swift-crypto.git", from: "3.2.0"), |
|
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"), |
|
]) |
|
extraTargetDependencies.append(contentsOf: [ |
|
.product(name: "Crypto", package: "swift-crypto"), |
|
.product(name: "Logging", package: "swift-log"), |
|
]) |
|
#endif |
)
Therefor the local (macOS) Package.resolved does not contain those dependencies.
When setting up Dependabot for the package repository the Package.resolved diff in the resulting PRs will not only contain the version change but also the Linux-specific dependencies (see the attached logs) because Dependabot runs on ubuntu-latest runners; it will not compile there, just use swift package show-dependencies --format json which includes manifest compilation.
Solutions
I think it is generally not recommended to use os directives in the package manifest and this is a good example why. There are 2 proper fixes I can think of right now:
1) Remove all os directives in the manifest
Instead of making the dependencies conditional on the compilation level, always add them and specify the condition on each target dependency:
dependencies: [
.product(name: "Crypto", package: "swift-crypto", condition: .when(platforms: [.linux])),
.product(name: "Logging", package: "swift-log", condition: .when(platforms: [.linux])),
]
This has the downside Apple platforms will also fetch those dependencies but is not a big deal IMO.
2) Create separate repositories for Apple and Linux
This solution is more flexible because you get platform-specific manifests but has the downside of cross-platform consuming packages, e.g. a Vapor backend service that gets developed on macOS but deployed on Linux (in this scenario the conditional dependency is also problematic BTW); it could be solved by adding both packages and adding them with condition but could be not obvious.
I currently maintain an Apple-only fork to solve the issue for us but hope this can be addressed.
Client
All
Version
9.27.0
Relevant log output
diff --git a/Package.resolved b/Package.resolved
index 75468d6a..0bdd9193 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -1,5 +1,5 @@
{
- "originHash" : "34f9005d46d2014727c22ce7b6c9522e9fe354c702311d6408ca66b0872bfc70",
+ "originHash" : "fc9f6186bdff1d0ba70b7f5b30c847ba6e07ad82e2eab4eb3c7b13232ed05f0b",
"pins" : [
{
"identity" : "algoliasearch-client-swift",
@@ -168,8 +168,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/getsentry/sentry-cocoa",
"state" : {
- "revision" : "ca92efeb24b10052cd2a79e5205f42c5a16770ec",
- "version" : "8.53.2"
+ "revision" : "3c2eee7773df58bdfb9e10e72d9a4be44253e0d9",
+ "version" : "8.55.0"
}
},
{
@@ -208,6 +208,15 @@
"version" : "1.5.0"
}
},
+ {
+ "identity" : "swift-asn1",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-asn1.git",
+ "state" : {
+ "revision" : "f70225981241859eb4aa1a18a75531d26637c8cc",
+ "version" : "1.4.0"
+ }
+ },
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
@@ -217,6 +226,15 @@
"version" : "1.1.4"
}
},
+ {
+ "identity" : "swift-crypto",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-crypto.git",
+ "state" : {
+ "revision" : "334e682869394ee239a57dbe9262bff3cd9495bd",
+ "version" : "3.14.0"
+ }
+ },
{
"identity" : "swift-eventsource",
"kind" : "remoteSourceControl",
@@ -235,6 +253,15 @@
"version" : "1.4.0"
}
},
+ {
+ "identity" : "swift-log",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-log.git",
+ "state" : {
+ "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2",
+ "version" : "1.6.4"
+ }
+ },
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
Description
Scenario
You have a Swift package for iOS only with some dependencies including
algoliasearch-client-swift.If you open this package in Xcode the
osdirective will be macOS and the Linux specific dependencies will be excluded on manifest compilation:algoliasearch-client-swift/Package.swift
Lines 18 to 27 in 583eba7
Therefor the local (macOS)
Package.resolveddoes not contain those dependencies.When setting up Dependabot for the package repository the
Package.resolveddiff in the resulting PRs will not only contain the version change but also the Linux-specific dependencies (see the attached logs) because Dependabot runs on ubuntu-latest runners; it will not compile there, just useswift package show-dependencies --format jsonwhich includes manifest compilation.Solutions
I think it is generally not recommended to use os directives in the package manifest and this is a good example why. There are 2 proper fixes I can think of right now:
1) Remove all os directives in the manifest
Instead of making the dependencies conditional on the compilation level, always add them and specify the condition on each target dependency:
This has the downside Apple platforms will also fetch those dependencies but is not a big deal IMO.
2) Create separate repositories for Apple and Linux
This solution is more flexible because you get platform-specific manifests but has the downside of cross-platform consuming packages, e.g. a Vapor backend service that gets developed on macOS but deployed on Linux (in this scenario the conditional dependency is also problematic BTW); it could be solved by adding both packages and adding them with condition but could be not obvious.
I currently maintain an Apple-only fork to solve the issue for us but hope this can be addressed.
Client
All
Version
9.27.0
Relevant log output