Skip to content

Commit d1e12f4

Browse files
committed
[Workspace] Make managed dependencies state file resilient
<rdar://problem/45786628> ManagedDepenency needs to be resilient against having the the state file removed underneath it
1 parent ab6eebb commit d1e12f4

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

Sources/Workspace/ManagedDependency.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ public final class ManagedDependencies: SimplePersistanceProtocol {
276276
try self.persistence.saveState(self)
277277
}
278278

279+
/// Returns true if the state file exists on the filesystem.
280+
public func stateFileExists() -> Bool {
281+
return persistence.stateFileExists()
282+
}
283+
279284
public var values: AnySequence<ManagedDependency> {
280285
return AnySequence<ManagedDependency>(dependencyMap.values)
281286
}

Sources/Workspace/Workspace.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,12 @@ extension Workspace {
15891589
/// If some edited dependency is removed from the file system, mark it as unedited and
15901590
/// fallback on the original checkout.
15911591
fileprivate func fixManagedDependencies(with diagnostics: DiagnosticsEngine) {
1592+
1593+
// Reset managed dependencies if the state file was removed during the lifetime of the Workspace object.
1594+
if managedDependencies.values.contains(where: { _ in true }) && !managedDependencies.stateFileExists() {
1595+
try? managedDependencies.reset()
1596+
}
1597+
15921598
for dependency in managedDependencies.values {
15931599
diagnostics.wrap {
15941600

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ final class WorkspaceTests: XCTestCase {
9797
result.check(dependency: "quix", at: .checkout(.version("1.2.0")))
9898
}
9999

100+
let stateFile = workspace.createWorkspace().managedDependencies.statePath
101+
102+
// Remove state file and check we can get the state back automatically.
103+
try fs.removeFileTree(stateFile)
104+
105+
workspace.checkPackageGraph(roots: ["Foo"], deps: deps) { _, _ in }
106+
XCTAssertTrue(fs.exists(stateFile))
107+
100108
// Remove state file and check we get back to a clean state.
101109
try fs.removeFileTree(workspace.createWorkspace().managedDependencies.statePath)
102110
workspace.closeWorkspace()

0 commit comments

Comments
 (0)