Skip to content

Commit 9f809ad

Browse files
authored
Merge branch 'main' into revert-3677-revert-collections-again
2 parents 5a48a53 + d5079ad commit 9f809ad

File tree

71 files changed

+2448
-1145
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+2448
-1145
lines changed

CHANGELOG.md

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ Note: This is in reverse chronological order, so newer entries are added to the
22

33
Swift 5.6
44
-----------
5+
* [SE-0332]
6+
7+
Package plugins of the type `command` can now be declared in packages that specify a tools version of 5.6 or later, and can be invoked using the `swift package` subcommand.
8+
59
* [#3649]
610

711
Semantic version dependencies can now be resolved against Git tag names that contain only major and minor version identifiers. A tag with the form `X.Y` will be treated as `X.Y.0`. This improves compatibility with existing repositories.
@@ -22,6 +26,28 @@ Swift 5.6
2226

2327
Adding a dependency requirement can now be done with the convenience initializer `.package(url: String, exact: Version)`.
2428

29+
* [#3641]
30+
31+
Dependency requirement enum calling convention is deprecated in favour of labeled argument:
32+
* `.package(url: String, .branch(String))` -> `.package(url: String, branch: String)`
33+
* `.package(url: String, .revision(String))` -> `.package(url: String, revision: String)`
34+
* `.package(url: String, .exact(Version))` -> `.package(url: String, exact: Version)`
35+
36+
* [#3717]
37+
38+
Introduce a second version of `Package.resolved` file format which more accurately captures package identity.
39+
40+
* [#3890]
41+
42+
To increase the security of packages, SwiftPM performs trust on first use (TOFU) validation. The fingerprint of a package is now being recorded when the package is first downloaded from a Git repository or package registry. Subsequent downloads must have fingerpints matching previous recorded values, otherwise it would result in build warnings or failures depending on settings.
43+
44+
* [#3670], [#3901], [#3942]
45+
46+
Location of configuration files (including mirror file) have changed to accomodate new features that require more robust configuration directories structure, such as SE-0292:
47+
* `<project>/.swiftpm/config` (mirrors file) was moved to `<project>/.swiftpm/configuration/mirrors.json`. SwiftPM 5.6 will automatically copy the file from the old location to the new one and emit a warning to prompt the user to delete the file from the old location.
48+
* `~/.swiftpm/config/collections.json` (collections file) was moved to `~/.swiftpm/configuration/collections.json`. SwiftPM 5.6 will automatically copy the file from the old location to the new one and emit a warning to prompt the user to delete the file from the old location.
49+
50+
2551
Swift 5.5
2652
-----------
2753
* [#3410]
@@ -44,6 +70,7 @@ Swift 5.5
4470

4571
Test targets can now link against executable targets as if they were libraries, so that they can test any data structures or algorithms in them. All the code in the executable except for the main entry point itself is available to the unit test. Separate executables are still linked, and can be tested as a subprocess in the same way as before. This feature is available to tests defined in packages that have a tools version of `5.5` or newer.
4672

73+
4774
Swift 5.4
4875
-----------
4976
* [#2937]
@@ -67,7 +94,6 @@ Swift 5.4
6794
The package manager now throws an error if a manifest file contains invalid UTF-8 byte sequences.
6895

6996

70-
7197
Swift 4.2
7298
---------
7399

@@ -108,6 +134,7 @@ Swift 4.2
108134
* [#1489]
109135
A simpler progress bar is now generated for "dumb" terminals.
110136

137+
111138
Swift 4.1
112139
---------
113140

@@ -130,6 +157,7 @@ Swift 4.0
130157
* `--specifier` option for `swift test` is now deprecated.
131158
Use `--filter` instead which supports regex.
132159

160+
133161
Swift 3.0
134162
---------
135163

@@ -153,11 +181,12 @@ Swift 3.0
153181

154182
* The `Package` initializer now requires the `name:` parameter.
155183

156-
[SE-0129]: https://github.com/apple/swift-evolution/blob/master/proposals/0129-package-manager-test-naming-conventions.md
157-
[SE-0135]: https://github.com/apple/swift-evolution/blob/master/proposals/0135-package-manager-support-for-differentiating-packages-by-swift-version.md
158-
[SE-0201]: https://github.com/apple/swift-evolution/blob/master/proposals/0201-package-manager-local-dependencies.md
159-
[SE-0208]: https://github.com/apple/swift-evolution/blob/master/proposals/0208-package-manager-system-library-targets.md
160-
[SE-0209]: https://github.com/apple/swift-evolution/blob/master/proposals/0209-package-manager-swift-lang-version-update.md
184+
[SE-0129]: https://github.com/apple/swift-evolution/blob/main/proposals/0129-package-manager-test-naming-conventions.md
185+
[SE-0135]: https://github.com/apple/swift-evolution/blob/main/proposals/0135-package-manager-support-for-differentiating-packages-by-swift-version.md
186+
[SE-0201]: https://github.com/apple/swift-evolution/blob/main/proposals/0201-package-manager-local-dependencies.md
187+
[SE-0208]: https://github.com/apple/swift-evolution/blob/main/proposals/0208-package-manager-system-library-targets.md
188+
[SE-0209]: https://github.com/apple/swift-evolution/blob/main/proposals/0209-package-manager-swift-lang-version-update.md
189+
[SE-0332]: https://github.com/apple/swift-evolution/blob/main/proposals/0332-swiftpm-command-plugins.md
161190

162191
[SR-5918]: https://bugs.swift.org/browse/SR-5918
163192
[SR-6978]: https://bugs.swift.org/browse/SR-6978
@@ -175,3 +204,8 @@ Swift 3.0
175204
[#3486]: https://github.com/apple/swift-package-manager/pull/3486
176205
[#3641]: https://github.com/apple/swift-package-manager/pull/3641
177206
[#3649]: https://github.com/apple/swift-package-manager/pull/3649
207+
[#3670]: https://github.com/apple/swift-package-manager/pull/3670
208+
[#3717]: https://github.com/apple/swift-package-manager/pull/3717
209+
[#3890]: https://github.com/apple/swift-package-manager/pull/3890
210+
[#3901]: https://github.com/apple/swift-package-manager/pull/3901
211+
[#3942]: https://github.com/apple/swift-package-manager/pull/3942

Fixtures/Miscellaneous/TestDiscovery/Async/Tests/AsyncTests/SwiftTests.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ class AsyncTests: XCTestCase {
77
func testAsync() async {
88
}
99

10+
func testAsyncThrows() async throws {
11+
}
12+
1013
@MainActor func testMainActor() async {
1114
XCTAssertTrue(Thread.isMainThread)
1215
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// swift-tools-version:4.2
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "Simple",
6+
targets: [
7+
.target(name: "Simple"),
8+
.testTarget(name: "SimpleTests", dependencies: ["Simple"]),
9+
]
10+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct Simple {
2+
func hello() {}
3+
4+
@available(*, deprecated, message: "use hello instead")
5+
func deprecatedHello() {}
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import XCTest
2+
@testable import Simple
3+
4+
class SimpleTests: XCTestCase {
5+
func testHello() {
6+
Simple().hello()
7+
}
8+
9+
@available(*, deprecated, message: "testing deprecated API")
10+
func testDeprecatedHello() {
11+
Simple().deprecatedHello()
12+
}
13+
}

Fixtures/Miscellaneous/TestDiscovery/Simple/Tests/SimpleTests/SwiftTests.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ class SimpleTests: XCTestCase {
99
func test_Example2() {
1010
}
1111

12-
func testExample3(arg: String) {
12+
func testThrowing() throws {
13+
}
14+
15+
func testWithArgs(arg: String) {
1316
}
1417

1518
func nontest() {

Sources/Basics/ByteString+Extensions.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ extension ByteString {
1616
/// Secure Hashing Algorithm 2 (SHA-2) hashing with a 256-bit digest, when available,
1717
/// falling back on a native implementation in Swift provided by TSCBasic.
1818
public var sha256Checksum: String {
19-
#if canImport(CryptoKit)
20-
if #available(macOS 10.15, *) {
21-
return CryptoKitSHA256().hash(self).hexadecimalRepresentation
22-
}
23-
#endif
24-
2519
return SHA256().hash(self).hexadecimalRepresentation
2620
}
2721
}

Sources/Basics/DispatchTimeInterval+Extensions.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift project authors
4+
Copyright (c) 2020-2022 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See http://swift.org/LICENSE.txt for license information
@@ -12,7 +12,7 @@ import Dispatch
1212
import struct Foundation.TimeInterval
1313

1414
extension DispatchTimeInterval {
15-
func timeInterval() -> TimeInterval? {
15+
public func timeInterval() -> TimeInterval? {
1616
switch self {
1717
case .seconds(let value):
1818
return Double(value)
@@ -27,7 +27,7 @@ extension DispatchTimeInterval {
2727
}
2828
}
2929

30-
func milliseconds() -> Int? {
30+
public func milliseconds() -> Int? {
3131
switch self {
3232
case .seconds(let value):
3333
return value.multipliedReportingOverflow(by: 1000).partialValue
@@ -42,7 +42,7 @@ extension DispatchTimeInterval {
4242
}
4343
}
4444

45-
func seconds() -> Int? {
45+
public func seconds() -> Int? {
4646
switch self {
4747
case .seconds(let value):
4848
return value

Sources/Basics/Sandbox.swift

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See http://swift.org/LICENSE.txt for license information
@@ -13,23 +13,38 @@ import TSCBasic
1313
import TSCUtility
1414

1515
public enum Sandbox {
16+
17+
/// Applies a sandbox invocation to the given command line (if the platform supports it),
18+
/// and returns the modified command line. On platforms that don't support sandboxing, the
19+
/// command line is returned unmodified.
20+
///
21+
/// - Parameters:
22+
/// - command: The command line to sandbox (including executable as first argument)
23+
/// - strictness: The basic strictness level of the standbox.
24+
/// - writableDirectories: Paths under which writing should be allowed, even if they would otherwise be read-only based on the strictness or paths in `readOnlyDirectories`.
25+
/// - readOnlyDirectories: Paths under which writing should be denied, even if they would have otherwise been allowed by the rules implied by the strictness level.
1626
public static func apply(
1727
command: [String],
28+
strictness: Strictness = .default,
1829
writableDirectories: [AbsolutePath] = [],
19-
strictness: Strictness = .default
30+
readOnlyDirectories: [AbsolutePath] = []
2031
) -> [String] {
2132
#if os(macOS)
22-
let profile = macOSSandboxProfile(writableDirectories: writableDirectories, strictness: strictness)
33+
let profile = macOSSandboxProfile(strictness: strictness, writableDirectories: writableDirectories, readOnlyDirectories: readOnlyDirectories)
2334
return ["/usr/bin/sandbox-exec", "-p", profile] + command
2435
#else
2536
// rdar://40235432, rdar://75636874 tracks implementing sandboxes for other platforms.
2637
return command
2738
#endif
2839
}
2940

41+
/// Basic strictness level of a sandbox applied to a command line.
3042
public enum Strictness: Equatable {
43+
/// Blocks network access and all file system modifications.
3144
case `default`
45+
/// More lenient restrictions than the default, for compatibility with SwiftPM manifests using a tools version older than 5.3.
3246
case manifest_pre_53 // backwards compatibility for manifests
47+
/// Like `default`, but also makes temporary-files directories (such as `/tmp`) on the platform writable.
3348
case writableTemporaryDirectory
3449
}
3550
}
@@ -38,8 +53,9 @@ public enum Sandbox {
3853

3954
#if os(macOS)
4055
fileprivate func macOSSandboxProfile(
56+
strictness: Sandbox.Strictness,
4157
writableDirectories: [AbsolutePath],
42-
strictness: Sandbox.Strictness
58+
readOnlyDirectories: [AbsolutePath]
4359
) -> String {
4460
var contents = "(version 1)\n"
4561

@@ -63,9 +79,8 @@ fileprivate func macOSSandboxProfile(
6379
}
6480

6581
// Allow writing only to certain directories.
66-
var writableDirectoriesExpression = writableDirectories.map {
67-
"(subpath \(resolveSymlinks($0).quotedAsSubpathForSandboxProfile))"
68-
}
82+
var writableDirectoriesExpression: [String] = []
83+
6984
// The following accesses are only needed when interpreting the manifest (versus running a compiled version).
7085
if strictness == .manifest_pre_53 {
7186
writableDirectoriesExpression += Platform.threadSafeDarwinCacheDirectories.get().map {
@@ -80,6 +95,7 @@ fileprivate func macOSSandboxProfile(
8095
}
8196
}
8297

98+
// Emit rules for paths under which writing is allowed. Some of these expressions may be regular expressions and others literal subpaths.
8399
if writableDirectoriesExpression.count > 0 {
84100
contents += "(allow file-write*\n"
85101
for expression in writableDirectoriesExpression {
@@ -88,6 +104,24 @@ fileprivate func macOSSandboxProfile(
88104
contents += ")\n"
89105
}
90106

107+
// Emit rules for paths under which writing should be disallowed, even if they would be covered by a previous rule to allow writing to them. A classic case is a package which is located under the temporary directory, which should be read-only even though the temporary directory as a whole is writable.
108+
if readOnlyDirectories.count > 0 {
109+
contents += "(deny file-write*\n"
110+
for path in readOnlyDirectories {
111+
contents += " (subpath \(resolveSymlinks(path).quotedAsSubpathForSandboxProfile))\n"
112+
}
113+
contents += ")\n"
114+
}
115+
116+
// Emit rules for paths under which writing is allowed, even if they are descendants directories that are otherwise read-only.
117+
if writableDirectories.count > 0 {
118+
contents += "(allow file-write*\n"
119+
for path in writableDirectories {
120+
contents += " (subpath \(resolveSymlinks(path).quotedAsSubpathForSandboxProfile))\n"
121+
}
122+
contents += ")\n"
123+
}
124+
91125
return contents
92126
}
93127

Sources/Basics/VirtualFileSystem.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ public class VirtualFileSystem: FileSystem {
177177

178178
public var cachesDirectory: AbsolutePath? = nil
179179

180+
public var tempDirectory = AbsolutePath("/")
181+
180182
public func createSymbolicLink(_ path: AbsolutePath, pointingAt destination: AbsolutePath, relative: Bool) throws {
181183
throw Errors.readOnlyFileSystem
182184
}

Sources/Build/BuildOperation.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,36 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
209209
let prebuildCommandResults = try graph.reachableTargets.reduce(into: [:], { partial, target in
210210
partial[target] = try buildToolPluginInvocationResults[target].map { try self.runPrebuildCommands(for: $0) }
211211
})
212+
213+
// Emit warnings about any unhandled files in authored packages. We do this after applying build tool plugins, once we know what files they handled.
214+
for package in graph.rootPackages where package.manifest.toolsVersion >= .v5_3 {
215+
for target in package.targets {
216+
// Get the set of unhandled files in targets.
217+
var unhandledFiles = Set(target.underlyingTarget.others)
218+
if unhandledFiles.isEmpty { continue }
219+
220+
// Subtract out any that were inputs to any commands generated by plugins.
221+
if let result = buildToolPluginInvocationResults[target] {
222+
let handledFiles = result.flatMap{ $0.buildCommands.flatMap{ $0.inputFiles } }
223+
unhandledFiles.subtract(handledFiles)
224+
}
225+
if unhandledFiles.isEmpty { continue }
226+
227+
// Emit a diagnostic if any remain. This is kept the same as the previous message for now, but this could be improved.
228+
let diagnosticsEmitter = self.observabilityScope.makeDiagnosticsEmitter {
229+
var metadata = ObservabilityMetadata()
230+
metadata.packageIdentity = package.identity
231+
metadata.packageKind = package.manifest.packageKind
232+
metadata.targetName = target.name
233+
return metadata
234+
}
235+
var warning = "found \(unhandledFiles.count) file(s) which are unhandled; explicitly declare them as resources or exclude from the target\n"
236+
for file in unhandledFiles {
237+
warning += " " + file.pathString + "\n"
238+
}
239+
diagnosticsEmitter.emit(warning: warning)
240+
}
241+
}
212242

213243
// Create the build plan based, on the graph and any information from plugins.
214244
let plan = try BuildPlan(
@@ -314,7 +344,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
314344
// TODO: We need to also use any working directory, but that support isn't yet available on all platforms at a lower level.
315345
var commandLine = [command.configuration.executable.pathString] + command.configuration.arguments
316346
if !self.disableSandboxForPluginCommands {
317-
commandLine = Sandbox.apply(command: commandLine, writableDirectories: [pluginResult.pluginOutputDirectory], strictness: .writableTemporaryDirectory)
347+
commandLine = Sandbox.apply(command: commandLine, strictness: .writableTemporaryDirectory, writableDirectories: [pluginResult.pluginOutputDirectory])
318348
}
319349
let processResult = try Process.popen(arguments: commandLine, environment: command.configuration.environment)
320350
let output = try processResult.utf8Output() + processResult.utf8stderrOutput()

0 commit comments

Comments
 (0)