Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Sources/Basics/Version+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ extension Version {
try? self.init(versionString: tag, usesLenientParsing: true)
}
}

package func literalEqual(to other: Version) -> Bool {
self.major == other.major &&
self.minor == other.minor &&
self.patch == other.patch &&
self.prereleaseIdentifiers == other.prereleaseIdentifiers &&
self.buildMetadataIdentifiers == other.buildMetadataIdentifiers
}
}
5 changes: 4 additions & 1 deletion Sources/PackageGraph/PackageGraphRoot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ extension PackageDependency.SourceControl.Requirement {
return .revision(name)
case .exact(let version):
return .versionSet(.exact(version))
case .exactLiteral(let version):
return .versionSet(.exactLiteral(version))
}
}
}
Expand All @@ -222,7 +224,8 @@ extension PackageDependency.Registry.Requirement {
return .versionSet(.range(range))
case .exact(let version):
return .versionSet(.exact(version))
case .exactLiteral(let version):
return .versionSet(.exactLiteral(version))
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ struct DiagnosticReportBuilder {
switch term.requirement {
case .any:
return true
case .empty, .exact, .ranges:
case .empty, .exact, .exactLiteral, .ranges:
return false
case .range(let range):
// container expected to be cached at this point
Expand Down Expand Up @@ -321,6 +321,11 @@ struct DiagnosticReportBuilder {
return "root"
}
return "\(name) \(version)"
case .exactLiteral(let version):
if term.node == self.rootNode {
return "root"
}
return "\(name) \(version)"
case .range(let range):
// container expected to be cached at this point
guard normalizeRange, let container = try? provider.getCachedContainer(for: term.node.package) else {
Expand Down
13 changes: 11 additions & 2 deletions Sources/PackageGraph/Resolution/PubGrub/PartialSolution.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,18 @@ public struct PartialSolution {

/// Create a new decision assignment and add it to the partial solution's
/// list of known assignments.
public mutating func decide(_ node: DependencyResolutionNode, at version: Version) {
public mutating func decide(
_ node: DependencyResolutionNode,
at version: Version,
requirement: VersionSetSpecifier? = nil
) {
self.decisions[node] = version
let term = Term(node, .exact(version))
let decisionRequirement = requirement ?? .exact(version)
precondition(
decisionRequirement.isExact,
"Cannot create a decision assignment with a non-exact version selection: \(decisionRequirement)"
)
let term = Term(node, decisionRequirement)
let decision = Assignment.decision(term, decisionLevel: self.decisionLevel)
self.assignments.append(decision)
self.register(decision)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,16 @@ public struct PubGrubDependencyResolver {
}
}

func decide(_ node: DependencyResolutionNode, at version: Version) {
let term = Term(node, .exact(version))
func decide(
_ node: DependencyResolutionNode,
at version: Version,
requirement: VersionSetSpecifier? = nil
) {
let decisionRequirement = requirement ?? .exact(version)
let term = Term(node, decisionRequirement)
self.lock.withLock {
assert(term.isValidDecision(for: self.solution))
self.solution.decide(node, at: version)
self.solution.decide(node, at: version, requirement: decisionRequirement)
}
}

Expand Down Expand Up @@ -250,6 +255,8 @@ public struct PubGrubDependencyResolver {
switch assignment.term.requirement {
case .exact(let version):
boundVersion = .version(version)
case .exactLiteral(let version):
boundVersion = .version(version)
case .range, .any, .empty, .ranges:
throw InternalError("unexpected requirement value for assignment \(assignment.term)")
}
Expand Down Expand Up @@ -764,7 +771,13 @@ public struct PubGrubDependencyResolver {
// Decide this version if there was no conflict with its dependencies.
if !haveConflict {
self.delegate?.didResolve(term: pkgTerm, version: version, duration: start.distance(to: .now()))
state.decide(pkgTerm.node, at: version)
let decisionRequirement: VersionSetSpecifier = switch pkgTerm.requirement {
case .exactLiteral:
.exactLiteral(version)
case .exact, .range, .ranges, .any, .empty:
.exact(version)
}
state.decide(pkgTerm.node, at: version, requirement: decisionRequirement)
}

return pkgTerm.node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,14 @@ final class PubGrubPackageContainer {
if let pinnedVersion = self.pinnedVersion {
if versionSet.contains(pinnedVersion) {
if !self.underlying.shouldInvalidatePinnedVersions {
versionSet = .exact(pinnedVersion)
versionSet = .exactLiteral(pinnedVersion)
} else {
// Make sure the pinned version is still available
let version = try await self.underlying.versionsDescending().first { pinnedVersion == $0 }
let version = try await self.underlying.versionsDescending().first {
pinnedVersion.buildMetadataIdentifiers.isEmpty
? pinnedVersion == $0
: pinnedVersion.description == $0.description
}
if version != nil {
return version
}
Expand Down
Loading