What is your evaluation of the proposal?
+1 for the idea but I have a couple of issues with the proposed syntax.
1. I think .linux
should become a static func
to be consistent with Apple platform functions.
struct SupportedPlatform {
...
static func linux() -> SupportedPlatform
}
platforms: [
.macOS(.v10_14), .iOS(.v12), .linux()
]
2. In my opinion, version arguments should be optional and default to .default
. This might be achieved by adding a .default
static variable to platform deployment target structures:
extension SupportedPlatform.MacOSVersion {
static let default: MacOSVersion
...
}
struct SupportedPlatform {
static func macOS(_ version: MacOSVersion = .default) -> SupportedPlatform
static func tvOS(_ version: TVOSVersion = .default) -> SupportedPlatform
static func iOS(_ version: IOSVersion = .default) -> SupportedPlatform
static func watchOS(_ version: WatchOSVersion = .default) -> SupportedPlatform
static func linux() -> SupportedPlatform
}
Then, the following declaration would mean that a package supports only macOS and iOS at their default deployment targets (such syntax is not possible with the proposed API):
platforms: [
.macOS(), .iOS()
]
3. I agree with Max that the behavior of .all
is definitely confusing. When I encountered it as the last element in the array, I thought this would be an example of invalid or ambiguous syntax.
I see 2 potential improvements of this. First one is to rename .all
to something more meaningful, like .rest
or .other
. I don't have a strong candidate, naming is hard. I just feel .all
is too bad.
The second option is for .all
to represent all platforms at their default deployment targets. The user would be able to either use .all
, or specify platforms explicitly.
extension Array where Element == SupportedPlatform {
static func all() -> [SupportedPlatform]
}
class Package {
init(
name: String,
platforms: [SupportedPlatform] = .all(),
...
)
}
By making such a change (and assuming my previous points are taken into consideration), these equivalent declarations would mean that the package supports all platforms at default deployment targets:
platforms: .all()
platforms: [
.macOS(), .iOS(), .watchOS(), .tvOS(), .linux()
]
platforms: [
.macOS(.default), .iOS(.default), .watchOS(.default), .tvOS(.default), .linux()
]
This declaration would mean that the target should use macOS 10.13, iOS 12 and default deployment targets on watchOS, tvOS and Linux:
platforms: [
.macOS(.v10_13), .iOS(.v12), .watchOS(), .tvOS(), .linux()
]
And this declaration would mean that the package only supports macOS and iOS and SPM should emit an error is this package is used on any other platform:
platforms: [
.macOS(), .iOS()
]
Is the problem being addressed significant enough to warrant a change to the Swift Package Manager?
Yes.
Does this proposal fit well with the feel and direction of Swift?
Yes.
If you have used other languages, libraries, or package managers with a similar feature, how do you feel that this proposal compares to those?
I used CocoaPods which allows to specify deployment targets in .podspec
and Carthage which reads it from .xcodeproj
. I feel the approach of SPM is the best of all of them.
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
Read the proposal and this thread.