Skip to content

Commit df81b0e

Browse files
authored
Replace PackageGraphRoot.PackageDependency with PackageDependencyDescription (#2997)
* Replace PackageGraphRoot.PackageDependency with PackageDependencyDescription * Add documentation comment for nothing type property * Update CMakeLists.txt for PackageModel module * Replace reference to FilteredDependencyDescription * Add comment about how package identity is determined
1 parent 9d31ebe commit df81b0e

20 files changed

+159
-213
lines changed

Sources/PackageGraph/GraphLoadingNode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public struct GraphLoadingNode: Equatable, Hashable {
3232
}
3333

3434
/// Returns the dependencies required by this node.
35-
internal func requiredDependencies() -> [FilteredDependencyDescription] {
35+
internal func requiredDependencies() -> [PackageDependencyDescription] {
3636
return manifest.dependenciesRequired(for: productFilter)
3737
}
3838
}

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extension PackageGraph {
4242
let manifestMap = Dictionary(uniqueKeysWithValues: manifestMapSequence)
4343
let successors: (GraphLoadingNode) -> [GraphLoadingNode] = { node in
4444
node.requiredDependencies().compactMap({ dependency in
45-
let url = config.mirroredURL(forURL: dependency.declaration.url)
45+
let url = config.mirroredURL(forURL: dependency.url)
4646
return manifestMap[PackageReference.computeIdentity(packageURL: url)].map { manifest in
4747
GraphLoadingNode(manifest: manifest, productFilter: dependency.productFilter)
4848
}
@@ -55,7 +55,7 @@ extension PackageGraph {
5555
manifestMap[PackageReference.computeIdentity(packageURL: $0.url)]
5656
}))
5757
let rootManifestNodes = root.manifests.map { GraphLoadingNode(manifest: $0, productFilter: .everything) }
58-
let rootDependencyNodes = root.dependencies.lazy.compactMap { (dependency: PackageGraphRoot.PackageDependency) -> GraphLoadingNode? in
58+
let rootDependencyNodes = root.dependencies.lazy.compactMap { (dependency: PackageDependencyDescription) -> GraphLoadingNode? in
5959
guard let manifest = manifestMap[PackageReference.computeIdentity(packageURL: dependency.url)] else { return nil }
6060
return GraphLoadingNode(manifest: manifest, productFilter: dependency.productFilter)
6161
}
@@ -223,22 +223,22 @@ private func createResolvedPackages(
223223
packageBuilder.dependencies = package.manifest.dependenciesRequired(for: packageBuilder.productFilter)
224224
.compactMap { dependency in
225225
// Use the package name to lookup the dependency. The package name will be present in packages with tools version >= 5.2.
226-
if let dependencyName = dependency.declaration.explicitName, let resolvedPackage = packageMapByName[dependencyName] {
226+
if let dependencyName = dependency.explicitName, let resolvedPackage = packageMapByName[dependencyName] {
227227
return resolvedPackage
228228
}
229229

230230
// Otherwise, look it up by its identity.
231-
let url = config.mirroredURL(forURL: dependency.declaration.url)
231+
let url = config.mirroredURL(forURL: dependency.url)
232232
let resolvedPackage = packageMapByIdentity[PackageReference.computeIdentity(packageURL: url)]
233233

234234
// We check that the explicit package dependency name matches the package name.
235235
if let resolvedPackage = resolvedPackage,
236-
let explicitDependencyName = dependency.declaration.explicitName,
237-
resolvedPackage.package.name != dependency.declaration.explicitName
236+
let explicitDependencyName = dependency.explicitName,
237+
resolvedPackage.package.name != dependency.explicitName
238238
{
239239
let error = PackageGraphError.incorrectPackageDependencyName(
240240
dependencyName: explicitDependencyName,
241-
dependencyURL: dependency.declaration.url,
241+
dependencyURL: dependency.url,
242242
packageName: resolvedPackage.package.name)
243243
let diagnosticLocation = PackageLocation.Local(name: package.name, packagePath: package.path)
244244
diagnostics.emit(error, location: diagnosticLocation)

Sources/PackageGraph/PackageGraphRoot.swift

Lines changed: 5 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,14 @@ import SourceControl
1616

1717
/// Represents the input to the package graph root.
1818
public struct PackageGraphRootInput {
19-
20-
public typealias PackageDependency = PackageGraphRoot.PackageDependency
21-
2219
/// The list of root packages.
2320
public let packages: [AbsolutePath]
2421

2522
/// Top level dependencies to the graph.
26-
public let dependencies: [PackageDependency]
23+
public let dependencies: [PackageDependencyDescription]
2724

2825
/// Create a package graph root.
29-
public init(packages: [AbsolutePath], dependencies: [PackageDependency] = []) {
26+
public init(packages: [AbsolutePath], dependencies: [PackageDependencyDescription] = []) {
3027
self.packages = packages
3128
self.dependencies = dependencies
3229
}
@@ -35,67 +32,14 @@ public struct PackageGraphRootInput {
3532
/// Represents the inputs to the package graph.
3633
public struct PackageGraphRoot {
3734

38-
// FIXME: We can kill this now.
39-
//
40-
/// Represents a top level package dependencies.
41-
public struct PackageDependency {
42-
43-
public typealias Requirement = PackageModel.PackageDependencyDescription.Requirement
44-
45-
// Location of this dependency.
46-
//
47-
// Opaque location object which will be included in any diagnostics
48-
// related to this dependency. Clients can use this identify where this
49-
// dependency is declared.
50-
public let location: String
51-
52-
/// The URL of the package.
53-
public let url: String
54-
55-
/// The requirement of the package.
56-
public let requirement: Requirement
57-
58-
/// The product filter to apply to the package.
59-
public let productFilter: ProductFilter
60-
61-
/// Create the package reference object for the dependency.
62-
public func createPackageRef(config: SwiftPMConfig) -> PackageReference {
63-
let effectiveURL = config.mirroredURL(forURL: self.url)
64-
return PackageReference(
65-
identity: PackageReference.computeIdentity(packageURL: effectiveURL),
66-
path: effectiveURL,
67-
kind: requirement == .localPackage ? .local : .remote
68-
)
69-
}
70-
71-
public init(
72-
url: String,
73-
requirement: Requirement,
74-
productFilter: ProductFilter,
75-
location: String
76-
) {
77-
// FIXME: SwiftPM can't handle file URLs with file:// scheme so we need to
78-
// strip that. We need to design a URL data structure for SwiftPM.
79-
let filePrefix = "file://"
80-
if url.hasPrefix(filePrefix) {
81-
self.url = AbsolutePath(String(url.dropFirst(filePrefix.count))).pathString
82-
} else {
83-
self.url = url
84-
}
85-
self.requirement = requirement
86-
self.productFilter = productFilter
87-
self.location = location
88-
}
89-
}
90-
9135
/// The list of root manifests.
9236
public let manifests: [Manifest]
9337

9438
/// The root package references.
9539
public let packageRefs: [PackageReference]
9640

9741
/// The top level dependencies.
98-
public let dependencies: [PackageDependency]
42+
public let dependencies: [PackageDependencyDescription]
9943

10044
/// Create a package graph root.
10145
public init(input: PackageGraphRootInput, manifests: [Manifest], explicitProduct: String? = nil) {
@@ -114,13 +58,8 @@ public struct PackageGraphRoot {
11458
// at which time the current special casing can be deprecated.
11559
var adjustedDependencies = input.dependencies
11660
if let product = explicitProduct {
117-
for dependency in manifests.lazy
118-
.map({ $0.dependenciesRequired(for: .everything) }).joined() {
119-
adjustedDependencies.append(PackageDependency(
120-
url: dependency.declaration.url,
121-
requirement: dependency.declaration.requirement,
122-
productFilter: .specific([product]),
123-
location: ""))
61+
for dependency in manifests.lazy.map({ $0.dependenciesRequired(for: .everything) }).joined() {
62+
adjustedDependencies.append(dependency.filtered(by: .specific([product])))
12463
}
12564
}
12665

Sources/PackageGraph/PackageModel+Extensions.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@ import SourceControl
1414
extension PackageDependencyDescription {
1515
/// Create the package reference object for the dependency.
1616
public func createPackageRef(config: SwiftPMConfig) -> PackageReference {
17-
let effectiveURL = config.mirroredURL(forURL: self.url)
17+
let effectiveURL = config.mirroredURL(forURL: url)
18+
19+
// FIXME: The identity of a package dependency is currently based on
20+
// the explicit name provided in the package manifest, if provided,
21+
// falling back on a name computed from its effective URL.
22+
// We should instead use the declared URL of a package dependency as its identity,
23+
// as it will be necessary for supporting package registries.
24+
let identity = explicitName?.lowercased() ?? PackageReference.computeIdentity(packageURL: effectiveURL)
25+
1826
return PackageReference(
19-
identity: PackageReference.computeIdentity(packageURL: effectiveURL),
27+
identity: identity,
2028
path: effectiveURL,
2129
kind: requirement == .localPackage ? .local : .remote
2230
)
@@ -28,8 +36,8 @@ extension Manifest {
2836
public func dependencyConstraints(productFilter: ProductFilter, config: SwiftPMConfig) -> [RepositoryPackageConstraint] {
2937
return dependenciesRequired(for: productFilter).map({
3038
return RepositoryPackageConstraint(
31-
container: $0.declaration.createPackageRef(config: config),
32-
requirement: $0.declaration.requirement.toConstraintRequirement(),
39+
container: $0.createPackageRef(config: config),
40+
requirement: $0.requirement.toConstraintRequirement(),
3341
products: $0.productFilter)
3442
})
3543
}

Sources/PackageModel/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ add_library(PackageModel
1212
BuildSettings.swift
1313
Diagnostics.swift
1414
Manifest.swift
15-
Manifest/FilteredDependencyDescription.swift
1615
Manifest/PackageConditionDescription.swift
1716
Manifest/PackageDependencyDescription.swift
1817
Manifest/PlatformDescription.swift
@@ -27,9 +26,9 @@ add_library(PackageModel
2726
Product.swift
2827
Resource.swift
2928
Sources.swift
30-
Target.swift
3129
SupportedLanguageExtension.swift
3230
SwiftLanguageVersion.swift
31+
Target.swift
3332
ToolsVersion.swift)
3433
target_link_libraries(PackageModel PUBLIC
3534
TSCBasic

Sources/PackageModel/Manifest.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public final class Manifest: ObjectIdentifierProtocol {
8686
private var _requiredTargets: [ProductFilter: [TargetDescription]]
8787

8888
/// Dependencies required for building particular product filters.
89-
private var _requiredDependencies: [ProductFilter: [FilteredDependencyDescription]]
89+
private var _requiredDependencies: [ProductFilter: [PackageDependencyDescription]]
9090

9191
public init(
9292
name: String,
@@ -154,7 +154,7 @@ public final class Manifest: ObjectIdentifierProtocol {
154154
}
155155

156156
/// Returns the package dependencies required for a particular products filter.
157-
public func dependenciesRequired(for productFilter: ProductFilter) -> [FilteredDependencyDescription] {
157+
public func dependenciesRequired(for productFilter: ProductFilter) -> [PackageDependencyDescription] {
158158
// If we have already calcualted it, returned the cached value.
159159
if let dependencies = _requiredDependencies[productFilter] {
160160
return dependencies
@@ -194,7 +194,7 @@ public final class Manifest: ObjectIdentifierProtocol {
194194
public func dependenciesRequired(
195195
for targets: [TargetDescription],
196196
keepUnused: Bool = false
197-
) -> [FilteredDependencyDescription] {
197+
) -> [PackageDependencyDescription] {
198198

199199
var registry: (known: [String: ProductFilter], unknown: Set<String>) = ([:], [])
200200
let availablePackages = Set(dependencies.lazy.map({ $0.name }))
@@ -211,23 +211,23 @@ public final class Manifest: ObjectIdentifierProtocol {
211211
let unknown = registry.unknown
212212
if !registry.unknown.isEmpty {
213213
for package in availablePackages {
214-
associations[package, default: .specific([])].formUnion(.specific(unknown))
214+
associations[package, default: .nothing].formUnion(.specific(unknown))
215215
}
216216
}
217217

218218
return dependencies.compactMap { dependency in
219219
#if ENABLE_TARGET_BASED_DEPENDENCY_RESOLUTION
220220
if let filter = associations[dependency.name] {
221-
return FilteredDependencyDescription(declaration: dependency, productFilter: filter)
221+
return dependency.filtered(by: filter)
222222
} else if keepUnused {
223223
// Register that while the dependency was kept, no products are needed.
224-
return FilteredDependencyDescription(declaration: dependency, productFilter: .specific([]))
224+
return dependency.filtered(by: .nothing)
225225
} else {
226226
// Dependencies known to not have any relevant products are discarded.
227227
return nil
228228
}
229229
#else
230-
return FilteredDependencyDescription(declaration: dependency, productFilter: .everything)
230+
return dependency.filtered(by: .everything)
231231
#endif
232232
}
233233
}

Sources/PackageModel/Manifest/FilteredDependencyDescription.swift

Lines changed: 0 additions & 29 deletions
This file was deleted.

Sources/PackageModel/Manifest/PackageDependencyDescription.swift

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,53 @@ public struct PackageDependencyDescription: Equatable, Codable {
3030
}
3131
}
3232

33-
/// The name of the dependency explicitly defined in the manifest.
33+
/// The name of the package dependency explicitly defined in the manifest, if any.
3434
public let explicitName: String?
3535

36-
/// The name of the dependency, either explicitly defined in the manifest, or deduced from the URL.
36+
/// The name of the packagedependency,
37+
/// either explicitly defined in the manifest,
38+
/// or derived from the URL.
39+
///
40+
/// - SeeAlso: `explicitName`
41+
/// - SeeAlso: `url`
3742
public let name: String
3843

39-
/// The url of the dependency.
44+
/// The url of the package dependency.
4045
public let url: String
4146

4247
/// The dependency requirement.
4348
public let requirement: Requirement
4449

45-
/// Create a dependency.
46-
public init(name: String?, url: String, requirement: Requirement) {
50+
/// The products requested of the package dependency.
51+
public let productFilter: ProductFilter
52+
53+
/// Create a package dependency.
54+
public init(
55+
name: String? = nil,
56+
url: String,
57+
requirement: Requirement,
58+
productFilter: ProductFilter = .everything
59+
) {
60+
// FIXME: SwiftPM can't handle file URLs with file:// scheme so we need to
61+
// strip that. We need to design a URL data structure for SwiftPM.
62+
let filePrefix = "file://"
63+
let normalizedURL: String
64+
if url.hasPrefix(filePrefix) {
65+
normalizedURL = AbsolutePath(String(url.dropFirst(filePrefix.count))).pathString
66+
} else {
67+
normalizedURL = url
68+
}
69+
4770
self.explicitName = name
48-
self.name = name ?? PackageReference.computeDefaultName(fromURL: url)
49-
self.url = url
71+
self.name = name ?? PackageReference.computeDefaultName(fromURL: normalizedURL)
72+
self.url = normalizedURL
5073
self.requirement = requirement
74+
self.productFilter = productFilter
75+
}
76+
77+
/// Returns a new package dependency with the specified products.
78+
public func filtered(by productFilter: ProductFilter) -> PackageDependencyDescription {
79+
PackageDependencyDescription(name: explicitName, url: url, requirement: requirement, productFilter: productFilter)
5180
}
5281
}
5382

Sources/PackageModel/Product.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ public enum ProductFilter: Equatable, Hashable {
8989
/// A set of specific products requested by one or more client packages.
9090
case specific(Set<String>)
9191

92+
/// No products, targets, or tests are requested.
93+
public static var nothing: ProductFilter { .specific([]) }
94+
9295
public func union(_ other: ProductFilter) -> ProductFilter {
9396
switch self {
9497
case .everything:

Sources/SPMTestSupport/TestWorkspace.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public final class TestWorkspace {
188188
}
189189

190190
public struct PackageDependency {
191-
public typealias Requirement = PackageGraphRoot.PackageDependency.Requirement
191+
public typealias Requirement = PackageDependencyDescription.Requirement
192192

193193
public let name: String
194194
public let requirement: Requirement
@@ -200,12 +200,11 @@ public final class TestWorkspace {
200200
self.products = products
201201
}
202202

203-
fileprivate func convert(_ packagesDir: AbsolutePath, url: String) -> PackageGraphRootInput.PackageDependency {
204-
return PackageGraphRootInput.PackageDependency(
203+
fileprivate func convert(_ packagesDir: AbsolutePath, url: String) -> PackageDependencyDescription {
204+
return PackageDependencyDescription(
205205
url: url,
206206
requirement: requirement,
207-
productFilter: products,
208-
location: name
207+
productFilter: products
209208
)
210209
}
211210
}
@@ -306,7 +305,7 @@ public final class TestWorkspace {
306305

307306
public func checkPackageGraph(
308307
roots: [String] = [],
309-
dependencies: [PackageGraphRootInput.PackageDependency] = [],
308+
dependencies: [PackageDependencyDescription] = [],
310309
forceResolvedVersions: Bool = false,
311310
_ result: (PackageGraph, DiagnosticsEngine) -> ()
312311
) {

0 commit comments

Comments
 (0)