Skip to content

Commit e534541

Browse files
committed
Remove basedOn property for ManagedDependency
1 parent 9207ea7 commit e534541

File tree

5 files changed

+44
-58
lines changed

5 files changed

+44
-58
lines changed

Sources/SPMTestSupport/MockWorkspace.swift

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -459,15 +459,13 @@ public final class MockWorkspace {
459459

460460
public func check(dependency name: String, at state: State, file: StaticString = #file, line: UInt = #line) {
461461
guard let dependency = managedDependencies[named: name] else {
462-
XCTFail("\(name) does not exists", file: file, line: line)
463-
return
462+
return XCTFail("\(name) does not exists", file: file, line: line)
464463
}
465464

466465
switch state {
467466
case .checkout(let checkoutState):
468467
guard case .checkout(let dependencyCheckoutState) = dependency.state else {
469-
XCTFail("Expected checked out dependency; found '\(dependency.state)' instead", file: file, line: line)
470-
return
468+
return XCTFail("Expected checked out dependency; found '\(dependency.state)' instead", file: file, line: line)
471469
}
472470

473471
switch checkoutState {
@@ -479,12 +477,12 @@ public final class MockWorkspace {
479477
XCTAssertEqual(dependencyCheckoutState.branch, branch, file: file, line: line)
480478
}
481479
case .edited(let editedState):
482-
if dependency.state != .edited(editedState) {
483-
XCTFail("Expected edited dependency; found '\(dependency.state)' instead", file: file, line: line)
480+
guard case .edited(_, editedState) = dependency.state else {
481+
return XCTFail("Expected edited dependency; found '\(dependency.state)' instead", file: file, line: line)
484482
}
485483
case .local:
486-
if dependency.state != .local {
487-
XCTFail("Expected local dependency", file: file, line: line)
484+
guard case .local = dependency.state else {
485+
return XCTFail("Expected local dependency", file: file, line: line)
488486
}
489487
}
490488
}

Sources/Workspace/ManagedDependency.swift

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import TSCUtility
1818
///
1919
/// Each dependency will have a checkout containing the sources at a
2020
/// particular revision, and may have an associated version.
21-
public class ManagedDependency {
21+
public struct ManagedDependency: Equatable {
2222
/// Represents the state of the managed dependency.
23-
public enum State: Equatable {
23+
public indirect enum State: Equatable {
2424
// The dependency is a local package.
2525
case local
2626

@@ -32,7 +32,7 @@ public class ManagedDependency {
3232
/// If the path is non-nil, the dependency is managed by a user and is
3333
/// located at the path. In other words, this dependency is being used
3434
/// for top of the tree style development.
35-
case edited(EditedState)
35+
case edited(basedOn: ManagedDependency, EditedState)
3636
}
3737

3838
/// The package reference.
@@ -57,43 +57,25 @@ public class ManagedDependency {
5757
}
5858
}
5959

60-
/// A dependency which in editable state is based on a dependency from
61-
/// which it edited from.
62-
///
63-
/// This information is useful so it can be restored when users
64-
/// unedit a package.
65-
public internal(set) var basedOn: ManagedDependency?
66-
6760
/// Create a dependency present locally on the filesystem.
68-
public static func local(
69-
package: PackageReference
70-
) -> ManagedDependency {
71-
return ManagedDependency(
72-
package: package,
73-
state: .local,
74-
basedOn: nil
75-
)
61+
public static func local(package: PackageReference) -> ManagedDependency {
62+
return ManagedDependency(package: package, state: .local)
7663
}
7764

7865
/// Create an editable managed dependency based on a dependency which
7966
/// was *not* in edit state.
8067
public static func checkout(package: PackageReference, state: CheckoutState) -> ManagedDependency {
81-
return ManagedDependency(package: package, state: .checkout(state), basedOn: nil)
68+
return ManagedDependency(package: package, state: .checkout(state))
8269
}
8370

8471
/// Create an editable managed dependency based on a dependency which
8572
/// was *not* in edit state.
8673
public static func edited(basedOn dependency: ManagedDependency, state: EditedState) -> ManagedDependency {
87-
return ManagedDependency(package: dependency.package, state: .edited(state), basedOn: dependency)
74+
return ManagedDependency(package: dependency.package, state: .edited(basedOn: dependency, state))
8875
}
8976

90-
internal init(
91-
package: PackageReference,
92-
state: State,
93-
basedOn: ManagedDependency?
94-
) {
77+
init(package: PackageReference, state: State) {
9578
self.package = package
96-
self.basedOn = basedOn
9779
self.state = state
9880
}
9981
}

Sources/Workspace/Workspace.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ extension Workspace {
11141114
root: PackageGraphRootInput? = nil,
11151115
diagnostics: DiagnosticsEngine
11161116
) throws {
1117-
guard case .edited(let editedState) = dependency.state else {
1117+
guard case let .edited(basedOn, editedState) = dependency.state else {
11181118
throw WorkspaceDiagnostics.DependencyNotInEditMode(dependencyName: dependency.package.name)
11191119
}
11201120

@@ -1144,7 +1144,8 @@ extension Workspace {
11441144
try fileSystem.removeFileTree(self.location.editsDirectory)
11451145
}
11461146

1147-
if case .checkout(let checkoutState) = dependency.basedOn?.state {
1147+
1148+
if case .checkout(let checkoutState) = basedOn.state {
11481149
// Restore the original checkout.
11491150
//
11501151
// The clone method will automatically update the managed dependency state.
@@ -1469,9 +1470,9 @@ extension Workspace {
14691470
switch dependency.state {
14701471
case .checkout:
14711472
return self.location.repositoryCheckoutDirectory(for: dependency.package)
1472-
case .edited(.managed):
1473-
return self.location.editDirectory(for: dependency.package)
1474-
case .edited(.unmanaged(let path)):
1473+
case .edited(basedOn: let basedOn, .managed):
1474+
return self.location.editDirectory(for: basedOn.package)
1475+
case .edited(_, .unmanaged(let path)):
14751476
return path
14761477
case .local:
14771478
return AbsolutePath(dependency.package.location)
@@ -2457,13 +2458,14 @@ extension Workspace {
24572458
// original checkout in somewhat of a dangling state when computing
24582459
// the state changes this method. We basically need to ensure that
24592460
// the edited checkout is unchanged.
2460-
if let editedDependency = state.dependencies.first(where: {
2461-
guard $0.basedOn != nil else { return false }
2462-
return self.path(to: $0).pathString == packageRef.location
2461+
if let editedDependency = state.dependencies.first(where: { dependency in
2462+
guard case .edited = dependency.state else { return false }
2463+
return self.path(to: dependency).pathString == packageRef.location
24632464
}) {
24642465
currentDependency = editedDependency
2465-
let originalReference = editedDependency.basedOn!.package // forced unwrap safe
2466-
packageStateChanges[originalReference.location] = (originalReference, .unchanged)
2466+
if case .edited(basedOn: let original, _) = editedDependency.state {
2467+
packageStateChanges[original.package.location] = (original.package, .unchanged)
2468+
}
24672469
} else {
24682470
currentDependency = nil
24692471
}
@@ -2832,7 +2834,7 @@ extension Workspace {
28322834

28332835
/// Removes the clone and checkout of the provided specifier.
28342836
fileprivate func remove(package: PackageReference) throws {
2835-
guard let dependency = state.dependencies[package.identity] else {
2837+
guard var dependency = state.dependencies[package.identity] else {
28362838
throw InternalError("trying to remove \(package.name) which isn't in workspace")
28372839
}
28382840

@@ -2855,10 +2857,10 @@ extension Workspace {
28552857
// Compute the dependency which we need to remove.
28562858
let dependencyToRemove: ManagedDependency
28572859

2858-
if let basedOn = dependency.basedOn {
2860+
if case .edited(basedOn: let original, _) = dependency.state {
28592861
// Remove the underlying dependency for edited packages.
2860-
dependencyToRemove = basedOn
2861-
dependency.basedOn = nil
2862+
dependencyToRemove = original
2863+
dependency = ManagedDependency(package: package, state: original.state)
28622864
state.dependencies.add(dependency)
28632865
} else {
28642866
dependencyToRemove = dependency

Sources/Workspace/WorkspaceState.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,12 @@ fileprivate struct WorkspaceStateStorage {
164164
init(_ dependency: ManagedDependency) {
165165
self.packageRef = .init(dependency.package)
166166
self.state = dependency.state
167-
self.basedOn = dependency.basedOn.map{ .init($0) }
167+
168+
if case .edited(basedOn: let original, _) = dependency.state {
169+
self.basedOn = .init(original)
170+
} else {
171+
self.basedOn = nil
172+
}
168173
}
169174

170175
private enum CodingKeys: String, CodingKey {
@@ -228,7 +233,9 @@ fileprivate struct WorkspaceStateStorage {
228233
case .checkout(let checkoutState):
229234
try nestedContainer.encode("checkout", forKey: .name)
230235
try nestedContainer.encode(CheckoutInfo(checkoutState), forKey: .checkoutState)
231-
case .edited(let editedState):
236+
case .edited(basedOn: let dependency, let editedState):
237+
try container.encode(Dependency(dependency), forKey: .basedOn)
238+
232239
try nestedContainer.encode("edited", forKey: .name)
233240
switch editedState {
234241
case .unmanaged(let path):
@@ -335,12 +342,8 @@ fileprivate struct WorkspaceStateStorage {
335342
}
336343

337344
extension ManagedDependency {
338-
fileprivate convenience init(_ dependency: WorkspaceStateStorage.V4.Dependency) {
339-
self.init(
340-
package: .init(dependency.packageRef),
341-
state: dependency.state,
342-
basedOn: dependency.basedOn.map { .init($0) }
343-
)
345+
fileprivate init(_ dependency: WorkspaceStateStorage.V4.Dependency) {
346+
self.init(package: .init(dependency.packageRef), state: dependency.state)
344347
}
345348
}
346349

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,8 +2277,9 @@ final class WorkspaceTests: XCTestCase {
22772277
}
22782278

22792279
// There should still be an entry for `foo`, which we can unedit.
2280-
let editedDependency = ws.state.dependencies[named: "foo"]!
2281-
XCTAssertNil(editedDependency.basedOn)
2280+
let editedDependency = ws.state.dependencies[named: "foo"]
2281+
XCTAssertNotNil(editedDependency)
2282+
22822283
workspace.checkManagedDependencies { result in
22832284
result.check(dependency: "foo", at: .edited(.managed))
22842285
}

0 commit comments

Comments
 (0)