Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

update the resolved file format #3717

Merged
merged 1 commit into from
Sep 8, 2021
Merged
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
99 changes: 75 additions & 24 deletions Sources/PackageGraph/PinsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,22 @@ fileprivate struct PinsStorage {
return try self.fileSystem.withLock(on: self.lockFilePath, type: .shared) {
let version = try self.decoder.decode(path: self.path, fileSystem: self.fileSystem, as: Version.self)
switch version.version {
case 1:
case V1.version:
let v1 = try decoder.decode(path: self.path, fileSystem: self.fileSystem, as: V1.self)
return try v1.object.pins.map{ try PinsStore.Pin($0, mirrors: mirrors) }.reduce(into: [PackageIdentity: PinsStore.Pin]()) { partial, iterator in
if partial.keys.contains(iterator.packageRef.identity) {
throw StringError("duplicated entry for package \"\(iterator.packageRef.name)\"")
}
partial[iterator.packageRef.identity] = iterator
}
case V2.version:
let v2 = try decoder.decode(path: self.path, fileSystem: self.fileSystem, as: V2.self)
return try v2.pins.map{ try PinsStore.Pin($0, mirrors: mirrors) }.reduce(into: [PackageIdentity: PinsStore.Pin]()) { partial, iterator in
if partial.keys.contains(iterator.packageRef.identity) {
throw StringError("duplicated entry for package \"\(iterator.packageRef.identity)\"")
}
partial[iterator.packageRef.identity] = iterator
}
default:
throw InternalError("unknown RepositoryManager version: \(version)")
}
Expand All @@ -150,7 +158,7 @@ fileprivate struct PinsStorage {
return
}

let container = V1(pins: pins, mirrors: mirrors)
let container = V2(pins: pins, mirrors: mirrors)
let data = try self.encoder.encode(container)
try self.fileSystem.writeFileContents(self.path, data: data)
}
Expand All @@ -172,11 +180,13 @@ fileprivate struct PinsStorage {

// v1 storage format
struct V1: Codable {
static let version = 1

let version: Int
let object: Container

init (pins: PinsStore.PinsMap, mirrors: DependencyMirrors) {
self.version = 1
self.version = Self.version
self.object = .init(
pins: pins.values
.sorted(by: { $0.packageRef.identity < $1.packageRef.identity })
Expand All @@ -200,27 +210,55 @@ fileprivate struct PinsStorage {
self.state = .init(pin.state)
}
}
}

struct CheckoutInfo: Codable {
let revision: String
let branch: String?
let version: String?

init(_ state: CheckoutState) {
switch state {
case .version(let version, let revision):
self.version = version.description
self.branch = nil
self.revision = revision.identifier
case .branch(let branch, let revision):
self.version = nil
self.branch = branch
self.revision = revision.identifier
case .revision(let revision):
self.version = nil
self.branch = nil
self.revision = revision.identifier
}
// v2 storage format
struct V2: Codable {
static let version = 2

let version: Int
let pins: [Pin]

init (pins: PinsStore.PinsMap, mirrors: DependencyMirrors) {
self.version = Self.version
self.pins = pins.values
.sorted(by: { $0.packageRef.identity < $1.packageRef.identity })
.map{ Pin($0, mirrors: mirrors) }
}

struct Pin: Codable {
let identity: PackageIdentity
let location: String
let state: CheckoutInfo

init(_ pin: PinsStore.Pin, mirrors: DependencyMirrors) {
self.identity = pin.packageRef.identity
// rdar://52529014, rdar://52529011: pin file should store the original location but remap when loading
self.location = mirrors.originalURL(for: pin.packageRef.location) ?? pin.packageRef.location
self.state = .init(pin.state)
}
}
}

struct CheckoutInfo: Codable {
let revision: String
let branch: String?
let version: String?

init(_ state: CheckoutState) {
switch state {
case .version(let version, let revision):
self.version = version.description
self.branch = nil
self.revision = revision.identifier
case .branch(let branch, let revision):
self.version = nil
self.branch = branch
self.revision = revision.identifier
case .revision(let revision):
self.version = nil
self.branch = nil
self.revision = revision.identifier
}
}
}
Expand All @@ -242,8 +280,21 @@ extension PinsStore.Pin {
}
}

extension PinsStore.Pin {
fileprivate init(_ pin: PinsStorage.V2.Pin, mirrors: DependencyMirrors) throws {
// rdar://52529014, rdar://52529011: pin file should store the original location but remap when loading
let url = mirrors.effectiveURL(for: pin.location)
let identity = pin.identity
let packageRef = PackageReference.remote(identity: identity, location: url)
self.init(
packageRef: packageRef,
state: try .init(pin.state)
)
}
}

extension CheckoutState {
fileprivate init(_ state: PinsStorage.V1.CheckoutInfo) throws {
fileprivate init(_ state: PinsStorage.CheckoutInfo) throws {
let revision: Revision = .init(identifier: state.revision)
if let branch = state.branch {
self = .branch(name: branch, revision: revision)
Expand Down
11 changes: 7 additions & 4 deletions Tests/WorkspaceTests/PinsStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,16 @@ final class PinsStoreTests: XCTestCase {

store.pin(packageRef: .remote(identity: fooIdentity, location: fooMirroredURL),
state: .version(v1, revision: .init(identifier: "foo-revision")))
store.pin(packageRef: .remote(identity: barMirroredIdentity, location: barMirroredURL),
store.pin(packageRef: .remote(identity: barIdentity, location: barMirroredURL),
state: .version(v1, revision: .init(identifier: "bar-revision")))
store.pin(packageRef: .remote(identity: bazIdentity, location: bazURL),
state: .version(v1, revision: .init(identifier: "baz-revision")))

XCTAssert(store.pinsMap.count == 3)
XCTAssertEqual(store.pinsMap[fooIdentity]!.packageRef.location, fooMirroredURL)
XCTAssertEqual(store.pinsMap[barIdentity]!.packageRef.location, barMirroredURL)
XCTAssertNil(store.pinsMap[barMirroredIdentity])
XCTAssertEqual(store.pinsMap[bazIdentity]!.packageRef.location, bazURL)

try store.saveState()
XCTAssert(fileSystem.exists(pinsFile))
Expand All @@ -207,8 +212,6 @@ final class PinsStoreTests: XCTestCase {
// Load the store again from disk, with mirrors
let store3 = try PinsStore(pinsFile: pinsFile, workingDirectory: .root, fileSystem: fileSystem, mirrors: mirrors)
XCTAssert(store3.pinsMap.count == 3)
XCTAssertEqual(store3.pinsMap[fooIdentity]!.packageRef.location, fooMirroredURL)
XCTAssertEqual(store3.pinsMap[barMirroredIdentity]!.packageRef.location, barMirroredURL)
XCTAssertEqual(store3.pinsMap[bazIdentity]!.packageRef.location, bazURL)
XCTAssertEqual(store3.pinsMap, store.pinsMap)
}
}