Skip to content

Commit e37c93b

Browse files
committed
* rename CanonicalPackageIdentity as CanonicalPackageLocation and use it to compare locations where required
* rename LegacyPackageIdentity as PackageIdentityParser and simplify how identity parsing is wired (removed unusued complexity)
1 parent 23e7c75 commit e37c93b

File tree

10 files changed

+114
-169
lines changed

10 files changed

+114
-169
lines changed

Sources/PackageCollections/PackageCollections.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ public struct PackageCollections: PackageCollectionsProtocol {
571571
let matches: [PackageCollectionsModel.Package]
572572
if let location = location {
573573
// A package identity can be associated with multiple repository URLs
574-
matches = packagesCollections.packages.filter { CanonicalPackageIdentity($0.location) == CanonicalPackageIdentity(location) }
574+
matches = packagesCollections.packages.filter { CanonicalPackageLocation($0.location) == CanonicalPackageLocation(location) }
575575
}
576576
else {
577577
matches = packagesCollections.packages

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -236,21 +236,7 @@ private func createResolvedPackages(
236236

237237
// Establish the manifest-declared package dependencies.
238238
package.manifest.dependenciesRequired(for: packageBuilder.productFilter).forEach { dependency in
239-
// FIXME: change this validation logic to use identity instead of location
240-
let dependencyLocation: String
241-
switch dependency {
242-
case .fileSystem(let settings):
243-
dependencyLocation = settings.path.pathString
244-
case .sourceControl(let settings):
245-
switch settings.location {
246-
case .local(let path):
247-
dependencyLocation = path.pathString
248-
case .remote(let url):
249-
dependencyLocation = url.absoluteString
250-
}
251-
case .registry(let settings):
252-
dependencyLocation = settings.identity.description
253-
}
239+
let dependencyPackageRef = dependency.createPackageRef()
254240

255241
// Otherwise, look it up by its identity.
256242
if let resolvedPackage = packagesByIdentity[dependency.identity] {
@@ -260,7 +246,7 @@ private func createResolvedPackages(
260246
guard dependencies[resolvedPackage.package.identity] == nil else {
261247
let error = PackageGraphError.dependencyAlreadySatisfiedByIdentifier(
262248
package: package.identity.description,
263-
dependencyLocation: dependencyLocation,
249+
dependencyLocation: dependencyPackageRef.locationString,
264250
otherDependencyURL: resolvedPackage.package.manifest.packageLocation,
265251
identity: dependency.identity)
266252
return packageObservabilityScope.emit(error)
@@ -269,10 +255,10 @@ private func createResolvedPackages(
269255
// check if the resolved package location is the same as the dependency one
270256
// if not, this means that the dependencies share the same identity
271257
// which only allowed when overriding
272-
if !LocationComparator.areEqual(resolvedPackage.package.manifest.packageLocation, dependencyLocation) && !resolvedPackage.allowedToOverride {
258+
if resolvedPackage.package.manifest.packageKind.canonicalLocation != dependencyPackageRef.canonicalLocation && !resolvedPackage.allowedToOverride {
273259
let error = PackageGraphError.dependencyAlreadySatisfiedByIdentifier(
274260
package: package.identity.description,
275-
dependencyLocation: dependencyLocation,
261+
dependencyLocation: dependencyPackageRef.locationString,
276262
otherDependencyURL: resolvedPackage.package.manifest.packageLocation,
277263
identity: dependency.identity)
278264
// 9/2021 this is currently emitting a warning only to support
@@ -291,7 +277,7 @@ private func createResolvedPackages(
291277
if let previouslyResolvedPackage = dependenciesByNameForTargetDependencyResolution[explicitDependencyName] {
292278
let error = PackageGraphError.dependencyAlreadySatisfiedByName(
293279
package: package.identity.description,
294-
dependencyLocation: dependencyLocation,
280+
dependencyLocation: dependencyPackageRef.locationString,
295281
otherDependencyURL: previouslyResolvedPackage.package.manifest.packageLocation,
296282
name: explicitDependencyName)
297283
return packageObservabilityScope.emit(error)
@@ -302,7 +288,7 @@ private func createResolvedPackages(
302288
if let previouslyResolvedPackage = dependenciesByNameForTargetDependencyResolution[dependency.identity.description] {
303289
let error = PackageGraphError.dependencyAlreadySatisfiedByName(
304290
package: package.identity.description,
305-
dependencyLocation: dependencyLocation,
291+
dependencyLocation: dependencyPackageRef.locationString,
306292
otherDependencyURL: previouslyResolvedPackage.package.manifest.packageLocation,
307293
name: dependency.identity.description)
308294
return packageObservabilityScope.emit(error)
@@ -674,22 +660,3 @@ fileprivate func findCycle(
674660
// Couldn't find any cycle in the graph.
675661
return nil
676662
}
677-
678-
679-
// TODO: model package location better / encapsulate into a new type (PackageLocation) so that such comparison is reusable
680-
// additionally move and rename CanonicalPackageIdentity to become a detail function of the PackageLocation abstraction, as it is not used otherwise
681-
struct LocationComparator {
682-
static func areEqual(_ lhs: String, _ rhs: String) -> Bool {
683-
if lhs == rhs {
684-
return true
685-
}
686-
687-
let canonicalLHS = CanonicalPackageIdentity(lhs)
688-
let canonicalRHS = CanonicalPackageIdentity(rhs)
689-
if canonicalLHS == canonicalRHS {
690-
return true
691-
}
692-
693-
return false
694-
}
695-
}

Sources/PackageModel/Manifest/PackageDependencyDescription.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ public enum PackageDependency: Equatable {
7272
public var nameForTargetDependencyResolutionOnly: String {
7373
switch self {
7474
case .fileSystem(let settings):
75-
return settings.nameForTargetDependencyResolutionOnly ?? LegacyPackageIdentity.computeDefaultName(fromPath: settings.path)
75+
return settings.nameForTargetDependencyResolutionOnly ?? PackageIdentityParser.computeDefaultName(fromPath: settings.path)
7676
case .sourceControl(let settings):
7777
switch settings.location {
7878
case .local(let path):
79-
return settings.nameForTargetDependencyResolutionOnly ?? LegacyPackageIdentity.computeDefaultName(fromPath: path)
79+
return settings.nameForTargetDependencyResolutionOnly ?? PackageIdentityParser.computeDefaultName(fromPath: path)
8080
case .remote(let url):
81-
return settings.nameForTargetDependencyResolutionOnly ?? LegacyPackageIdentity.computeDefaultName(fromURL: url)
81+
return settings.nameForTargetDependencyResolutionOnly ?? PackageIdentityParser.computeDefaultName(fromURL: url)
8282
}
8383
case .registry:
8484
return self.identity.description

Sources/PackageModel/PackageIdentity.swift

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,8 @@ import Foundation
1212
import TSCBasic
1313
import TSCUtility
1414

15-
/// When set to `false`,
16-
/// `PackageIdentity` uses the canonical location of package dependencies as its identity.
17-
/// Otherwise, only the last path component is used to identify package dependencies.
18-
public var _useLegacyIdentities: Bool = true {
19-
willSet {
20-
PackageIdentity.provider = newValue ? LegacyPackageIdentity.self : CanonicalPackageIdentity.self
21-
}
22-
}
23-
24-
internal protocol PackageIdentityProvider: CustomStringConvertible {
25-
init(_ string: String)
26-
}
27-
2815
/// The canonical identifier for a package, based on its source location.
2916
public struct PackageIdentity: CustomStringConvertible {
30-
/// The underlying type used to create package identities.
31-
internal static var provider: PackageIdentityProvider.Type = LegacyPackageIdentity.self
32-
3317
/// A textual representation of this instance.
3418
public let description: String
3519

@@ -49,13 +33,13 @@ public struct PackageIdentity: CustomStringConvertible {
4933
/// - Parameter urlString: The package's URL.
5034
// FIXME: deprecate this
5135
public init(urlString: String) {
52-
self.description = Self.provider.init(urlString).description
36+
self.description = PackageIdentityParser(urlString).description
5337
}
5438

5539
/// Creates a package identity from a file path.
5640
/// - Parameter path: An absolute path to the package.
5741
public init(path: AbsolutePath) {
58-
self.description = Self.provider.init(path.pathString).description
42+
self.description = PackageIdentityParser(path.pathString).description
5943
}
6044

6145
/// Creates a plain package identity for a root package
@@ -282,7 +266,7 @@ extension PackageIdentity {
282266

283267
// MARK: -
284268

285-
struct LegacyPackageIdentity: PackageIdentityProvider, Equatable {
269+
struct PackageIdentityParser {
286270
/// A textual representation of this instance.
287271
public let description: String
288272

@@ -329,7 +313,7 @@ struct LegacyPackageIdentity: PackageIdentityProvider, Equatable {
329313
}
330314
}
331315

332-
/// A canonicalized package identity.
316+
/// A canonicalized package location.
333317
///
334318
/// A package may declare external packages as dependencies in its manifest.
335319
/// Each external package is uniquely identified by the location of its source code.
@@ -400,7 +384,7 @@ struct LegacyPackageIdentity: PackageIdentityProvider, Equatable {
400384
/// ```
401385
/// file:///Users/mona/LinkedList → /Users/mona/LinkedList
402386
/// ```
403-
public struct CanonicalPackageIdentity: PackageIdentityProvider, Equatable {
387+
public struct CanonicalPackageLocation: Equatable {
404388
/// A textual representation of this instance.
405389
public let description: String
406390

Sources/PackageModel/PackageReference.swift

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public struct PackageReference {
3434
/// A package from a registry.
3535
case registry(PackageIdentity)
3636

37-
// FIXME: we should not need this
37+
// FIXME: we should not need this once we migrate off URLs
3838
//@available(*, deprecated)
3939
public var locationString: String {
4040
switch self {
@@ -52,6 +52,12 @@ public struct PackageReference {
5252
}
5353
}
5454

55+
// FIXME: we should not need this once we migrate off URLs
56+
//@available(*, deprecated)
57+
public var canonicalLocation: CanonicalPackageLocation {
58+
return CanonicalPackageLocation(self.locationString)
59+
}
60+
5561
public var description: String {
5662
switch self {
5763
case .root(let path):
@@ -92,12 +98,18 @@ public struct PackageReference {
9298
/// The location of the package.
9399
///
94100
/// This could be a remote repository, local repository or local package.
95-
// FIXME: we should not need this
101+
// FIXME: we should not need this once we migrate off URLs
96102
//@available(*, deprecated)
97103
public var locationString: String {
98104
self.kind.locationString
99105
}
100106

107+
// FIXME: we should not need this once we migrate off URLs
108+
//@available(*, deprecated)
109+
public var canonicalLocation: CanonicalPackageLocation {
110+
self.kind.canonicalLocation
111+
}
112+
101113
/// The kind of package: root, local, or remote.
102114
public let kind: Kind
103115

@@ -107,13 +119,13 @@ public struct PackageReference {
107119
self.kind = kind
108120
switch kind {
109121
case .root(let path):
110-
self.deprecatedName = name ?? LegacyPackageIdentity.computeDefaultName(fromPath: path)
122+
self.deprecatedName = name ?? PackageIdentityParser.computeDefaultName(fromPath: path)
111123
case .fileSystem(let path):
112-
self.deprecatedName = name ?? LegacyPackageIdentity.computeDefaultName(fromPath: path)
124+
self.deprecatedName = name ?? PackageIdentityParser.computeDefaultName(fromPath: path)
113125
case .localSourceControl(let path):
114-
self.deprecatedName = name ?? LegacyPackageIdentity.computeDefaultName(fromPath: path)
126+
self.deprecatedName = name ?? PackageIdentityParser.computeDefaultName(fromPath: path)
115127
case .remoteSourceControl(let url):
116-
self.deprecatedName = name ?? LegacyPackageIdentity.computeDefaultName(fromURL: url)
128+
self.deprecatedName = name ?? PackageIdentityParser.computeDefaultName(fromURL: url)
117129
case .registry(let identity):
118130
// FIXME: this is a placeholder
119131
self.deprecatedName = name ?? identity.description
@@ -154,7 +166,7 @@ extension PackageReference: Equatable {
154166

155167
// TODO: consider rolling into Equatable
156168
public func equalsIncludingLocation(_ other: PackageReference) -> Bool {
157-
return self.identity == other.identity && self.kind.locationString.caseInsensitiveCompare(other.kind.locationString) == .orderedSame
169+
return self.identity == other.identity && self.canonicalLocation == other.canonicalLocation
158170
}
159171
}
160172

Sources/Workspace/Workspace.swift

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,13 +1740,13 @@ extension Workspace {
17401740
let dependenciesToLoad = dependenciesRequired.map{ $0.createPackageRef() }.filter { !loadedManifests.keys.contains($0.identity) }
17411741
let dependenciesManifests = try temp_await { self.loadManagedManifests(for: dependenciesToLoad, observabilityScope: observabilityScope, completion: $0) }
17421742
dependenciesManifests.forEach { loadedManifests[$0.key] = $0.value }
1743-
return pair.item.dependenciesRequired(for: pair.key.productFilter).compactMap{ dependency in
1743+
return pair.item.dependenciesRequired(for: pair.key.productFilter).compactMap { dependency in
17441744
loadedManifests[dependency.identity].flatMap {
17451745
// we also compare the location as this function may attempt to load
17461746
// dependencies that have the same identity but from a different location
17471747
// which is an error case we diagnose an report about in the GraphLoading part which
17481748
// is prepared to handle the case where not all manifest are available
1749-
$0.packageLocation.caseInsensitiveCompare(dependency.locationString) == .orderedSame ?
1749+
$0.packageKind.canonicalLocation == dependency.createPackageRef().canonicalLocation ?
17501750
KeyedPair($0, key: Key(identity: dependency.identity, productFilter: dependency.productFilter)) : nil
17511751
}
17521752
}
@@ -3372,9 +3372,8 @@ extension Workspace {
33723372
try workingCopy.checkout(revision: checkoutState.revision)
33733373
try? fileSystem.chmod(.userUnWritable, path: checkoutPath, options: [.recursive, .onlyFiles])
33743374

3375-
print("********************* adding \(package.locationString) to managed deps")
3376-
3377-
// Write the state record.
3375+
// Record the new state.
3376+
observabilityScope.emit(debug: "adding '\(package.identity)' (\(package.locationString)) to managed dependencies")
33783377
self.state.dependencies.add(
33793378
try .sourceControlCheckout(
33803379
packageRef: package,
@@ -3532,8 +3531,8 @@ extension Workspace {
35323531
)
35333532
}
35343533

3535-
// TODO: make download read-only?
3536-
3534+
// Record the new state.
3535+
observabilityScope.emit(debug: "adding '\(package.identity)' (\(package.locationString)) to managed dependencies")
35373536
self.state.dependencies.add(
35383537
try .registryDownload(
35393538
packageRef: package,

0 commit comments

Comments
 (0)