Skip to content

Commit 5a48a53

Browse files
authored
Merge branch 'main' into revert-3677-revert-collections-again
2 parents ae005fb + dbe7b15 commit 5a48a53

Some content is hidden

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

43 files changed

+691
-375
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ SwiftPM is typically built with a pre-existing version of SwiftPM present on the
4444

4545
1. Install Xcode from [https://developer.apple.com/xcode](https://developer.apple.com/xcode) (including betas!).
4646
2. Verify the expected version of Xcode was installed.
47-
3. Open SwiftPM's `Package.swift` manifest with Xcode, and use Xcode to edit the code, build, and run the tests.
47+
3. Open SwiftPM's `Package.swift` manifest with Xcode.
48+
4. Use Xcode to inspect, edit, and build the code.
49+
5. Select the `SwiftPM-Package` scheme to run the tests from Xcode.
4850

4951
### Using the Command Line
5052

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// swift-tools-version:5.5
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "Foo",
6+
dependencies: [
7+
.package(url: "https://localhost/foo/bar", branch: "#!~")
8+
],
9+
targets: []
10+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// swift-tools-version:5.5
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "Foo",
6+
dependencies: [
7+
.package(url: "https://localhost/foo/bar", revision: "#!~")
8+
],
9+
targets: []
10+
)

Package.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ let package = Package(
192192
name: "PackageLoading",
193193
dependencies: [
194194
"Basics",
195-
"PackageModel",
196-
"SourceControl"
195+
"PackageModel"
197196
],
198197
exclude: ["CMakeLists.txt", "README.md"]
199198
),
@@ -573,8 +572,8 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
573572
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "1.0.1")),
574573
.package(url: "https://github.com/apple/swift-driver.git", .branch(relatedDependenciesBranch)),
575574
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMinor(from: minimumCryptoVersion)),
576-
.package(url: "https://github.com/apple/swift-system.git", .upToNextMinor(from: "1.0.0")),
577-
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMinor(from: "1.0.1")),
575+
.package(url: "https://github.com/apple/swift-system.git", .upToNextMinor(from: "1.1.1")),
576+
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMinor(from: "1.0.1"))
578577
]
579578
} else {
580579
package.dependencies += [

Sources/Basics/FileSystem+Extensions.swift

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ extension FileSystem {
2121
public var dotSwiftPM: AbsolutePath {
2222
self.homeDirectory.appending(component: ".swiftpm")
2323
}
24-
25-
/// SwiftPM security directory
26-
public var swiftPMSecurityDirectory: AbsolutePath {
27-
self.dotSwiftPM.appending(component: "security")
24+
25+
fileprivate var idiomaticSwiftPMDirectory: AbsolutePath? {
26+
return FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first.flatMap { AbsolutePath($0.path) }?.appending(component: "org.swift.swiftpm")
2827
}
2928
}
3029

@@ -62,59 +61,144 @@ extension FileSystem {
6261
try self.createDirectory(self.dotSwiftPM, recursive: true)
6362
}
6463
// Create ~/.swiftpm/cache symlink if necessary
65-
if !self.exists(self.dotSwiftPMCachesDirectory, followSymlink: false) {
66-
try self.createSymbolicLink(dotSwiftPMCachesDirectory, pointingAt: idiomaticCacheDirectory, relative: false)
64+
// locking ~/.swiftpm to protect from concurrent access
65+
try self.withLock(on: self.dotSwiftPM, type: .exclusive) {
66+
if !self.exists(self.dotSwiftPMCachesDirectory, followSymlink: false) {
67+
try self.createSymbolicLink(dotSwiftPMCachesDirectory, pointingAt: idiomaticCacheDirectory, relative: false)
68+
}
6769
}
6870
return idiomaticCacheDirectory
6971
}
7072
}
7173

72-
// MARK: - config
74+
// MARK: - configuration
7375

7476
extension FileSystem {
75-
private var idiomaticUserConfigDirectory: AbsolutePath? {
76-
return FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first.flatMap { AbsolutePath($0.path) }
77+
/// SwiftPM config directory under user's config directory (if exists)
78+
public var swiftPMConfigurationDirectory: AbsolutePath {
79+
if let path = self.idiomaticSwiftPMDirectory {
80+
return path.appending(component: "configuration")
81+
} else {
82+
return self.dotSwiftPMConfigurationDirectory
83+
}
7784
}
7885

79-
/// SwiftPM config directory under user's config directory (if exists)
80-
public var swiftPMConfigDirectory: AbsolutePath {
81-
if let path = self.idiomaticUserConfigDirectory {
82-
return path.appending(component: "org.swift.swiftpm")
86+
fileprivate var dotSwiftPMConfigurationDirectory: AbsolutePath {
87+
return self.dotSwiftPM.appending(component: "configuration")
88+
}
89+
}
90+
91+
extension FileSystem {
92+
public func getOrCreateSwiftPMConfigurationDirectory(observabilityScope: ObservabilityScope?) throws -> AbsolutePath {
93+
let idiomaticConfigurationDirectory = self.swiftPMConfigurationDirectory
94+
95+
// temporary 5.6, remove on next version: transition from previous configuration location
96+
if !self.exists(idiomaticConfigurationDirectory) {
97+
try self.createDirectory(idiomaticConfigurationDirectory, recursive: true)
98+
}
99+
100+
// in the case where ~/.swiftpm/configuration is not the idiomatic location (eg on macOS where its /Users/<user>/Library/org.swift.swiftpm/configuration)
101+
if idiomaticConfigurationDirectory != self.dotSwiftPMConfigurationDirectory {
102+
// copy the configuration files from old location (eg /Users/<user>/Library/org.swift.swiftpm) to new one (eg /Users/<user>/Library/org.swift.swiftpm/configuration)
103+
// but leave them there for backwards compatibility (eg older xcode)
104+
let oldConfigDirectory = idiomaticConfigurationDirectory.parentDirectory
105+
if self.exists(oldConfigDirectory, followSymlink: false) && self.isDirectory(oldConfigDirectory) {
106+
let configurationFiles = try self.getDirectoryContents(oldConfigDirectory)
107+
.map{ oldConfigDirectory.appending(component: $0) }
108+
.filter{ self.isFile($0) && !self.isSymlink($0) && $0.extension != "lock"}
109+
for file in configurationFiles {
110+
let destination = idiomaticConfigurationDirectory.appending(component: file.basename)
111+
observabilityScope?.emit(warning: "Usage of \(file) has been deprecated. Please delete it and use the new \(destination) instead.")
112+
if !self.exists(destination) {
113+
try self.copy(from: file, to: destination)
114+
}
115+
}
116+
}
117+
// in the case where ~/.swiftpm/configuration is the idiomatic location (eg on Linux)
118+
} else {
119+
// copy the configuration files from old location (~/.swiftpm/config) to new one (~/.swiftpm/configuration)
120+
// but leave them there for backwards compatibility (eg older toolchain)
121+
let oldConfigDirectory = self.dotSwiftPM.appending(component: "config")
122+
if self.exists(oldConfigDirectory, followSymlink: false) && self.isDirectory(oldConfigDirectory) {
123+
let configurationFiles = try self.getDirectoryContents(oldConfigDirectory)
124+
.map{ oldConfigDirectory.appending(component: $0) }
125+
.filter{ self.isFile($0) && !self.isSymlink($0) && $0.extension != "lock"}
126+
for file in configurationFiles {
127+
let destination = idiomaticConfigurationDirectory.appending(component: file.basename)
128+
observabilityScope?.emit(warning: "Usage of \(file) has been deprecated. Please delete it and use the new \(destination) instead.")
129+
if !self.exists(destination) {
130+
try self.copy(from: file, to: destination)
131+
}
132+
}
133+
}
134+
}
135+
// ~temporary 5.6 migration
136+
137+
// Create idiomatic if necessary
138+
if !self.exists(idiomaticConfigurationDirectory) {
139+
try self.createDirectory(idiomaticConfigurationDirectory, recursive: true)
140+
}
141+
// Create ~/.swiftpm if necessary
142+
if !self.exists(self.dotSwiftPM) {
143+
try self.createDirectory(self.dotSwiftPM, recursive: true)
144+
}
145+
// Create ~/.swiftpm/configuration symlink if necessary
146+
// locking ~/.swiftpm to protect from concurrent access
147+
try self.withLock(on: self.dotSwiftPM, type: .exclusive) {
148+
if !self.exists(self.dotSwiftPMConfigurationDirectory, followSymlink: false) {
149+
try self.createSymbolicLink(dotSwiftPMConfigurationDirectory, pointingAt: idiomaticConfigurationDirectory, relative: false)
150+
}
151+
}
152+
153+
return idiomaticConfigurationDirectory
154+
}
155+
}
156+
157+
// MARK: - security
158+
159+
extension FileSystem {
160+
/// SwiftPM security directory under user's security directory (if exists)
161+
public var swiftPMSecurityDirectory: AbsolutePath {
162+
if let path = self.idiomaticSwiftPMDirectory {
163+
return path.appending(component: "security")
83164
} else {
84-
return self.dotSwiftPMConfigDirectory
165+
return self.dotSwiftPMSecurityDirectory
85166
}
86167
}
87168

88-
fileprivate var dotSwiftPMConfigDirectory: AbsolutePath {
89-
return self.dotSwiftPM.appending(component: "config")
169+
fileprivate var dotSwiftPMSecurityDirectory: AbsolutePath {
170+
return self.dotSwiftPM.appending(component: "security")
90171
}
91172
}
92173

93174
extension FileSystem {
94-
public func getOrCreateSwiftPMConfigDirectory() throws -> AbsolutePath {
95-
let idiomaticConfigDirectory = self.swiftPMConfigDirectory
175+
public func getOrCreateSwiftPMSecurityDirectory() throws -> AbsolutePath {
176+
let idiomaticSecurityDirectory = self.swiftPMSecurityDirectory
96177

97-
// temporary 5.5, remove on next version: transition from ~/.swiftpm/config to idiomatic location + symbolic link
98-
if idiomaticConfigDirectory != self.dotSwiftPMConfigDirectory &&
99-
self.exists(self.dotSwiftPMConfigDirectory) && self.isDirectory(self.dotSwiftPMConfigDirectory) &&
100-
!self.exists(idiomaticConfigDirectory) {
101-
print("transitioning \(self.dotSwiftPMConfigDirectory) to \(idiomaticConfigDirectory)")
102-
try self.move(from: self.dotSwiftPMConfigDirectory, to: idiomaticConfigDirectory)
178+
// temporary 5.6, remove on next version: transition from ~/.swiftpm/security to idiomatic location + symbolic link
179+
if idiomaticSecurityDirectory != self.dotSwiftPMSecurityDirectory &&
180+
self.exists(self.dotSwiftPMSecurityDirectory) &&
181+
self.isDirectory(self.dotSwiftPMSecurityDirectory) {
182+
try self.removeFileTree(self.dotSwiftPMSecurityDirectory)
103183
}
184+
// ~temporary 5.6 migration
104185

105186
// Create idiomatic if necessary
106-
if !self.exists(idiomaticConfigDirectory) {
107-
try self.createDirectory(idiomaticConfigDirectory, recursive: true)
187+
if !self.exists(idiomaticSecurityDirectory) {
188+
try self.createDirectory(idiomaticSecurityDirectory, recursive: true)
108189
}
109190
// Create ~/.swiftpm if necessary
110191
if !self.exists(self.dotSwiftPM) {
111192
try self.createDirectory(self.dotSwiftPM, recursive: true)
112193
}
113-
// Create ~/.swiftpm/config symlink if necessary
114-
if !self.exists(self.dotSwiftPMConfigDirectory, followSymlink: false) {
115-
try self.createSymbolicLink(dotSwiftPMConfigDirectory, pointingAt: idiomaticConfigDirectory, relative: false)
194+
// Create ~/.swiftpm/security symlink if necessary
195+
// locking ~/.swiftpm to protect from concurrent access
196+
try self.withLock(on: self.dotSwiftPM, type: .exclusive) {
197+
if !self.exists(self.dotSwiftPMSecurityDirectory, followSymlink: false) {
198+
try self.createSymbolicLink(dotSwiftPMSecurityDirectory, pointingAt: idiomaticSecurityDirectory, relative: false)
199+
}
116200
}
117-
return idiomaticConfigDirectory
201+
return idiomaticSecurityDirectory
118202
}
119203
}
120204

Sources/Commands/Options.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ public struct SwiftToolOptions: ParsableArguments {
149149
@Option(help: "Specify the shared configuration directory")
150150
var configPath: AbsolutePath?
151151

152+
@Option(help: "Specify the shared security directory")
153+
var securityPath: AbsolutePath?
154+
152155
/// Disables repository caching.
153156
@Flag(name: .customLong("repository-cache"), inversion: .prefixedEnableDisable, help: "Use a shared cache when fetching repositories")
154157
var useRepositoriesCache: Bool = true

Sources/Commands/SwiftPackageTool.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -882,10 +882,6 @@ extension SwiftPackageTool {
882882
help: "Target(s) to which the plugin command should be applied")
883883
var targetNames: [String] = []
884884

885-
@Option(name: .customLong("output"),
886-
help: "Optional output directory passed to the command plugin")
887-
var outputPath: String?
888-
889885
@Flag(name: .customLong("list"),
890886
help: "List the available plugin commands")
891887
var listCommands: Bool = false
@@ -941,9 +937,6 @@ extension SwiftPackageTool {
941937
// If no targets were specified, default to all the applicable ones in the package.
942938
let targetNames = targetNames.isEmpty ? package.targets.filter(\.isEligibleForPluginCommand).map(\.name) : targetNames
943939

944-
// If the user specified an output path, we validate it.
945-
let outputPath = try self.outputPath.map{ try AbsolutePath(validating: $0) }
946-
947940
// Find the targets (if any) specified by the user. We expect them in the root package.
948941
var targets: [String: ResolvedTarget] = [:]
949942
for target in package.targets where targetNames.contains(target.name) {
@@ -1019,8 +1012,7 @@ extension SwiftPackageTool {
10191012
let _ = try tsc_await { plugin.invoke(
10201013
action: .performCommand(
10211014
targets: Array(targets.values),
1022-
arguments: Array(pluginCommand.dropFirst()),
1023-
outputPath: outputPath),
1015+
arguments: Array(pluginCommand.dropFirst())),
10241016
package: package,
10251017
buildEnvironment: buildEnvironment,
10261018
scriptRunner: pluginScriptRunner,

0 commit comments

Comments
 (0)