Introduction
Adoption tooling for upcoming features pitch proposed to extend the Swift compiler to add an integrated mechanism for producing source-compatible adjustments to code that can be applied to preserve its behavior once a given eligible upcoming feature is enabled.
To enable seemless migration experience for Swift packages, I'd like to propose a new Swift Package Manager command - swift migrate
to complement the Swift compiler-side changes.
The command would accept one or more features that have migration mode enabled and optionally a set of targets to migrate, if no targets are specified the whole package is going to be migrated to use new features.
Interface
USAGE: swift migrate [<options>] --to-feature <to-feature> ... OPTIONS: --targets <targets> The targets to migrate to specified set of features or a new language mode. --to-feature <to-feature> The Swift language upcoming/experimental feature to migrate to. -h, --help Show help information.
Use case
swift migrate --targets MyTarget,MyTest --to-feature ExistentialAny
This command would attempt to build MyTarget
and MyTest
targets with ExistentialAny:migrate
feature flag, apply any fix-its associated with
the feature produced by the compiler, and update the Package.swift
to
enable the feature(s) if both of the previous actions are successful:
.target( name: "MyTarget", ... swiftSettings: [ // ... existing settings, .enableUpcomingFeature("ExistentialAny") ] ) ... .testTarget( name: "MyTest", ... swiftSettings: [ // ... existing settings, .enableUpcomingFeature("ExistentialAny") ] )
In the "whole package" mode, every target is going to be updated to include
new feature flag(s). This is supported by the same functionality as swift package add-setting
command.
If it's, for some reason, impossible to add the setting the diagnostic message would suggest what to add and where i.e. ...; please add '.enableUpcomingFeature("ExistentialAny")' to
MyTarget target manually
.
Impact on Interface
This proposal introduces a new command but does that does not interfere with existing commands. It follows the same pattern as swift build
and swift test
in a consistent manner.