Skip to content

Commit eb2d5b3

Browse files
authored
[6.0] Deprecate experimental Swift SDK CLI in favor of unprefixed counterparts (#7515)
Cherry-pick of #7512, #7507, and #7517. **Explanation**: Since [SE-0387](https://github.com/apple/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md) was accepted and available in Swift 5.9 and Swift 5.10, it's time to deprecate relevant CLI with the `experimental` prefix. There are enough users of this command and corresponding options on `swift build` in the wild, which means those should be deprecated first before removing. **Scope**: isolated to `swift sdk` command and 2 Swift SDK options on `swift build`. **Risk**: low, these commands options have no impact on `swift build` outside of cross-compilation use cases. **Testing**: added new end-to-end tests in `SDKCommandTests` in #7517 cherry-picked here. **Issue**: N/A **Reviewer**: @bnbarham
1 parent 0b53c3c commit eb2d5b3

File tree

16 files changed

+229
-10
lines changed

16 files changed

+229
-10
lines changed

CHANGELOG.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
Note: This is in reverse chronological order, so newer entries are added to the top.
22

3-
Swift Next
3+
Swift 6.0
44
-----------
55

6+
* [#7507]
7+
8+
`swift experimental-sdk` command is deprecated with `swift sdk` command replacing it. `--experimental-swift-sdk` and
9+
`--experimental-swift-sdks-path` options on `swift build` are deprecated with replacements that don't have the
10+
`experimental` prefix.
11+
612
* [#7202]
713

814
Package manifests can now access information about the Git repository the given package is in via the context object's
915
`gitInformation` property. This allows to determine the current tag (if any), the current commit and whether or not there are uncommited changes.
1016

17+
* [#7201]
18+
19+
`// swift-tools-version:` can now be specified on subsequent lines of `Package.swift`, for example when first few lines are required to contain a licensing comment header.
20+
21+
Swift 5.10
22+
-----------
1123
* [#7010]
1224

1325
On macOS, `swift build` and `swift run` now produce binaries that allow backtraces in debug builds. Pass `SWIFT_BACKTRACE=enable=yes` environment variable to enable backtraces on such binaries when running them.
@@ -387,4 +399,9 @@ Swift 3.0
387399
[#6276]: https://github.com/apple/swift-package-manager/pull/6276
388400
[#6540]: https://github.com/apple/swift-package-manager/pull/6540
389401
[#6663]: https://github.com/apple/swift-package-manager/pull/6663
402+
[#7010]: https://github.com/apple/swift-package-manager/pull/7010
390403
[#7101]: https://github.com/apple/swift-package-manager/pull/7101
404+
[#7118]: https://github.com/apple/swift-package-manager/pull/7118
405+
[#7201]: https://github.com/apple/swift-package-manager/pull/7201
406+
[#7202]: https://github.com/apple/swift-package-manager/pull/7202
407+
[#7507]: https://github.com/apple/swift-package-manager/pull/7507

Fixtures/SwiftSDKs/Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// This empty file tells test fixture logic to copy this directory's content to the test case temp directory.

Package.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,12 @@ let package = Package(
508508
),
509509
.executableTarget(
510510
/** Interacts with Swift SDKs used for cross-compilation */
511+
name: "swift-sdk",
512+
dependencies: ["Commands", "SwiftSDKCommand"],
513+
exclude: ["CMakeLists.txt"]
514+
),
515+
.executableTarget(
516+
/** Deprecated command superseded by `swift-sdk` */
511517
name: "swift-experimental-sdk",
512518
dependencies: ["Commands", "SwiftSDKCommand"],
513519
exclude: ["CMakeLists.txt"]

Sources/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ add_subdirectory(SPMSQLite3)
3333
add_subdirectory(swift-bootstrap)
3434
add_subdirectory(swift-build)
3535
add_subdirectory(swift-experimental-sdk)
36+
add_subdirectory(swift-sdk)
3637
add_subdirectory(swift-package)
3738
add_subdirectory(swift-run)
3839
add_subdirectory(swift-test)

Sources/CoreCommands/Options.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,15 @@ package struct LocationOptions: ParsableArguments {
111111
@Option(name: .customLong("destination"), help: .hidden, completion: .directory)
112112
package var customCompileDestination: AbsolutePath?
113113

114-
/// Path to the directory containing installed Swift SDKs.
115114
@Option(name: .customLong("experimental-swift-sdks-path"), help: .hidden, completion: .directory)
115+
package var deprecatedSwiftSDKsDirectory: AbsolutePath?
116+
117+
/// Path to the directory containing installed Swift SDKs.
118+
@Option(
119+
name: .customLong("swift-sdks-path"),
120+
help: "Path to the directory containing installed Swift SDKs",
121+
completion: .directory
122+
)
116123
package var swiftSDKsDirectory: AbsolutePath?
117124

118125
@Option(
@@ -406,8 +413,14 @@ package struct BuildOptions: ParsableArguments {
406413
)
407414
package var architectures: [String] = []
408415

409-
/// Filter for selecting a specific Swift SDK to build with.
410416
@Option(name: .customLong("experimental-swift-sdk"), help: .hidden)
417+
package var deprecatedSwiftSDKSelector: String?
418+
419+
/// Filter for selecting a specific Swift SDK to build with.
420+
@Option(
421+
name: .customLong("swift-sdk"),
422+
help: "Filter for selecting a specific Swift SDK to build with"
423+
)
411424
package var swiftSDKSelector: String?
412425

413426
/// Which compile-time sanitizers should be enabled.

Sources/CoreCommands/SwiftCommandState.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,13 @@ package final class SwiftCommandState {
350350
fileSystem: fileSystem
351351
)
352352
self.sharedCacheDirectory = try getSharedCacheDirectory(options: options, fileSystem: fileSystem)
353+
if options.locations.deprecatedSwiftSDKsDirectory != nil {
354+
self.observabilityScope.emit(
355+
warning: "`--experimental-swift-sdks-path` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdks-path` instead."
356+
)
357+
}
353358
self.sharedSwiftSDKsDirectory = try fileSystem.getSharedSwiftSDKsDirectory(
354-
explicitDirectory: options.locations.swiftSDKsDirectory
359+
explicitDirectory: options.locations.swiftSDKsDirectory ?? options.locations.deprecatedSwiftSDKsDirectory
355360
)
356361

357362
// set global process logging handler
@@ -821,14 +826,20 @@ package final class SwiftCommandState {
821826
do {
822827
let hostToolchain = try _hostToolchain.get()
823828
hostSwiftSDK = hostToolchain.swiftSDK
829+
830+
if options.build.deprecatedSwiftSDKSelector != nil {
831+
self.observabilityScope.emit(
832+
warning: "`--experimental-swift-sdk` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdk` instead."
833+
)
834+
}
824835
swiftSDK = try SwiftSDK.deriveTargetSwiftSDK(
825836
hostSwiftSDK: hostSwiftSDK,
826837
hostTriple: hostToolchain.targetTriple,
827838
customCompileDestination: options.locations.customCompileDestination,
828839
customCompileTriple: options.build.customCompileTriple,
829840
customCompileToolchain: options.build.customCompileToolchain,
830841
customCompileSDK: options.build.customCompileSDK,
831-
swiftSDKSelector: options.build.swiftSDKSelector,
842+
swiftSDKSelector: options.build.swiftSDKSelector ?? options.build.deprecatedSwiftSDKSelector,
832843
architectures: options.build.architectures,
833844
store: store,
834845
observabilityScope: self.observabilityScope,

Sources/PackageModel/SwiftSDKs/SwiftSDKBundleStore.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public final class SwiftSDKBundleStore {
4646
case let .noMatchingSwiftSDK(selector, hostTriple):
4747
return """
4848
No Swift SDK found matching query `\(selector)` and host triple \
49-
`\(hostTriple.tripleString)`. Use `swift experimental-sdk list` command to see \
49+
`\(hostTriple.tripleString)`. Use `swift sdk list` command to see \
5050
available Swift SDKs.
5151
"""
5252
}

Sources/SPMTestSupport/SwiftPMProduct.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ package enum SwiftPM {
2525
case Registry
2626
case Test
2727
case Run
28+
case experimentalSDK
29+
case sdk
2830
}
2931

3032
extension SwiftPM {
@@ -41,6 +43,10 @@ extension SwiftPM {
4143
return "swift-test"
4244
case .Run:
4345
return "swift-run"
46+
case .experimentalSDK:
47+
return "swift-experimental-sdk"
48+
case .sdk:
49+
return "swift-sdk"
4450
}
4551
}
4652

Sources/SwiftSDKCommand/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Swift SDKs Tool
1+
# Swift SDKs Command
22

3-
This module implements `swift experimental-sdk` command and its subcommands, which allow managing artifact
3+
This module implements `swift sdk` command and its subcommands, which allow managing artifact
44
bundles used as Swift SDKs, as specified in [SE-0387](https://github.com/apple/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md).

Sources/SwiftSDKCommand/SwiftSDKCommand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Basics
1515

1616
package struct SwiftSDKCommand: AsyncParsableCommand {
1717
package static let configuration = CommandConfiguration(
18-
commandName: "experimental-sdk",
18+
commandName: "sdk",
1919
_superCommandName: "swift",
2020
abstract: "Perform operations on Swift SDKs.",
2121
version: SwiftVersion.current.completeDisplayString,

Sources/swift-experimental-sdk/Entrypoint.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import SwiftSDKCommand
1515
@main
1616
struct Entrypoint {
1717
static func main() async {
18+
print("warning: `swift experimental-sdk` command is deprecated and will be removed in a future version of SwiftPM. Use `swift sdk` instead.")
1819
await SwiftSDKCommand.main()
1920
}
2021
}

Sources/swift-package-manager/SwiftPM.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ struct SwiftPM {
4242
case "swift-build":
4343
await SwiftBuildCommand.main()
4444
case "swift-experimental-sdk":
45+
print("warning: `swift experimental-sdk` command is deprecated and will be removed in a future version of SwiftPM. Use `swift sdk` instead.")
46+
fallthrough
47+
case "swift-sdk":
4548
await SwiftSDKCommand.main()
4649
case "swift-test":
4750
await SwiftTestCommand.main()

Sources/swift-sdk/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# This source file is part of the Swift open source project
2+
#
3+
# Copyright (c) 2023 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
add_executable(swift-sdk
10+
Entrypoint.swift)
11+
target_link_libraries(swift-sdk PRIVATE
12+
SwiftSDKCommand)
13+
14+
target_compile_options(swift-sdk PRIVATE
15+
-parse-as-library)
16+
17+
install(TARGETS swift-sdk
18+
RUNTIME DESTINATION bin)

Sources/swift-sdk/Entrypoint.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSDKCommand
14+
15+
@main
16+
struct Entrypoint {
17+
static func main() async {
18+
await SwiftSDKCommand.main()
19+
}
20+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Basics
14+
import Commands
15+
import SPMTestSupport
16+
import XCTest
17+
18+
import class TSCBasic.Process
19+
import enum TSCBasic.ProcessEnv
20+
21+
private let deprecationWarning = "warning: `swift experimental-sdk` command is deprecated and will be removed in a future version of SwiftPM. Use `swift sdk` instead."
22+
23+
final class SDKCommandTests: CommandsTestCase {
24+
func testUsage() throws {
25+
for command in [SwiftPM.sdk, SwiftPM.experimentalSDK] {
26+
let stdout = try command.execute(["-help"]).stdout
27+
XCTAssert(stdout.contains("USAGE: swift sdk <subcommand>") || stdout.contains("USAGE: swift sdk [<subcommand>]"), "got stdout:\n" + stdout)
28+
}
29+
}
30+
31+
func testVersion() throws {
32+
for command in [SwiftPM.sdk, SwiftPM.experimentalSDK] {
33+
let stdout = try command.execute(["--version"]).stdout
34+
XCTAssert(stdout.contains("Swift Package Manager"), "got stdout:\n" + stdout)
35+
}
36+
}
37+
38+
func testInstallSDK() throws {
39+
for command in [SwiftPM.sdk, SwiftPM.experimentalSDK] {
40+
try fixture(name: "SwiftSDKs") { fixturePath in
41+
for bundle in ["test-sdk.artifactbundle.tar.gz", "test-sdk.artifactbundle.zip"] {
42+
var (stdout, stderr) = try command.execute(
43+
[
44+
"install",
45+
"--swift-sdks-path", fixturePath.pathString,
46+
fixturePath.appending(bundle).pathString
47+
]
48+
)
49+
50+
if command == .experimentalSDK {
51+
XCTAssertMatch(stdout, .contains(deprecationWarning))
52+
}
53+
54+
// We only expect tool's output on the stdout stream.
55+
XCTAssertMatch(
56+
stdout,
57+
.contains("\(bundle)` successfully installed as test-sdk.artifactbundle.")
58+
)
59+
60+
XCTAssertEqual(stderr.count, 0)
61+
62+
(stdout, stderr) = try command.execute(
63+
["list", "--swift-sdks-path", fixturePath.pathString])
64+
65+
if command == .experimentalSDK {
66+
XCTAssertMatch(stdout, .contains(deprecationWarning))
67+
}
68+
69+
// We only expect tool's output on the stdout stream.
70+
XCTAssertMatch(stdout, .contains("test-artifact"))
71+
XCTAssertEqual(stderr.count, 0)
72+
73+
XCTAssertThrowsError(try command.execute(
74+
[
75+
"install",
76+
"--swift-sdks-path", fixturePath.pathString,
77+
fixturePath.appending(bundle).pathString
78+
]
79+
)) { error in
80+
guard case SwiftPMError.executionFailure(_, _, let stderr) = error else {
81+
XCTFail()
82+
return
83+
}
84+
85+
XCTAssertTrue(
86+
stderr.contains(
87+
"Error: Swift SDK bundle with name `test-sdk.artifactbundle` is already installed. Can't install a new bundle with the same name."
88+
),
89+
"got stderr: \(stderr)"
90+
)
91+
}
92+
93+
if command == .experimentalSDK {
94+
XCTAssertMatch(stdout, .contains(deprecationWarning))
95+
}
96+
97+
(stdout, stderr) = try command.execute(
98+
["remove", "--swift-sdks-path", fixturePath.pathString, "test-artifact"])
99+
100+
if command == .experimentalSDK {
101+
XCTAssertMatch(stdout, .contains(deprecationWarning))
102+
}
103+
104+
// We only expect tool's output on the stdout stream.
105+
XCTAssertMatch(stdout, .contains("test-sdk.artifactbundle` was successfully removed from the file system."))
106+
XCTAssertEqual(stderr.count, 0)
107+
108+
(stdout, stderr) = try command.execute(
109+
["list", "--swift-sdks-path", fixturePath.pathString])
110+
111+
if command == .experimentalSDK {
112+
XCTAssertMatch(stdout, .contains(deprecationWarning))
113+
}
114+
115+
// We only expect tool's output on the stdout stream.
116+
XCTAssertNoMatch(stdout, .contains("test-artifact"))
117+
XCTAssertEqual(stderr.count, 0)
118+
}
119+
}
120+
}
121+
}
122+
}

Utilities/bootstrap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def install_swiftpm(prefix, args):
432432
# Install the swift-package-manager tool and create symlinks to it.
433433
cli_tool_dest = os.path.join(prefix, "bin")
434434
install_binary(args, "swift-package-manager", os.path.join(cli_tool_dest, "swift-package"), destination_is_directory=False)
435-
for tool in ["swift-build", "swift-test", "swift-run", "swift-package-collection", "swift-package-registry", "swift-experimental-sdk"]:
435+
for tool in ["swift-build", "swift-test", "swift-run", "swift-package-collection", "swift-package-registry", "swift-sdk", "swift-experimental-sdk"]:
436436
src = "swift-package"
437437
dest = os.path.join(cli_tool_dest, tool)
438438
note("Creating tool symlink from %s to %s" % (src, dest))

0 commit comments

Comments
 (0)