Skip to content

Commit 241e610

Browse files
committed
update the resolved file format
motivation: resolved file now encodes the package name which is redundant. it also does not include the identity of the package so that needs to be computed frmo the url and could be incorrect in case of "creative" mirroring. it will also pose issues as we transition to registry based dependencies changes: * create V2 of the resolved file format * in new format, encode identity and not name * adjust tests
1 parent c9a8f60 commit 241e610

File tree

2 files changed

+82
-28
lines changed

2 files changed

+82
-28
lines changed

Sources/PackageGraph/PinsStore.swift

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,22 @@ fileprivate struct PinsStorage {
122122
return try self.fileSystem.withLock(on: self.lockFilePath, type: .shared) {
123123
let version = try self.decoder.decode(path: self.path, fileSystem: self.fileSystem, as: Version.self)
124124
switch version.version {
125-
case 1:
125+
case V1.version:
126126
let v1 = try decoder.decode(path: self.path, fileSystem: self.fileSystem, as: V1.self)
127127
return try v1.object.pins.map{ try PinsStore.Pin($0, mirrors: mirrors) }.reduce(into: [PackageIdentity: PinsStore.Pin]()) { partial, iterator in
128128
if partial.keys.contains(iterator.packageRef.identity) {
129129
throw StringError("duplicated entry for package \"\(iterator.packageRef.name)\"")
130130
}
131131
partial[iterator.packageRef.identity] = iterator
132132
}
133+
case V2.version:
134+
let v2 = try decoder.decode(path: self.path, fileSystem: self.fileSystem, as: V2.self)
135+
return try v2.pins.map{ try PinsStore.Pin($0, mirrors: mirrors) }.reduce(into: [PackageIdentity: PinsStore.Pin]()) { partial, iterator in
136+
if partial.keys.contains(iterator.packageRef.identity) {
137+
throw StringError("duplicated entry for package \"\(iterator.packageRef.identity)\"")
138+
}
139+
partial[iterator.packageRef.identity] = iterator
140+
}
133141
default:
134142
throw InternalError("unknown RepositoryManager version: \(version)")
135143
}
@@ -150,7 +158,7 @@ fileprivate struct PinsStorage {
150158
return
151159
}
152160

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

173181
// v1 storage format
174182
struct V1: Codable {
183+
static let version = 1
184+
175185
let version: Int
176186
let object: Container
177187

178188
init (pins: PinsStore.PinsMap, mirrors: DependencyMirrors) {
179-
self.version = 1
189+
self.version = Self.version
180190
self.object = .init(
181191
pins: pins.values
182192
.sorted(by: { $0.packageRef.identity < $1.packageRef.identity })
@@ -200,27 +210,55 @@ fileprivate struct PinsStorage {
200210
self.state = .init(pin.state)
201211
}
202212
}
213+
}
203214

204-
struct CheckoutInfo: Codable {
205-
let revision: String
206-
let branch: String?
207-
let version: String?
208-
209-
init(_ state: CheckoutState) {
210-
switch state {
211-
case .version(let version, let revision):
212-
self.version = version.description
213-
self.branch = nil
214-
self.revision = revision.identifier
215-
case .branch(let branch, let revision):
216-
self.version = nil
217-
self.branch = branch
218-
self.revision = revision.identifier
219-
case .revision(let revision):
220-
self.version = nil
221-
self.branch = nil
222-
self.revision = revision.identifier
223-
}
215+
// v2 storage format
216+
struct V2: Codable {
217+
static let version = 2
218+
219+
let version: Int
220+
let pins: [Pin]
221+
222+
init (pins: PinsStore.PinsMap, mirrors: DependencyMirrors) {
223+
self.version = Self.version
224+
self.pins = pins.values
225+
.sorted(by: { $0.packageRef.identity < $1.packageRef.identity })
226+
.map{ Pin($0, mirrors: mirrors) }
227+
}
228+
229+
struct Pin: Codable {
230+
let identity: PackageIdentity
231+
let location: String
232+
let state: CheckoutInfo
233+
234+
init(_ pin: PinsStore.Pin, mirrors: DependencyMirrors) {
235+
self.identity = pin.packageRef.identity
236+
// rdar://52529014, rdar://52529011: pin file should store the original location but remap when loading
237+
self.location = mirrors.originalURL(for: pin.packageRef.location) ?? pin.packageRef.location
238+
self.state = .init(pin.state)
239+
}
240+
}
241+
}
242+
243+
struct CheckoutInfo: Codable {
244+
let revision: String
245+
let branch: String?
246+
let version: String?
247+
248+
init(_ state: CheckoutState) {
249+
switch state {
250+
case .version(let version, let revision):
251+
self.version = version.description
252+
self.branch = nil
253+
self.revision = revision.identifier
254+
case .branch(let branch, let revision):
255+
self.version = nil
256+
self.branch = branch
257+
self.revision = revision.identifier
258+
case .revision(let revision):
259+
self.version = nil
260+
self.branch = nil
261+
self.revision = revision.identifier
224262
}
225263
}
226264
}
@@ -242,8 +280,21 @@ extension PinsStore.Pin {
242280
}
243281
}
244282

283+
extension PinsStore.Pin {
284+
fileprivate init(_ pin: PinsStorage.V2.Pin, mirrors: DependencyMirrors) throws {
285+
// rdar://52529014, rdar://52529011: pin file should store the original location but remap when loading
286+
let url = mirrors.effectiveURL(for: pin.location)
287+
let identity = pin.identity
288+
let packageRef = PackageReference.remote(identity: identity, location: url)
289+
self.init(
290+
packageRef: packageRef,
291+
state: try .init(pin.state)
292+
)
293+
}
294+
}
295+
245296
extension CheckoutState {
246-
fileprivate init(_ state: PinsStorage.V1.CheckoutInfo) throws {
297+
fileprivate init(_ state: PinsStorage.CheckoutInfo) throws {
247298
let revision: Revision = .init(identifier: state.revision)
248299
if let branch = state.branch {
249300
self = .branch(name: branch, revision: revision)

Tests/WorkspaceTests/PinsStoreTests.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,16 @@ final class PinsStoreTests: XCTestCase {
188188

189189
store.pin(packageRef: .remote(identity: fooIdentity, location: fooMirroredURL),
190190
state: .version(v1, revision: .init(identifier: "foo-revision")))
191-
store.pin(packageRef: .remote(identity: barMirroredIdentity, location: barMirroredURL),
191+
store.pin(packageRef: .remote(identity: barIdentity, location: barMirroredURL),
192192
state: .version(v1, revision: .init(identifier: "bar-revision")))
193193
store.pin(packageRef: .remote(identity: bazIdentity, location: bazURL),
194194
state: .version(v1, revision: .init(identifier: "baz-revision")))
195195

196+
XCTAssert(store.pinsMap.count == 3)
197+
XCTAssertEqual(store.pinsMap[fooIdentity]!.packageRef.location, fooMirroredURL)
198+
XCTAssertEqual(store.pinsMap[barIdentity]!.packageRef.location, barMirroredURL)
199+
XCTAssertNil(store.pinsMap[barMirroredIdentity])
200+
XCTAssertEqual(store.pinsMap[bazIdentity]!.packageRef.location, bazURL)
196201

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

0 commit comments

Comments
 (0)