Skip to content

Commit d968485

Browse files
authored
NFC: cleanup usage of registry identifiers (swiftlang#6178)
motivation: make code easier to reason about changes: * deprecate scopeAndName accessor in favour of .registry one * define RegistryIdentity struct to encapsulate such identity * update call sites and tests * update error messages
1 parent 36dc7e6 commit d968485

File tree

15 files changed

+245
-192
lines changed

15 files changed

+245
-192
lines changed

Sources/PackageDescription/PackageDependency.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ extension Package.Dependency {
683683
) -> Package.Dependency {
684684
let pattern = #"\A[a-zA-Z\d](?:[a-zA-Z\d]|-(?=[a-zA-Z\d])){0,38}\.[a-zA-Z0-9](?:[a-zA-Z0-9]|[-_](?=[a-zA-Z0-9])){0,99}\z"#
685685
if id.range(of: pattern, options: .regularExpression) == nil {
686-
errors.append("Invalid package identifier: \(id)")
686+
errors.append("Invalid package identifier: '\(id)'")
687687
}
688688

689689
return .init(id: id, requirement: requirement)

Sources/PackageGraph/DependencyMirrors.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public final class DependencyMirrors: Equatable {
160160
}
161161

162162
private func parseLocation(_ location: String) throws -> PackageIdentity {
163-
if PackageIdentity.plain(location).scopeAndName != nil {
163+
if PackageIdentity.plain(location).isRegistry {
164164
return PackageIdentity.plain(location)
165165
} else if let path = try? AbsolutePath(validating: location) {
166166
return PackageIdentity(path: path)

Sources/PackageLoading/ManifestJSONParser.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ enum ManifestJSONParser {
207207
var location = try sanitizeDependencyLocation(fileSystem: fileSystem, packageKind: packageKind, dependencyLocation: location)
208208
// location mapping (aka mirrors) if any
209209
location = identityResolver.mappedLocation(for: location)
210-
if PackageIdentity.plain(location).scopeAndName != nil {
210+
if PackageIdentity.plain(location).isRegistry {
211211
// re-mapped to registry
212212
let identity = PackageIdentity.plain(location)
213213
let registryRequirement: PackageDependency.Registry.Requirement
@@ -257,7 +257,7 @@ enum ManifestJSONParser {
257257
) throws -> PackageDependency {
258258
// location mapping (aka mirrors) if any
259259
let location = identityResolver.mappedLocation(for: identity.description)
260-
if PackageIdentity.plain(location).scopeAndName != nil {
260+
if PackageIdentity.plain(location).isRegistry {
261261
// re-mapped to registry
262262
let identity = PackageIdentity.plain(location)
263263
return .registry(

Sources/PackageMetadata/PackageMetadata.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public struct PackageSearchClient {
9999
callback: @escaping (Result<[Package], Error>) -> Void
100100
) {
101101
let identity = PackageIdentity.plain(query)
102-
let isRegistryIdentity = identity.scopeAndName != nil
103102

104103
// Search the package index and collections for a search term.
105104
let search = { (error: Error?) -> Void in
@@ -164,7 +163,7 @@ public struct PackageSearchClient {
164163
// package metadata for it from the configured registry. If there are any errors
165164
// or the search term does not work as a registry identity, we will fall back on
166165
// `fetchStandalonePackageByURL`.
167-
if isRegistryIdentity {
166+
if identity.isRegistry {
168167
return self.registryClient.getPackageMetadata(package: identity, observabilityScope: observabilityScope, callbackQueue: DispatchQueue.sharedConcurrent) { result in
169168
do {
170169
let metadata = try result.get()

Sources/PackageModel/PackageIdentity.swift

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,39 +49,59 @@ public struct PackageIdentity: CustomStringConvertible, Sendable {
4949
PackageIdentity(value)
5050
}
5151

52-
// TODO: formalize package registry identifier
52+
@available(*, deprecated, message: "use .registry instead")
5353
public var scopeAndName: (scope: Scope, name: Name)? {
54-
let components = description.split(separator: ".", maxSplits: 1, omittingEmptySubsequences: true)
54+
self.registry.flatMap { (scope: $0.scope, name: $0.name) }
55+
}
56+
57+
public var registry: RegistryIdentity? {
58+
let components = self.description.split(separator: ".", maxSplits: 1, omittingEmptySubsequences: true)
5559
guard components.count == 2,
5660
let scope = Scope(components.first),
5761
let name = Name(components.last)
58-
else { return .none }
62+
else {
63+
return .none
64+
}
65+
66+
return RegistryIdentity(
67+
scope: scope,
68+
name: name,
69+
underlying: self
70+
)
71+
}
72+
73+
public var isRegistry: Bool {
74+
self.registry != nil
75+
}
5976

60-
return (scope: scope, name: name)
77+
public struct RegistryIdentity {
78+
public let scope: PackageIdentity.Scope
79+
public let name: PackageIdentity.Name
80+
public let underlying: PackageIdentity
6181
}
6282
}
6383

6484
extension PackageIdentity: Equatable, Comparable {
6585
private func compare(to other: PackageIdentity) -> ComparisonResult {
66-
return self.description.caseInsensitiveCompare(other.description)
86+
self.description.caseInsensitiveCompare(other.description)
6787
}
6888

6989
public static func == (lhs: PackageIdentity, rhs: PackageIdentity) -> Bool {
70-
return lhs.compare(to: rhs) == .orderedSame
90+
lhs.compare(to: rhs) == .orderedSame
7191
}
7292

7393
public static func < (lhs: PackageIdentity, rhs: PackageIdentity) -> Bool {
74-
return lhs.compare(to: rhs) == .orderedAscending
94+
lhs.compare(to: rhs) == .orderedAscending
7595
}
7696

7797
public static func > (lhs: PackageIdentity, rhs: PackageIdentity) -> Bool {
78-
return lhs.compare(to: rhs) == .orderedDescending
98+
lhs.compare(to: rhs) == .orderedDescending
7999
}
80100
}
81101

82102
extension PackageIdentity: Hashable {
83103
public func hash(into hasher: inout Hasher) {
84-
hasher.combine(description.lowercased())
104+
hasher.combine(self.description.lowercased())
85105
}
86106
}
87107

@@ -116,9 +136,9 @@ extension PackageIdentity {
116136

117137
for (index, character) in zip(description.indices, description) {
118138
guard character.isASCII,
119-
character.isLetter ||
120-
character.isNumber ||
121-
character == "-"
139+
character.isLetter ||
140+
character.isNumber ||
141+
character == "-"
122142
else {
123143
throw StringError("A package scope consists of alphanumeric characters and hyphens.")
124144
}
@@ -154,25 +174,25 @@ extension PackageIdentity {
154174

155175
private func compare(to other: Scope) -> ComparisonResult {
156176
// Package scopes are case-insensitive (for example, `mona` ≍ `MONA`).
157-
return self.description.caseInsensitiveCompare(other.description)
177+
self.description.caseInsensitiveCompare(other.description)
158178
}
159179

160180
public static func == (lhs: Scope, rhs: Scope) -> Bool {
161-
return lhs.compare(to: rhs) == .orderedSame
181+
lhs.compare(to: rhs) == .orderedSame
162182
}
163183

164184
public static func < (lhs: Scope, rhs: Scope) -> Bool {
165-
return lhs.compare(to: rhs) == .orderedAscending
185+
lhs.compare(to: rhs) == .orderedAscending
166186
}
167187

168188
public static func > (lhs: Scope, rhs: Scope) -> Bool {
169-
return lhs.compare(to: rhs) == .orderedDescending
189+
lhs.compare(to: rhs) == .orderedDescending
170190
}
171191

172192
// MARK: - Hashable
173193

174194
public func hash(into hasher: inout Hasher) {
175-
hasher.combine(description.lowercased())
195+
hasher.combine(self.description.lowercased())
176196
}
177197

178198
// MARK: - ExpressibleByStringLiteral
@@ -197,10 +217,10 @@ extension PackageIdentity {
197217

198218
for (index, character) in zip(description.indices, description) {
199219
guard character.isASCII,
200-
character.isLetter ||
201-
character.isNumber ||
202-
character == "-" ||
203-
character == "_"
220+
character.isLetter ||
221+
character.isNumber ||
222+
character == "-" ||
223+
character == "_"
204224
else {
205225
throw StringError("A package name consists of alphanumeric characters, underscores, and hyphens.")
206226
}
@@ -236,25 +256,25 @@ extension PackageIdentity {
236256

237257
private func compare(to other: Name) -> ComparisonResult {
238258
// Package scopes are case-insensitive (for example, `LinkedList` ≍ `LINKEDLIST`).
239-
return self.description.caseInsensitiveCompare(other.description)
259+
self.description.caseInsensitiveCompare(other.description)
240260
}
241261

242262
public static func == (lhs: Name, rhs: Name) -> Bool {
243-
return lhs.compare(to: rhs) == .orderedSame
263+
lhs.compare(to: rhs) == .orderedSame
244264
}
245265

246266
public static func < (lhs: Name, rhs: Name) -> Bool {
247-
return lhs.compare(to: rhs) == .orderedAscending
267+
lhs.compare(to: rhs) == .orderedAscending
248268
}
249269

250270
public static func > (lhs: Name, rhs: Name) -> Bool {
251-
return lhs.compare(to: rhs) == .orderedDescending
271+
lhs.compare(to: rhs) == .orderedDescending
252272
}
253273

254274
// MARK: - Hashable
255275

256276
public func hash(into hasher: inout Hasher) {
257-
hasher.combine(description.lowercased())
277+
hasher.combine(self.description.lowercased())
258278
}
259279

260280
// MARK: - ExpressibleByStringLiteral
@@ -289,9 +309,9 @@ struct PackageIdentityParser {
289309
/// Compute the default name of a package given its location.
290310
public static func computeDefaultName(fromLocation url: String) -> String {
291311
#if os(Windows)
292-
let isSeparator : (Character) -> Bool = { $0 == "/" || $0 == "\\" }
312+
let isSeparator: (Character) -> Bool = { $0 == "/" || $0 == "\\" }
293313
#else
294-
let isSeparator : (Character) -> Bool = { $0 == "/" }
314+
let isSeparator: (Character) -> Bool = { $0 == "/" }
295315
#endif
296316

297317
// Get the last path component of the URL.
@@ -303,7 +323,7 @@ struct PackageIdentityParser {
303323

304324
let separatorIndex = url[..<endIndex].lastIndex(where: isSeparator)
305325
let startIndex = separatorIndex.map { url.index(after: $0) } ?? url.startIndex
306-
var lastComponent = url[startIndex..<endIndex]
326+
var lastComponent = url[startIndex ..< endIndex]
307327

308328
// Strip `.git` suffix if present.
309329
if lastComponent.hasSuffix(".git") {
@@ -443,8 +463,8 @@ fileprivate let isSeparator: (Character) -> Bool = { $0 == "/" || $0 == "\\" }
443463
fileprivate let isSeparator: (Character) -> Bool = { $0 == "/" }
444464
#endif
445465

446-
private extension Character {
447-
var isDigit: Bool {
466+
extension Character {
467+
fileprivate var isDigit: Bool {
448468
switch self {
449469
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
450470
return true
@@ -453,31 +473,31 @@ private extension Character {
453473
}
454474
}
455475

456-
var isAllowedInURLScheme: Bool {
457-
return isLetter || self.isDigit || self == "+" || self == "-" || self == "."
476+
fileprivate var isAllowedInURLScheme: Bool {
477+
isLetter || self.isDigit || self == "+" || self == "-" || self == "."
458478
}
459479
}
460480

461-
private extension String {
481+
extension String {
462482
@discardableResult
463-
mutating func removePrefixIfPresent<T: StringProtocol>(_ prefix: T) -> Bool {
483+
private mutating func removePrefixIfPresent<T: StringProtocol>(_ prefix: T) -> Bool {
464484
guard hasPrefix(prefix) else { return false }
465485
removeFirst(prefix.count)
466486
return true
467487
}
468488

469489
@discardableResult
470-
mutating func removeSuffixIfPresent<T: StringProtocol>(_ suffix: T) -> Bool {
490+
fileprivate mutating func removeSuffixIfPresent<T: StringProtocol>(_ suffix: T) -> Bool {
471491
guard hasSuffix(suffix) else { return false }
472492
removeLast(suffix.count)
473493
return true
474494
}
475495

476496
@discardableResult
477-
mutating func dropSchemeComponentPrefixIfPresent() -> String? {
497+
fileprivate mutating func dropSchemeComponentPrefixIfPresent() -> String? {
478498
if let rangeOfDelimiter = range(of: "://"),
479499
self[startIndex].isLetter,
480-
self[..<rangeOfDelimiter.lowerBound].allSatisfy({ $0.isAllowedInURLScheme })
500+
self[..<rangeOfDelimiter.lowerBound].allSatisfy(\.isAllowedInURLScheme)
481501
{
482502
defer { self.removeSubrange(..<rangeOfDelimiter.upperBound) }
483503

@@ -488,7 +508,7 @@ private extension String {
488508
}
489509

490510
@discardableResult
491-
mutating func dropUserinfoSubcomponentPrefixIfPresent() -> (user: String, password: String?)? {
511+
fileprivate mutating func dropUserinfoSubcomponentPrefixIfPresent() -> (user: String, password: String?)? {
492512
if let indexOfAtSign = firstIndex(of: "@"),
493513
let indexOfFirstPathComponent = firstIndex(where: isSeparator),
494514
indexOfAtSign < indexOfFirstPathComponent
@@ -508,7 +528,7 @@ private extension String {
508528
}
509529

510530
@discardableResult
511-
mutating func removePortComponentIfPresent() -> Bool {
531+
fileprivate mutating func removePortComponentIfPresent() -> Bool {
512532
if let indexOfFirstPathComponent = firstIndex(where: isSeparator),
513533
let startIndexOfPort = firstIndex(of: ":"),
514534
startIndexOfPort < endIndex,
@@ -523,7 +543,7 @@ private extension String {
523543
}
524544

525545
@discardableResult
526-
mutating func removeFragmentComponentIfPresent() -> Bool {
546+
fileprivate mutating func removeFragmentComponentIfPresent() -> Bool {
527547
if let index = firstIndex(of: "#") {
528548
self.removeSubrange(index...)
529549
}
@@ -532,7 +552,7 @@ private extension String {
532552
}
533553

534554
@discardableResult
535-
mutating func removeQueryComponentIfPresent() -> Bool {
555+
fileprivate mutating func removeQueryComponentIfPresent() -> Bool {
536556
if let index = firstIndex(of: "?") {
537557
self.removeSubrange(index...)
538558
}
@@ -541,7 +561,7 @@ private extension String {
541561
}
542562

543563
@discardableResult
544-
mutating func replaceFirstOccurenceIfPresent<T: StringProtocol, U: StringProtocol>(
564+
fileprivate mutating func replaceFirstOccurenceIfPresent<T: StringProtocol, U: StringProtocol>(
545565
of string: T,
546566
before index: Index? = nil,
547567
with replacement: U
@@ -556,4 +576,3 @@ private extension String {
556576
return true
557577
}
558578
}
559-

0 commit comments

Comments
 (0)