Skip to content

Commit c30c2cc

Browse files
committed
refactor workspace initializers
motivation: nicer API to work with changes: * deprecate previous initializer * introduce new initializer with minimal signatures, and clearly defined argument names and API docs * make DependencyMirrors thread safe * adjust call sites
1 parent 531334f commit c30c2cc

File tree

10 files changed

+378
-267
lines changed

10 files changed

+378
-267
lines changed

Sources/Commands/APIDigester.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ struct APIDigesterBaselineDumper {
3434
let inputBuildParameters: BuildParameters
3535

3636
/// The manifest loader.
37-
let manifestLoader: ManifestLoaderProtocol
37+
//let manifestLoader: ManifestLoaderProtocol
3838

3939
/// The repository manager.
40-
let repositoryManager: RepositoryManager
40+
//let repositoryManager: RepositoryManager
4141

4242
/// The API digester tool.
4343
let apiDigesterTool: SwiftAPIDigester
@@ -49,16 +49,16 @@ struct APIDigesterBaselineDumper {
4949
baselineRevision: Revision,
5050
packageRoot: AbsolutePath,
5151
buildParameters: BuildParameters,
52-
manifestLoader: ManifestLoaderProtocol,
53-
repositoryManager: RepositoryManager,
52+
//manifestLoader: ManifestLoaderProtocol,
53+
//repositoryManager: RepositoryManager,
5454
apiDigesterTool: SwiftAPIDigester,
5555
diags: DiagnosticsEngine
5656
) {
5757
self.baselineRevision = baselineRevision
5858
self.packageRoot = packageRoot
5959
self.inputBuildParameters = buildParameters
60-
self.manifestLoader = manifestLoader
61-
self.repositoryManager = repositoryManager
60+
//self.manifestLoader = manifestLoader
61+
//self.repositoryManager = repositoryManager
6262
self.apiDigesterTool = apiDigesterTool
6363
self.diags = diags
6464
}
@@ -93,8 +93,9 @@ struct APIDigesterBaselineDumper {
9393
}
9494

9595
// Clone the current package in a sandbox and checkout the baseline revision.
96+
let repositoryProvider = GitRepositoryProvider()
9697
let specifier = RepositorySpecifier(url: baselinePackageRoot.pathString)
97-
let workingCopy = try repositoryManager.provider.createWorkingCopy(
98+
let workingCopy = try repositoryProvider.createWorkingCopy(
9899
repository: specifier,
99100
sourcePath: packageRoot,
100101
at: baselinePackageRoot,
@@ -105,9 +106,9 @@ struct APIDigesterBaselineDumper {
105106

106107
// Create the workspace for this package.
107108
let workspace = try Workspace(
108-
forRootPackage: baselinePackageRoot,
109-
manifestLoader: manifestLoader,
110-
repositoryManager: repositoryManager
109+
forRootPackage: baselinePackageRoot//,
110+
//manifestLoader: manifestLoader,
111+
//repositoryManager: repositoryManager
111112
)
112113

113114
let graph = try workspace.loadPackageGraph(

Sources/Commands/SwiftPackageTool.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,13 @@ extension SwiftPackageTool {
364364
try buildOp.build()
365365

366366
// Dump JSON for the baseline package.
367-
let workspace = try swiftTool.getActiveWorkspace()
367+
//let workspace = try swiftTool.getActiveWorkspace()
368368
let baselineDumper = try APIDigesterBaselineDumper(
369369
baselineRevision: baselineRevision,
370370
packageRoot: swiftTool.getPackageRoot(),
371371
buildParameters: buildOp.buildParameters,
372-
manifestLoader: workspace.manifestLoader,
373-
repositoryManager: workspace.repositoryManager,
372+
//manifestLoader: workspace.manifestLoader,
373+
//repositoryManager: workspace.repositoryManager,
374374
apiDigesterTool: apiDigesterTool,
375375
diags: swiftTool.diagnostics
376376
)
@@ -886,7 +886,7 @@ extension SwiftPackageTool.Config {
886886
var mirrorURL: String
887887

888888
func run(_ swiftTool: SwiftTool) throws {
889-
let config = try swiftTool.getSwiftPMConfig()
889+
let config = try swiftTool.getMirrorsConfig()
890890

891891
if packageURL != nil {
892892
swiftTool.diagnostics.emit(
@@ -920,7 +920,7 @@ extension SwiftPackageTool.Config {
920920
var mirrorURL: String?
921921

922922
func run(_ swiftTool: SwiftTool) throws {
923-
let config = try swiftTool.getSwiftPMConfig()
923+
let config = try swiftTool.getMirrorsConfig()
924924

925925
if packageURL != nil {
926926
swiftTool.diagnostics.emit(
@@ -951,7 +951,7 @@ extension SwiftPackageTool.Config {
951951
var originalURL: String?
952952

953953
func run(_ swiftTool: SwiftTool) throws {
954-
let config = try swiftTool.getSwiftPMConfig()
954+
let config = try swiftTool.getMirrorsConfig()
955955

956956
if packageURL != nil {
957957
swiftTool.diagnostics.emit(

Sources/Commands/SwiftTool.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,14 @@ public class SwiftTool {
459459
return try getPackageRoot().appending(component: "Packages")
460460
}
461461

462-
func resolvedFilePath() throws -> AbsolutePath {
462+
func resolvedVersionsFilePath() throws -> AbsolutePath {
463463
if let multiRootPackageDataFile = options.multirootPackageDataFile {
464464
return multiRootPackageDataFile.appending(components: "xcshareddata", "swiftpm", "Package.resolved")
465465
}
466466
return try getPackageRoot().appending(component: "Package.resolved")
467467
}
468468

469-
func configFilePath() throws -> AbsolutePath {
469+
func mirrorsConfigFilePath() throws -> AbsolutePath {
470470
// Look for the override in the environment.
471471
if let envPath = ProcessEnv.vars["SWIFTPM_MIRROR_CONFIG"] {
472472
return try AbsolutePath(validating: envPath)
@@ -479,15 +479,15 @@ public class SwiftTool {
479479
return try getPackageRoot().appending(components: ".swiftpm", "config")
480480
}
481481

482-
func getSwiftPMConfig() throws -> Workspace.Configuration {
483-
return try _swiftpmConfig.get()
482+
func getMirrorsConfig() throws -> Workspace.Configuration {
483+
return try _mirrorsConfig.get()
484484
}
485485

486-
private lazy var _swiftpmConfig: Result<Workspace.Configuration, Swift.Error> = {
487-
return Result(catching: { try Workspace.Configuration(path: try configFilePath()) })
486+
private lazy var _mirrorsConfig: Result<Workspace.Configuration, Swift.Error> = {
487+
return Result(catching: { try Workspace.Configuration(path: try mirrorsConfigFilePath(), fileSystem: localFileSystem) })
488488
}()
489-
490-
func resolvedNetrcFilePath() throws -> AbsolutePath? {
489+
490+
func netrcFilePath() throws -> AbsolutePath? {
491491
guard options.netrc ||
492492
options.netrcFilePath != nil ||
493493
options.netrcOptional else { return nil }
@@ -551,21 +551,21 @@ public class SwiftTool {
551551
let cachePath = self.options.useRepositoriesCache ? try self.getCachePath() : .none
552552
_ = try self.getConfigPath() // TODO: actually use this in the workspace
553553
let isXcodeBuildSystemEnabled = self.options.buildSystem == .xcode
554-
let workspace = Workspace(
554+
let workspace = try Workspace(
555+
fileSystem: localFileSystem,
555556
dataPath: buildPath,
556557
editablesPath: try editablesPath(),
557-
pinsFile: try resolvedFilePath(),
558-
manifestLoader: try getManifestLoader(),
559-
toolsVersionLoader: ToolsVersionLoader(),
560-
delegate: delegate,
561-
config: try getSwiftPMConfig(),
562-
repositoryProvider: provider,
563-
netrcFilePath: try resolvedNetrcFilePath(),
558+
resolvedVersionsFilePath: try resolvedVersionsFilePath(),
559+
cachePath: cachePath,
560+
netrcFilePath: try netrcFilePath(),
561+
mirrors: self.getMirrorsConfig().mirrors,
562+
customManifestLoader: try getManifestLoader(), // FIXME: doe we really need to customize it?
563+
customRepositoryProvider: provider, // FIXME: doe we really need to customize it?
564564
additionalFileRules: isXcodeBuildSystemEnabled ? FileRuleDescription.xcbuildFileTypes : FileRuleDescription.swiftpmFileTypes,
565-
isResolverPrefetchingEnabled: options.shouldEnableResolverPrefetching,
566-
skipUpdate: options.skipDependencyUpdate,
567-
enableResolverTrace: options.enableResolverTrace,
568-
cachePath: cachePath
565+
resolverUpdateEnabled: !options.skipDependencyUpdate,
566+
resolverPrefetchingEnabled: options.shouldEnableResolverPrefetching,
567+
resolverTracingEnabled: options.enableResolverTrace,
568+
delegate: delegate
569569
)
570570
_workspace = workspace
571571
_workspaceDelegate = delegate

Sources/PackageGraph/DependencyMirrors.swift

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public final class DependencyMirrors {
2424

2525
private var index: [String: String]
2626
private var reverseIndex: [String: String]
27+
private let lock = Lock()
2728

2829
private init(_ mirrors: [Mirror]) {
2930
self.index = Dictionary(mirrors.map({ ($0.original, $0.mirror) }), uniquingKeysWith: { first, _ in first })
@@ -32,30 +33,36 @@ public final class DependencyMirrors {
3233

3334
/// Sets a mirror URL for the given URL.
3435
public func set(mirrorURL: String, forURL url: String) {
35-
self.index[url] = mirrorURL
36-
self.reverseIndex[mirrorURL] = url
36+
self.lock.withLock {
37+
self.index[url] = mirrorURL
38+
self.reverseIndex[mirrorURL] = url
39+
}
3740
}
3841

3942
/// Unsets a mirror for the given URL.
4043
/// - Parameter originalOrMirrorURL: The original URL or the mirrored URL
4144
/// - Throws: `Error.mirrorNotFound` if no mirror exists for the provided URL.
4245
public func unset(originalOrMirrorURL: String) throws {
43-
if let value = self.index[originalOrMirrorURL] {
44-
self.index[originalOrMirrorURL] = nil
45-
self.reverseIndex[value] = nil
46-
} else if let mirror = self.index.first(where: { $0.value == originalOrMirrorURL }) {
47-
self.index[mirror.key] = nil
48-
self.reverseIndex[originalOrMirrorURL] = nil
49-
} else {
50-
throw Error.mirrorNotFound
46+
try self.lock.withLock {
47+
if let value = self.index[originalOrMirrorURL] {
48+
self.index[originalOrMirrorURL] = nil
49+
self.reverseIndex[value] = nil
50+
} else if let mirror = self.index.first(where: { $0.value == originalOrMirrorURL }) {
51+
self.index[mirror.key] = nil
52+
self.reverseIndex[originalOrMirrorURL] = nil
53+
} else {
54+
throw Error.mirrorNotFound
55+
}
5156
}
5257
}
5358

5459
/// Returns the mirrored URL for a package dependency URL.
5560
/// - Parameter url: The original URL
5661
/// - Returns: The mirrored URL, if one exists.
5762
public func mirrorURL(for url: String) -> String? {
58-
return self.index[url]
63+
self.lock.withLock {
64+
return self.index[url]
65+
}
5966
}
6067

6168
/// Returns the effective URL for a package dependency URL.
@@ -69,9 +76,10 @@ public final class DependencyMirrors {
6976
/// - Parameter url: The mirror URL
7077
/// - Returns: The original URL, if one exists.
7178
public func originalURL(for url: String) -> String? {
72-
return self.reverseIndex[url]
79+
self.lock.withLock {
80+
return self.reverseIndex[url]
81+
}
7382
}
74-
7583
}
7684

7785
extension DependencyMirrors: Collection {

Sources/PackageGraph/Pubgrub/PubgrubDependencyResolver.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,30 +102,30 @@ public struct PubgrubDependencyResolver {
102102
/// The container provider used to load package containers.
103103
private let provider: ContainerProvider
104104

105-
/// Skip updating containers while fetching them.
106-
private let skipUpdate: Bool
107-
108105
/// Reference to the package container provider.
109106
private let packageContainerProvider: PackageContainerProvider
110107

111108
/// Should resolver prefetch the containers.
112-
private let isPrefetchingEnabled: Bool
109+
private let prefetchingEnabled: Bool
110+
111+
/// Skip updating containers while fetching them.
112+
private let updateEnabled: Bool
113113

114114
/// Resolver delegate
115115
private let delegate: DependencyResolverDelegate?
116116

117117
public init(
118118
provider: PackageContainerProvider,
119119
pinsMap: PinsStore.PinsMap = [:],
120-
isPrefetchingEnabled: Bool = false,
121-
skipUpdate: Bool = false,
120+
updateEnabled: Bool = true,
121+
prefetchingEnabled: Bool = false,
122122
delegate: DependencyResolverDelegate? = nil
123123
) {
124124
self.packageContainerProvider = provider
125125
self.pinsMap = pinsMap
126-
self.isPrefetchingEnabled = isPrefetchingEnabled
127-
self.skipUpdate = skipUpdate
128-
self.provider = ContainerProvider(provider: self.packageContainerProvider, skipUpdate: self.skipUpdate, pinsMap: self.pinsMap)
126+
self.updateEnabled = updateEnabled
127+
self.prefetchingEnabled = prefetchingEnabled
128+
self.provider = ContainerProvider(provider: self.packageContainerProvider, updateEnabled: self.updateEnabled, pinsMap: self.pinsMap)
129129
self.delegate = delegate
130130
}
131131

@@ -170,7 +170,7 @@ public struct PubgrubDependencyResolver {
170170
let inputs = try self.processInputs(root: root, with: constraints)
171171

172172
// Prefetch the containers if prefetching is enabled.
173-
if self.isPrefetchingEnabled {
173+
if self.prefetchingEnabled {
174174
// We avoid prefetching packages that are overridden since
175175
// otherwise we'll end up creating a repository container
176176
// for them.
@@ -1357,8 +1357,8 @@ private final class ContainerProvider {
13571357
/// The actual package container provider.
13581358
private let underlying: PackageContainerProvider
13591359

1360-
/// Wheather to perform update (git fetch) on existing cloned repositories or not.
1361-
private let skipUpdate: Bool
1360+
/// Whether to perform update (git fetch) on existing cloned repositories or not.
1361+
private let updateEnabled: Bool
13621362

13631363
/// Reference to the pins store.
13641364
private let pinsMap: PinsStore.PinsMap
@@ -1369,9 +1369,9 @@ private final class ContainerProvider {
13691369
//// Store prefetches synchronization
13701370
private var prefetches = ThreadSafeKeyValueStore<PackageReference, DispatchGroup>()
13711371

1372-
init(provider underlying: PackageContainerProvider, skipUpdate: Bool, pinsMap: PinsStore.PinsMap) {
1372+
init(provider underlying: PackageContainerProvider, updateEnabled: Bool, pinsMap: PinsStore.PinsMap) {
13731373
self.underlying = underlying
1374-
self.skipUpdate = skipUpdate
1374+
self.updateEnabled = updateEnabled
13751375
self.pinsMap = pinsMap
13761376
}
13771377

@@ -1404,7 +1404,7 @@ private final class ContainerProvider {
14041404
}
14051405
} else {
14061406
// Otherwise, fetch the container from the provider
1407-
self.underlying.getContainer(for: package, skipUpdate: skipUpdate, on: .sharedConcurrent) { result in
1407+
self.underlying.getContainer(for: package, skipUpdate: !self.updateEnabled, on: .sharedConcurrent) { result in
14081408
let result = result.tryMap { container -> PubGrubPackageContainer in
14091409
let pubGrubContainer = PubGrubPackageContainer(underlying: container, pinsMap: self.pinsMap)
14101410
// only cache positive results
@@ -1428,7 +1428,7 @@ private final class ContainerProvider {
14281428
return group
14291429
}
14301430
if needsFetching {
1431-
self.underlying.getContainer(for: identifier, skipUpdate: skipUpdate, on: .sharedConcurrent) { result in
1431+
self.underlying.getContainer(for: identifier, skipUpdate: !self.updateEnabled, on: .sharedConcurrent) { result in
14321432
defer { self.prefetches[identifier]?.leave() }
14331433
// only cache positive results
14341434
if case .success(let container) = result {

0 commit comments

Comments
 (0)