From 094be230697a4e0f62d01ae32fecf9c242568f21 Mon Sep 17 00:00:00 2001 From: fxwx23 Date: Wed, 30 Oct 2024 13:55:40 +0900 Subject: [PATCH 1/2] fix: skip locking package build directory --- .../PackageMetadata.swift | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Sources/DependencyCalculator/PackageMetadata.swift b/Sources/DependencyCalculator/PackageMetadata.swift index 61e352b..30c9516 100644 --- a/Sources/DependencyCalculator/PackageMetadata.swift +++ b/Sources/DependencyCalculator/PackageMetadata.swift @@ -17,8 +17,16 @@ struct PackageTargetMetadata { // TODO: Split in several methods static func parse(at path: Path) throws -> [PackageTargetMetadata] { - // NB: Flag `--disable-sandbox` is required to allow running SPM from an SPM plugin - let manifest = try Shell.execOrFail("cd \(path) && swift package dump-package --disable-sandbox").trimmingCharacters(in: .newlines) + // NB: + // - Flag `--disable-sandbox` is required to allow running SPM from an SPM plugin + // - Flag `--ignore-lock` is required to avoid locking the package build directory when exectuting from SPM plugin (Swift 6). + var flags = ["--disable-sandbox"] + if try isSwiftVersion6Plus() { + flags.append("--ignore-lock") + } + + let manifest = try Shell.execOrFail("cd \(path) && swift package dump-package \(flags.joined(separator: " "))") + .trimmingCharacters(in: .newlines) guard let manifestData = manifest.data(using: .utf8), let manifestJson = try JSONSerialization.jsonObject(with: manifestData, options: []) as? [String: Any], let targets = manifestJson["targets"] as? [[String: Any]] @@ -127,4 +135,24 @@ struct PackageTargetMetadata { func targetIdentity() -> TargetIdentity { return TargetIdentity.package(path: path, targetName: name, testTarget: testTarget) } + + private static func isSwiftVersion6Plus() throws -> Bool { + let versionString = try Shell.execOrFail("swift --version") + let pattern = #"Apple Swift version (\d+)"# + + guard let regex = try? NSRegularExpression(pattern: pattern) else { + return false + } + + let range = NSRange(versionString.startIndex.. 5 + { + return true + } else { + return false + } + } } From 18fe3eb7278d3dbd48d3af778fab3ed72beed1a1 Mon Sep 17 00:00:00 2001 From: fxwx23 Date: Tue, 26 Nov 2024 11:28:26 +0900 Subject: [PATCH 2/2] fixed to get swift version before concurrent parsing --- .../DependencyGraph.swift | 27 ++++++++++++++++++- .../PackageMetadata.swift | 26 +++--------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Sources/DependencyCalculator/DependencyGraph.swift b/Sources/DependencyCalculator/DependencyGraph.swift index 6ef3a78..5eb020e 100644 --- a/Sources/DependencyCalculator/DependencyGraph.swift +++ b/Sources/DependencyCalculator/DependencyGraph.swift @@ -6,6 +6,7 @@ import Foundation import Git import PathKit import SelectiveTestLogger +import SelectiveTestShell import Workspace import XcodeProj @@ -200,8 +201,14 @@ extension WorkspaceInfo { } == nil } + // SwiftPM6 locks build directory up when parsing multiple packages concurrently + let isSwiftVersion6Plus = try isSwiftVersion6Plus() + return Array(allPackages).concurrentMap { path in - try? PackageTargetMetadata.parse(at: path.parent()) + try? PackageTargetMetadata.parse( + at: path.parent(), + addingIgnoreLockOption: isSwiftVersion6Plus + ) }.compactMap { $0 }.reduce([PackageTargetMetadata]()) { partialResult, new in var result = partialResult result.append(contentsOf: new) @@ -347,4 +354,22 @@ extension WorkspaceInfo { dependencyStructure: DependencyGraph(dependsOn: dependsOn), candidateTestPlan: candidateTestPlan) } + + private static func isSwiftVersion6Plus() throws -> Bool { + guard let regex = try? NSRegularExpression(pattern: #"Apple Swift version (\d+)"#) else { + return false + } + + let versionString = try Shell.execOrFail("swift --version") + let range = NSRange(versionString.startIndex.. 5 + { + return true + } else { + return false + } + } } diff --git a/Sources/DependencyCalculator/PackageMetadata.swift b/Sources/DependencyCalculator/PackageMetadata.swift index 30c9516..a6c667c 100644 --- a/Sources/DependencyCalculator/PackageMetadata.swift +++ b/Sources/DependencyCalculator/PackageMetadata.swift @@ -16,12 +16,12 @@ struct PackageTargetMetadata { let testTarget: Bool // TODO: Split in several methods - static func parse(at path: Path) throws -> [PackageTargetMetadata] { + static func parse(at path: Path, addingIgnoreLockOption: Bool = false) throws -> [PackageTargetMetadata] { // NB: // - Flag `--disable-sandbox` is required to allow running SPM from an SPM plugin - // - Flag `--ignore-lock` is required to avoid locking the package build directory when exectuting from SPM plugin (Swift 6). + // - Flag `--ignore-lock` is required to avoid locking the package build directory when parsing is done concurrently (Swift 6). var flags = ["--disable-sandbox"] - if try isSwiftVersion6Plus() { + if addingIgnoreLockOption { flags.append("--ignore-lock") } @@ -135,24 +135,4 @@ struct PackageTargetMetadata { func targetIdentity() -> TargetIdentity { return TargetIdentity.package(path: path, targetName: name, testTarget: testTarget) } - - private static func isSwiftVersion6Plus() throws -> Bool { - let versionString = try Shell.execOrFail("swift --version") - let pattern = #"Apple Swift version (\d+)"# - - guard let regex = try? NSRegularExpression(pattern: pattern) else { - return false - } - - let range = NSRange(versionString.startIndex.. 5 - { - return true - } else { - return false - } - } }