Skip to content

Commit 21104ca

Browse files
authored
SwiftPM6: Fix to skip locking package build directory (#38)
* fix: skip locking package build directory * fixed to get swift version before concurrent parsing
1 parent edd6e7f commit 21104ca

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

Sources/DependencyCalculator/DependencyGraph.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Foundation
66
import Git
77
import PathKit
88
import SelectiveTestLogger
9+
import SelectiveTestShell
910
import Workspace
1011
import XcodeProj
1112

@@ -200,8 +201,14 @@ extension WorkspaceInfo {
200201
} == nil
201202
}
202203

204+
// SwiftPM6 locks build directory up when parsing multiple packages concurrently
205+
let isSwiftVersion6Plus = try isSwiftVersion6Plus()
206+
203207
return Array(allPackages).concurrentMap { path in
204-
try? PackageTargetMetadata.parse(at: path.parent())
208+
try? PackageTargetMetadata.parse(
209+
at: path.parent(),
210+
addingIgnoreLockOption: isSwiftVersion6Plus
211+
)
205212
}.compactMap { $0 }.reduce([PackageTargetMetadata]()) { partialResult, new in
206213
var result = partialResult
207214
result.append(contentsOf: new)
@@ -347,4 +354,22 @@ extension WorkspaceInfo {
347354
dependencyStructure: DependencyGraph(dependsOn: dependsOn),
348355
candidateTestPlan: candidateTestPlan)
349356
}
357+
358+
private static func isSwiftVersion6Plus() throws -> Bool {
359+
guard let regex = try? NSRegularExpression(pattern: #"Apple Swift version (\d+)"#) else {
360+
return false
361+
}
362+
363+
let versionString = try Shell.execOrFail("swift --version")
364+
let range = NSRange(versionString.startIndex..<versionString.endIndex, in: versionString)
365+
if let match = regex.firstMatch(in: versionString, options: [], range: range),
366+
let majorVersionRange = Range(match.range(at: 1), in: versionString),
367+
let majorVersion = Int(versionString[majorVersionRange]),
368+
majorVersion > 5
369+
{
370+
return true
371+
} else {
372+
return false
373+
}
374+
}
350375
}

Sources/DependencyCalculator/PackageMetadata.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,17 @@ struct PackageTargetMetadata {
1616
let testTarget: Bool
1717

1818
// TODO: Split in several methods
19-
static func parse(at path: Path) throws -> [PackageTargetMetadata] {
20-
// NB: Flag `--disable-sandbox` is required to allow running SPM from an SPM plugin
21-
let manifest = try Shell.execOrFail("cd \(path) && swift package dump-package --disable-sandbox").trimmingCharacters(in: .newlines)
19+
static func parse(at path: Path, addingIgnoreLockOption: Bool = false) throws -> [PackageTargetMetadata] {
20+
// NB:
21+
// - Flag `--disable-sandbox` is required to allow running SPM from an SPM plugin
22+
// - Flag `--ignore-lock` is required to avoid locking the package build directory when parsing is done concurrently (Swift 6).
23+
var flags = ["--disable-sandbox"]
24+
if addingIgnoreLockOption {
25+
flags.append("--ignore-lock")
26+
}
27+
28+
let manifest = try Shell.execOrFail("cd \(path) && swift package dump-package \(flags.joined(separator: " "))")
29+
.trimmingCharacters(in: .newlines)
2230
guard let manifestData = manifest.data(using: .utf8),
2331
let manifestJson = try JSONSerialization.jsonObject(with: manifestData, options: []) as? [String: Any],
2432
let targets = manifestJson["targets"] as? [[String: Any]]

0 commit comments

Comments
 (0)