Skip to content

Commit 5d039ee

Browse files
committed
wip
1 parent a6f29d5 commit 5d039ee

38 files changed

+871
-530
lines changed

Examples/package-info/Sources/package-info/main.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ let packagePath = localFileSystem.currentWorkingDirectory!
3131
// There are several levels of information available.
3232
// Each takes longer to load than the level above it, but provides more detail.
3333
let diagnostics = DiagnosticsEngine()
34-
let manifest = try tsc_await { ManifestLoader.loadManifest(at: packagePath, kind: .local, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], on: .global(), completion: $0) }
35-
let loadedPackage = try tsc_await { PackageBuilder.loadPackage(at: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], diagnostics: diagnostics, on: .global(), completion: $0) }
36-
let graph = try Workspace.loadGraph(packagePath: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], diagnostics: diagnostics)
34+
let identityResolver = DefaultIdentityResolver()
35+
let manifest = try tsc_await { ManifestLoader.loadManifest(at: packagePath, kind: .local, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, on: .global(), completion: $0) }
36+
let loadedPackage = try tsc_await { PackageBuilder.loadPackage(at: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, diagnostics: diagnostics, on: .global(), completion: $0) }
37+
let graph = try Workspace.loadGraph(packagePath: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, diagnostics: diagnostics)
3738

3839
// EXAMPLES
3940
// ========

Sources/Commands/Describe.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,22 @@ fileprivate struct DescribedPackage: Encodable {
100100

101101
/// Represents a package dependency for the sole purpose of generating a description.
102102
struct DescribedPackageDependency: Encodable {
103+
let identity: PackageIdentity
103104
let name: String?
104105
let url: String?
105106
let requirement: PackageDependencyDescription.Requirement?
106107

107108
init(from dependency: PackageDependencyDescription) {
109+
self.identity = dependency.identity
108110
self.name = dependency.explicitNameForTargetDependencyResolutionOnly
109-
self.url = dependency.location
110-
self.requirement = dependency.requirement
111+
switch dependency {
112+
case .local(let data):
113+
self.url = data.path.pathString
114+
self.requirement = nil
115+
case .git(let data):
116+
self.url = data.location
117+
self.requirement = data.requirement
118+
}
111119
}
112120
}
113121

Sources/Commands/SwiftTool.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,9 +784,15 @@ public class SwiftTool {
784784
case (false, .shared):
785785
cachePath = try self.getCachePath().map{ $0.appending(component: "manifests") }
786786
}
787+
788+
// inject URL mapping (aka mirrors)
789+
let config = try self.getSwiftPMConfig()
790+
let identityResolver = DefaultIdentityResolver(urlMapper: config.mirrors.effectiveURL(forURL:))
791+
787792
return try ManifestLoader(
788793
// Always use the host toolchain's resources for parsing manifest.
789794
manifestResources: self._hostToolchain.get().manifestResources,
795+
identityResolver: identityResolver,
790796
isManifestSandboxEnabled: !self.options.shouldDisableSandbox,
791797
cacheDir: cachePath,
792798
extraManifestFlags: self.options.manifestFlags

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,21 @@ extension PackageGraph {
4242
let manifestMapSequence = (root.manifests + externalManifests).map({ (PackageIdentity(url: $0.packageLocation), $0) })
4343
let manifestMap = Dictionary(uniqueKeysWithValues: manifestMapSequence)
4444
let successors: (GraphLoadingNode) -> [GraphLoadingNode] = { node in
45-
node.requiredDependencies().compactMap({ dependency in
46-
let url = mirrors.effectiveURL(forURL: dependency.location)
47-
return manifestMap[PackageIdentity(url: url)].map { manifest in
45+
node.requiredDependencies().compactMap{ dependency in
46+
return manifestMap[dependency.identity].map { manifest in
4847
GraphLoadingNode(manifest: manifest, productFilter: dependency.productFilter)
4948
}
50-
})
49+
}
5150
}
5251

5352
// Construct the root manifest and root dependencies set.
5453
let rootManifestSet = Set(root.manifests)
55-
let rootDependencies = Set(root.dependencies.compactMap({
56-
manifestMap[PackageIdentity(url: $0.location)]
57-
}))
54+
let rootDependencies = Set(root.dependencies.compactMap{
55+
manifestMap[$0.identity]
56+
})
5857
let rootManifestNodes = root.manifests.map { GraphLoadingNode(manifest: $0, productFilter: .everything) }
5958
let rootDependencyNodes = root.dependencies.lazy.compactMap { (dependency: PackageDependencyDescription) -> GraphLoadingNode? in
60-
guard let manifest = manifestMap[PackageIdentity(url: dependency.location)] else { return nil }
59+
guard let manifest = manifestMap[dependency.identity] else { return nil }
6160
return GraphLoadingNode(manifest: manifest, productFilter: dependency.productFilter)
6261
}
6362
let inputManifests = rootManifestNodes + rootDependencyNodes
@@ -223,8 +222,15 @@ private func createResolvedPackages(
223222
var dependencies = [ResolvedPackageBuilder]()
224223
// Establish the manifest-declared package dependencies.
225224
package.manifest.dependenciesRequired(for: packageBuilder.productFilter).forEach { dependency in
226-
let dependencyURL = mirrors.effectiveURL(forURL: dependency.location)
227-
let dependencyIdentity = PackageIdentity(url: dependencyURL)
225+
let dependencyIdentity = dependency.identity
226+
// FIXME: change this validation logic to use identity instead of location
227+
let dependencyLocation: String
228+
switch dependency {
229+
case .local(let data):
230+
dependencyLocation = data.path.pathString
231+
case .git(let data):
232+
dependencyLocation = data.location
233+
}
228234

229235
// Use the package name to lookup the dependency. The package name will be present in packages with tools version >= 5.2.
230236
if let explicitDependencyName = dependency.explicitNameForTargetDependencyResolutionOnly, let resolvedPackage = packageMapByName[explicitDependencyName] {
@@ -234,7 +240,7 @@ private func createResolvedPackages(
234240
// FIXME: this works but the way we find out about this is based on a side effect, need to improve it when working on identity
235241
let error = PackageGraphError.dependencyAlreadySatisfiedByName(
236242
dependencyPackageName: package.name,
237-
dependencyURL: dependencyURL,
243+
dependencyLocation: dependencyLocation,
238244
otherDependencyURL: resolvedPackage.package.manifest.packageLocation,
239245
name: explicitDependencyName)
240246
let diagnosticLocation = PackageLocation.Local(name: package.name, packagePath: package.path)
@@ -251,7 +257,7 @@ private func createResolvedPackages(
251257
guard !dependencies.contains(resolvedPackage) else {
252258
let error = PackageGraphError.dependencyAlreadySatisfiedByIdentifier(
253259
dependencyPackageName: package.name,
254-
dependencyURL: dependencyURL,
260+
dependencyLocation: dependencyLocation,
255261
otherDependencyURL: resolvedPackage.package.manifest.packageLocation,
256262
identity: dependencyIdentity)
257263
let diagnosticLocation = PackageLocation.Local(name: package.name, packagePath: package.path)
@@ -262,10 +268,10 @@ private func createResolvedPackages(
262268
// check if this resolvedPackage url is the same as the dependency one
263269
// if not, this means that the dependencies share the same identity
264270
// FIXME: this works but the way we find out about this is based on a side effect, need to improve it when working on identity
265-
if resolvedPackage.package.manifest.packageLocation != dependencyURL {
271+
if resolvedPackage.package.manifest.packageLocation != dependencyLocation {
266272
let error = PackageGraphError.dependencyAlreadySatisfiedByIdentifier(
267273
dependencyPackageName: package.name,
268-
dependencyURL: dependencyURL,
274+
dependencyLocation: dependencyLocation,
269275
otherDependencyURL: resolvedPackage.package.manifest.packageLocation,
270276
identity: dependencyIdentity)
271277
let diagnosticLocation = PackageLocation.Local(name: package.name, packagePath: package.path)
@@ -274,7 +280,7 @@ private func createResolvedPackages(
274280
let error = PackageGraphError.incorrectPackageDependencyName(
275281
dependencyPackageName: package.name,
276282
dependencyName: explicitDependencyName,
277-
dependencyURL: dependencyURL,
283+
dependencyLocation: dependencyLocation,
278284
resolvedPackageName: resolvedPackage.package.name,
279285
resolvedPackageURL: resolvedPackage.package.manifest.packageLocation)
280286
let diagnosticLocation = PackageLocation.Local(name: package.name, packagePath: package.path)
@@ -417,9 +423,7 @@ private func createResolvedPackages(
417423
let referencedPackageURL = mirrors.effectiveURL(forURL: product.packageBuilder.package.manifest.packageLocation)
418424
let referencedPackageIdentity = PackageIdentity(url: referencedPackageURL)
419425
guard let packageDependency = (packageBuilder.package.manifest.dependencies.first { package in
420-
let packageURL = mirrors.effectiveURL(forURL: package.location)
421-
let packageIdentity = PackageIdentity(url: packageURL)
422-
return packageIdentity == referencedPackageIdentity
426+
return package.identity == referencedPackageIdentity
423427
}) else {
424428
throw InternalError("dependency reference for \(referencedPackageURL) not found")
425429
}

Sources/PackageGraph/PackageGraph.swift

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ enum PackageGraphError: Swift.Error {
2525
case productDependencyIncorrectPackage(name: String, package: String)
2626

2727
/// The package dependency name does not match the package name.
28-
case incorrectPackageDependencyName(dependencyPackageName: String, dependencyName: String, dependencyURL: String, resolvedPackageName: String, resolvedPackageURL: String)
28+
case incorrectPackageDependencyName(dependencyPackageName: String, dependencyName: String, dependencyLocation: String, resolvedPackageName: String, resolvedPackageURL: String)
2929

3030
/// The package dependency already satisfied by a different dependency package
31-
case dependencyAlreadySatisfiedByIdentifier(dependencyPackageName: String, dependencyURL: String, otherDependencyURL: String, identity: PackageIdentity)
31+
case dependencyAlreadySatisfiedByIdentifier(dependencyPackageName: String, dependencyLocation: String, otherDependencyURL: String, identity: PackageIdentity)
3232

3333
/// The package dependency already satisfied by a different dependency package
34-
case dependencyAlreadySatisfiedByName(dependencyPackageName: String, dependencyURL: String, otherDependencyURL: String, name: String)
34+
case dependencyAlreadySatisfiedByName(dependencyPackageName: String, dependencyLocation: String, otherDependencyURL: String, name: String)
3535

3636
/// The product dependency was found but the package name was not referenced correctly (tools version > 5.2).
3737
case productDependencyMissingPackage(
@@ -244,12 +244,12 @@ fileprivate extension PackageDependencyDescription {
244244
parameters.append("name: \"\(name)\"")
245245
}
246246

247-
if requirement == .localPackage {
248-
parameters.append("path: \"\(self.location)\"")
249-
} else {
250-
parameters.append("url: \"\(self.location)\"")
251-
252-
switch requirement {
247+
switch self {
248+
case .local(let data):
249+
parameters.append("path: \"\(data.path)\"")
250+
case .git(let data):
251+
parameters.append("url: \"\(data.location)\"")
252+
switch data.requirement {
253253
case .branch(let branch):
254254
parameters.append(".branch(\"\(branch)\")")
255255
case .exact(let version):
@@ -264,8 +264,6 @@ fileprivate extension PackageDependencyDescription {
264264
} else {
265265
parameters.append(".upToNextMinor(\"\(range.lowerBound)\"..<\"\(range.upperBound)\")")
266266
}
267-
case .localPackage:
268-
fatalError("handled above")
269267
}
270268
}
271269

Sources/PackageGraph/PackageGraphRoot.swift

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,42 +72,45 @@ public struct PackageGraphRoot {
7272

7373
/// Returns the constraints imposed by root manifests + dependencies.
7474
public func constraints(mirrors: DependencyMirrors) -> [PackageContainerConstraint] {
75-
let constraints = packageRefs.map({
75+
let constraints = packageRefs.map{
7676
PackageContainerConstraint(package: $0, requirement: .unversioned, products: .everything)
77-
})
78-
return constraints + dependencies.map({
77+
}
78+
return constraints + dependencies.map{
7979
PackageContainerConstraint(
8080
package: $0.createPackageRef(mirrors: mirrors),
81-
requirement: $0.requirement.toConstraintRequirement(),
81+
requirement: $0.toConstraintRequirement(),
8282
products: $0.productFilter
8383
)
84-
})
84+
}
8585
}
8686
}
8787

88-
extension PackageDependencyDescription.Requirement {
88+
extension PackageDependencyDescription {
89+
/// Returns the constraint requirement representation.
90+
public func toConstraintRequirement() -> PackageRequirement {
91+
switch self {
92+
case .local:
93+
return .unversioned
94+
case .git(let data):
95+
return data.requirement.toConstraintRequirement()
96+
}
97+
}
98+
}
8999

100+
extension PackageDependencyDescription.Requirement {
90101
/// Returns the constraint requirement representation.
91102
public func toConstraintRequirement() -> PackageRequirement {
92103
switch self {
93104
case .range(let range):
94105
return .versionSet(.range(range))
95-
96106
case .revision(let identifier):
97107
assert(Git.checkRefFormat(ref: identifier))
98-
99108
return .revision(identifier)
100-
101109
case .branch(let identifier):
102110
assert(Git.checkRefFormat(ref: identifier))
103-
104111
return .revision(identifier)
105-
106112
case .exact(let version):
107113
return .versionSet(.exact(version))
108-
109-
case .localPackage:
110-
return .unversioned
111114
}
112115
}
113116
}

Sources/PackageGraph/PackageModel+Extensions.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ import SourceControl
1414
extension PackageDependencyDescription {
1515
/// Create the package reference object for the dependency.
1616
public func createPackageRef(mirrors: DependencyMirrors) -> PackageReference {
17-
let effectiveURL = mirrors.effectiveURL(forURL: self.location)
18-
19-
// FIXME: The identity of a package dependency is currently based on
20-
// on a name computed from the package's effective URL. This
21-
// is because the name of the package that's in the manifest
22-
// is not known until the manifest has been parsed.
23-
// We should instead use the declared URL of a package dependency
24-
// as its identity, as it will be needed for supporting package
25-
// registries.
26-
let identity = PackageIdentity(url: effectiveURL)
27-
17+
// TODO (next steps): move the location into PackageKind to preserve path vs. location
18+
let packageKind: PackageReference.Kind
19+
let location: String
20+
switch self {
21+
case .local(let data):
22+
packageKind = .local
23+
location = data.path.pathString
24+
case .git(let data):
25+
packageKind = .remote
26+
location = data.location
27+
}
2828
return PackageReference(
29-
identity: identity,
30-
kind: requirement == .localPackage ? .local : .remote,
31-
location: effectiveURL
29+
identity: self.identity,
30+
kind: packageKind,
31+
location: location
3232
)
3333
}
3434
}
@@ -39,7 +39,7 @@ extension Manifest {
3939
return dependenciesRequired(for: productFilter).map({
4040
return PackageContainerConstraint(
4141
package: $0.createPackageRef(mirrors: mirrors),
42-
requirement: $0.requirement.toConstraintRequirement(),
42+
requirement: $0.toConstraintRequirement(),
4343
products: $0.productFilter)
4444
})
4545
}

Sources/PackageLoading/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
add_library(PackageLoading
1010
Diagnostics.swift
11+
IdentityResolver.swift
1112
ManifestLoader.swift
1213
MinimumDeploymentTarget.swift
1314
ModuleMapGenerator.swift
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2021 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import TSCBasic
12+
import PackageModel
13+
14+
// TODO: refactor this when adding registry support
15+
public protocol IdentityResolver {
16+
func resolveIdentity(for location: String) -> PackageIdentity
17+
func resolveIdentity(for path: AbsolutePath) -> PackageIdentity
18+
func resolveURL(from otherURL: String) -> String
19+
}
20+
21+
public struct DefaultIdentityResolver: IdentityResolver {
22+
let urlMapper: (String) -> String
23+
24+
public init(urlMapper: @escaping (String) -> String = { $0 }) {
25+
self.urlMapper = urlMapper
26+
}
27+
28+
public func resolveIdentity(for location: String) -> PackageIdentity {
29+
return PackageIdentity(url: location)
30+
}
31+
32+
public func resolveIdentity(for path: AbsolutePath) -> PackageIdentity {
33+
return PackageIdentity(url: path.pathString)
34+
}
35+
36+
public func resolveURL(from otherURL: String) -> String {
37+
return self.urlMapper(otherURL)
38+
}
39+
}

0 commit comments

Comments
 (0)