Skip to content

Commit a4ed9a3

Browse files
committed
WIP: Make PackageRegistry module optional
1 parent dde5b89 commit a4ed9a3

13 files changed

+228
-97
lines changed

Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ let package = Package(
196196
dependencies: [
197197
"Basics",
198198
"PackageFingerprint",
199+
"PackageGraph",
199200
"PackageLoading",
200201
"PackageModel"
201202
],
@@ -247,7 +248,6 @@ let package = Package(
247248
"Basics",
248249
"PackageLoading",
249250
"PackageModel",
250-
"PackageRegistry",
251251
"SourceControl"
252252
],
253253
exclude: ["CMakeLists.txt", "README.md"]
@@ -352,6 +352,7 @@ let package = Package(
352352
"PackageCollections",
353353
"PackageFingerprint",
354354
"PackageGraph",
355+
"PackageRegistry",
355356
"SourceControl",
356357
"Workspace",
357358
"XCBuildSupport",
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Basics
14+
import Dispatch
15+
import Foundation
16+
import PackageModel
17+
18+
import struct TSCBasic.AbsolutePath
19+
20+
// MARK: - Registry downloads manager
21+
22+
public struct RegistryDownloads {
23+
/// Additional information about a fetch
24+
public struct FetchDetails: Equatable {
25+
/// Indicates if the repository was fetched from the cache or from the remote.
26+
public let fromCache: Bool
27+
/// Indicates wether the wether the repository was already present in the cache and updated or if a clean fetch was performed.
28+
public let updatedCache: Bool
29+
30+
public init(fromCache: Bool, updatedCache: Bool) {
31+
self.fromCache = fromCache
32+
self.updatedCache = updatedCache
33+
}
34+
}
35+
}
36+
37+
/// Delegate to notify clients about actions being performed by RegistryManager.
38+
public protocol RegistryDownloadsManagerDelegate {
39+
/// Called when a package is about to be fetched.
40+
func willFetch(package: PackageIdentity, version: Version, fetchDetails: RegistryDownloads.FetchDetails)
41+
42+
/// Called when a package has finished fetching.
43+
func didFetch(package: PackageIdentity, version: Version, result: Result<RegistryDownloads.FetchDetails, Error>, duration: DispatchTimeInterval)
44+
45+
/// Called every time the progress of a repository fetch operation updates.
46+
func fetching(package: PackageIdentity, version: Version, bytesDownloaded: Int64, totalBytesToDownload: Int64?)
47+
}
48+
49+
public protocol RegistryDownloadsManagerInterface {
50+
func lookup(
51+
package: PackageIdentity,
52+
version: Version,
53+
observabilityScope: ObservabilityScope,
54+
delegateQueue: DispatchQueue,
55+
callbackQueue: DispatchQueue,
56+
completion: @escaping (Result<AbsolutePath, Error>) -> Void
57+
)
58+
59+
func purgeCache() throws
60+
func remove(package: PackageIdentity) throws
61+
func reset() throws
62+
}
63+
64+
// MARK: - Registry client
65+
66+
public struct RegistryPackageMetadata {
67+
public let versions: [Version]
68+
public let alternateLocations: [URL]?
69+
70+
public init(versions: [Version], alternateLocations: [URL]?) {
71+
self.versions = versions
72+
self.alternateLocations = alternateLocations
73+
}
74+
}
75+
76+
public protocol RegistryClientInterface {
77+
var configured: Bool { get }
78+
79+
func getAvailableManifests(
80+
package: PackageIdentity,
81+
version: Version,
82+
timeout: DispatchTimeInterval?,
83+
observabilityScope: ObservabilityScope,
84+
callbackQueue: DispatchQueue,
85+
completion: @escaping (Result<[String: (toolsVersion: ToolsVersion, content: String?)], Error>) -> Void
86+
)
87+
88+
func getManifestContent(
89+
package: PackageIdentity,
90+
version: Version,
91+
customToolsVersion: ToolsVersion?,
92+
timeout: DispatchTimeInterval?,
93+
observabilityScope: ObservabilityScope,
94+
callbackQueue: DispatchQueue,
95+
completion: @escaping (Result<String, Error>) -> Void
96+
)
97+
98+
func getPackageMetadata(
99+
package: PackageIdentity,
100+
timeout: DispatchTimeInterval?,
101+
observabilityScope: ObservabilityScope,
102+
callbackQueue: DispatchQueue,
103+
completion: @escaping (Result<RegistryPackageMetadata, Error>) -> Void
104+
)
105+
106+
func lookupIdentities(
107+
url: URL,
108+
timeout: DispatchTimeInterval?,
109+
observabilityScope: ObservabilityScope,
110+
callbackQueue: DispatchQueue,
111+
completion: @escaping (Result<Set<PackageIdentity>, Error>) -> Void
112+
)
113+
}
114+
115+
public extension RegistryClientInterface {
116+
func getAvailableManifests(
117+
package: PackageIdentity,
118+
version: Version,
119+
observabilityScope: ObservabilityScope,
120+
callbackQueue: DispatchQueue,
121+
completion: @escaping (Result<[String: (toolsVersion: ToolsVersion, content: String?)], Error>) -> Void
122+
) {
123+
self.getAvailableManifests(package: package,
124+
version: version,
125+
timeout: .none,
126+
observabilityScope: observabilityScope,
127+
callbackQueue: callbackQueue,
128+
completion: completion)
129+
}
130+
131+
func getManifestContent(
132+
package: PackageIdentity,
133+
version: Version,
134+
customToolsVersion: ToolsVersion?,
135+
observabilityScope: ObservabilityScope,
136+
callbackQueue: DispatchQueue,
137+
completion: @escaping (Result<String, Error>) -> Void
138+
) {
139+
self.getManifestContent(package: package,
140+
version: version,
141+
customToolsVersion: customToolsVersion,
142+
timeout: .none,
143+
observabilityScope: observabilityScope,
144+
callbackQueue: callbackQueue,
145+
completion: completion)
146+
}
147+
148+
func getPackageMetadata(
149+
package: PackageIdentity,
150+
observabilityScope: ObservabilityScope,
151+
callbackQueue: DispatchQueue,
152+
completion: @escaping (Result<RegistryPackageMetadata, Error>) -> Void
153+
) {
154+
self.getPackageMetadata(
155+
package: package,
156+
timeout: .none,
157+
observabilityScope: observabilityScope,
158+
callbackQueue: callbackQueue,
159+
completion: completion)
160+
}
161+
162+
func lookupIdentities(
163+
url: URL,
164+
observabilityScope: ObservabilityScope,
165+
callbackQueue: DispatchQueue,
166+
completion: @escaping (Result<Set<PackageIdentity>, Error>) -> Void
167+
) {
168+
self.lookupIdentities(url: url,
169+
timeout: .none,
170+
observabilityScope: observabilityScope,
171+
callbackQueue: callbackQueue,
172+
completion: completion)
173+
}
174+
}

Sources/PackageRegistry/RegistryClient.swift

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ import Basics
1414
import Dispatch
1515
import Foundation
1616
import PackageFingerprint
17+
import PackageGraph
1718
import PackageLoading
1819
import PackageModel
1920
import TSCBasic
2021

2122
/// Package registry client.
2223
/// API specification: https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md
23-
public final class RegistryClient: Cancellable {
24+
public final class RegistryClient: RegistryClientInterface, Cancellable {
2425
private let apiVersion: APIVersion = .v1
2526

2627
private let configuration: RegistryConfiguration
@@ -62,7 +63,7 @@ public final class RegistryClient: Cancellable {
6263
timeout: DispatchTimeInterval? = .none,
6364
observabilityScope: ObservabilityScope,
6465
callbackQueue: DispatchQueue,
65-
completion: @escaping (Result<PackageMetadata, Error>) -> Void
66+
completion: @escaping (Result<RegistryPackageMetadata, Error>) -> Void
6667
) {
6768
let completion = self.makeAsync(completion, on: callbackQueue)
6869

@@ -107,7 +108,7 @@ public final class RegistryClient: Cancellable {
107108

108109
let alternateLocations = try response.headers.parseAlternativeLocationLinks()
109110

110-
return PackageMetadata(
111+
return RegistryPackageMetadata(
111112
versions: versions,
112113
alternateLocations: alternateLocations?.map{ $0.url }
113114
)
@@ -657,13 +658,6 @@ fileprivate extension RegistryClient {
657658
}
658659
}
659660

660-
extension RegistryClient {
661-
public struct PackageMetadata {
662-
public let versions: [Version]
663-
public let alternateLocations: [URL]?
664-
}
665-
}
666-
667661
fileprivate extension RegistryClient {
668662
struct AlternativeLocationLink {
669663
let url: URL

Sources/PackageRegistry/RegistryDownloadsManager.swift

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import Basics
1414
import Dispatch
1515
import Foundation
16+
import PackageGraph
1617
import PackageModel
1718
import TSCBasic
1819
import PackageLoading
@@ -101,7 +102,7 @@ public class RegistryDownloadsManager: Cancellable {
101102
// calculate if cached (for delegate call) outside queue as it may change while queue is processing
102103
let isCached = self.cachePath.map{ self.fileSystem.exists($0.appending(packageRelativePath)) } ?? false
103104
delegateQueue.async {
104-
let details = FetchDetails(fromCache: isCached, updatedCache: false)
105+
let details = RegistryDownloads.FetchDetails(fromCache: isCached, updatedCache: false)
105106
self.delegate?.willFetch(package: package, version: version, fetchDetails: details)
106107
}
107108

@@ -145,7 +146,7 @@ public class RegistryDownloadsManager: Cancellable {
145146
observabilityScope: ObservabilityScope,
146147
delegateQueue: DispatchQueue,
147148
callbackQueue: DispatchQueue,
148-
completion: @escaping (Result<FetchDetails, Error>) -> Void
149+
completion: @escaping (Result<RegistryDownloads.FetchDetails, Error>) -> Void
149150
) {
150151
if let cachePath = self.cachePath {
151152
do {
@@ -186,7 +187,7 @@ public class RegistryDownloadsManager: Cancellable {
186187
// copy the package from the cache into the package path.
187188
try self.fileSystem.createDirectory(packagePath.parentDirectory, recursive: true)
188189
try self.fileSystem.copy(from: cachedPackagePath, to: packagePath)
189-
return FetchDetails(fromCache: true, updatedCache: true)
190+
return RegistryDownloads.FetchDetails(fromCache: true, updatedCache: true)
190191
})
191192
}
192193
}
@@ -206,7 +207,7 @@ public class RegistryDownloadsManager: Cancellable {
206207
observabilityScope: observabilityScope,
207208
callbackQueue: callbackQueue
208209
) { result in
209-
completion(result.map{ FetchDetails(fromCache: false, updatedCache: false) })
210+
completion(result.map{ RegistryDownloads.FetchDetails(fromCache: false, updatedCache: false) })
210211
}
211212
}
212213
} else {
@@ -223,7 +224,7 @@ public class RegistryDownloadsManager: Cancellable {
223224
observabilityScope: observabilityScope,
224225
callbackQueue: callbackQueue
225226
) { result in
226-
completion(result.map{ FetchDetails(fromCache: false, updatedCache: false) })
227+
completion(result.map{ RegistryDownloads.FetchDetails(fromCache: false, updatedCache: false) })
227228
}
228229
}
229230

@@ -270,29 +271,6 @@ public class RegistryDownloadsManager: Cancellable {
270271
}
271272
}
272273

273-
/// Delegate to notify clients about actions being performed by RegistryManager.
274-
public protocol RegistryDownloadsManagerDelegate {
275-
/// Called when a package is about to be fetched.
276-
func willFetch(package: PackageIdentity, version: Version, fetchDetails: RegistryDownloadsManager.FetchDetails)
277-
278-
/// Called when a package has finished fetching.
279-
func didFetch(package: PackageIdentity, version: Version, result: Result<RegistryDownloadsManager.FetchDetails, Error>, duration: DispatchTimeInterval)
280-
281-
/// Called every time the progress of a repository fetch operation updates.
282-
func fetching(package: PackageIdentity, version: Version, bytesDownloaded: Int64, totalBytesToDownload: Int64?)
283-
}
284-
285-
extension RegistryDownloadsManager {
286-
/// Additional information about a fetch
287-
public struct FetchDetails: Equatable {
288-
/// Indicates if the repository was fetched from the cache or from the remote.
289-
public let fromCache: Bool
290-
/// Indicates wether the wether the repository was already present in the cache and updated or if a clean fetch was performed.
291-
public let updatedCache: Bool
292-
}
293-
}
294-
295-
296274
extension FileSystem {
297275
func validPackageDirectory(_ path: AbsolutePath) throws -> Bool {
298276
if !self.exists(path) {

Sources/SPMTestSupport/MockRegistry.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class MockRegistry {
2525
private let fileSystem: FileSystem
2626
private let identityResolver: IdentityResolver
2727
private let checksumAlgorithm: HashAlgorithm
28-
public var registryClient: RegistryClient!
28+
public var registryClient: RegistryClientInterface!
2929
private let jsonEncoder: JSONEncoder
3030

3131
private var packageVersions = [PackageIdentity: [String: InMemoryRegistryPackageSource]]()

Sources/SPMTestSupport/MockWorkspace.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public final class MockWorkspace {
3030
let customToolsVersion: ToolsVersion?
3131
let fingerprints: MockPackageFingerprintStorage
3232
let mirrors: DependencyMirrors
33-
public var registryClient: RegistryClient
33+
public var registryClient: RegistryClientInterface
3434
let registry: MockRegistry
3535
let customBinaryArtifactsManager: Workspace.CustomBinaryArtifactsManager
3636
public var checksumAlgorithm: MockHashAlgorithm
@@ -258,6 +258,7 @@ public final class MockWorkspace {
258258
sharedSecurityDirectory: self.fileSystem.swiftPMSecurityDirectory,
259259
sharedCacheDirectory: self.fileSystem.swiftPMCacheDirectory
260260
),
261+
registryClient: self.registryClient,
261262
configuration: .init(
262263
skipDependenciesUpdates: self.skipDependenciesUpdates,
263264
prefetchBasedOnResolvedFile: WorkspaceConfiguration.default.prefetchBasedOnResolvedFile,
@@ -274,7 +275,6 @@ public final class MockWorkspace {
274275
customManifestLoader: self.manifestLoader,
275276
customPackageContainerProvider: self.customPackageContainerProvider,
276277
customRepositoryProvider: self.repositoryProvider,
277-
customRegistryClient: self.registryClient,
278278
customBinaryArtifactsManager: self.customBinaryArtifactsManager,
279279
customIdentityResolver: self.identityResolver,
280280
customChecksumAlgorithm: self.checksumAlgorithm,

Sources/Workspace/RegistryPackageContainer.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@ import Dispatch
1515
import PackageGraph
1616
import PackageLoading
1717
import PackageModel
18-
import PackageRegistry
1918
import TSCBasic
2019

2120
public class RegistryPackageContainer: PackageContainer {
2221
public let package: PackageReference
2322

24-
private let registryClient: RegistryClient
23+
private let registryClient: RegistryClientInterface
2524
private let identityResolver: IdentityResolver
2625
private let manifestLoader: ManifestLoaderProtocol
2726
private let currentToolsVersion: ToolsVersion
@@ -36,7 +35,7 @@ public class RegistryPackageContainer: PackageContainer {
3635
public init(
3736
package: PackageReference,
3837
identityResolver: IdentityResolver,
39-
registryClient: RegistryClient,
38+
registryClient: RegistryClientInterface,
4039
manifestLoader: ManifestLoaderProtocol,
4140
currentToolsVersion: ToolsVersion,
4241
observabilityScope: ObservabilityScope

Sources/Workspace/Workspace+Configuration.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import PackageFingerprint
1616
import PackageGraph
1717
import PackageLoading
1818
import PackageModel
19-
import PackageRegistry
2019
import TSCBasic
2120

2221
import class TSCUtility.SimplePersistence

0 commit comments

Comments
 (0)