Skip to content

Commit dd71675

Browse files
authored
Print reason for requiring resolution (#3688)
This moves the existing code for printing a `WorkspaceResolveReason` and always appends it to the diagnostic for an out-of-date required resolved file.
1 parent 09e73d8 commit dd71675

File tree

3 files changed

+63
-56
lines changed

3 files changed

+63
-56
lines changed

Sources/Commands/SwiftTool.swift

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -148,56 +148,9 @@ private class ToolWorkspaceDelegate: WorkspaceDelegate {
148148
guard isVerbose else { return }
149149

150150
queue.sync {
151-
self.stdoutStream <<< "Running resolver because "
152-
153-
switch reason {
154-
case .forced:
155-
self.stdoutStream <<< "it was forced"
156-
case .newPackages(let packages):
157-
let dependencies = packages.lazy.map({ "'\($0.location)'" }).joined(separator: ", ")
158-
self.stdoutStream <<< "the following dependencies were added: \(dependencies)"
159-
case .packageRequirementChange(let package, let state, let requirement):
160-
self.stdoutStream <<< "dependency '\(package.name)' was "
161-
162-
switch state {
163-
case .checkout(let checkoutState)?:
164-
switch checkoutState.requirement {
165-
case .versionSet(.exact(let version)):
166-
self.stdoutStream <<< "resolved to '\(version)'"
167-
case .versionSet(_):
168-
// Impossible
169-
break
170-
case .revision(let revision):
171-
self.stdoutStream <<< "resolved to '\(revision)'"
172-
case .unversioned:
173-
self.stdoutStream <<< "unversioned"
174-
}
175-
case .edited?:
176-
self.stdoutStream <<< "edited"
177-
case .local?:
178-
self.stdoutStream <<< "versioned"
179-
case nil:
180-
self.stdoutStream <<< "root"
181-
}
182-
183-
self.stdoutStream <<< " but now has a "
184-
185-
switch requirement {
186-
case .versionSet:
187-
self.stdoutStream <<< "different version-based"
188-
case .revision:
189-
self.stdoutStream <<< "different revision-based"
190-
case .unversioned:
191-
self.stdoutStream <<< "unversioned"
192-
}
193-
194-
self.stdoutStream <<< " requirement."
195-
default:
196-
self.stdoutStream <<< " requirements have changed."
197-
}
198-
151+
self.stdoutStream <<< Workspace.format(workspaceResolveReason: reason)
199152
self.stdoutStream <<< "\n"
200-
stdoutStream.flush()
153+
self.stdoutStream.flush()
201154
}
202155
}
203156

Sources/Workspace/Workspace.swift

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,11 +2038,13 @@ extension Workspace {
20382038
pinsStore: pinsStore
20392039
)
20402040

2041-
if precomputationResult.isRequired {
2041+
if case let .required(reason) = precomputationResult {
2042+
let reasonString = Self.format(workspaceResolveReason: reason)
2043+
20422044
if !fileSystem.exists(self.location.resolvedVersionsFile) {
2043-
diagnostics.emit(error: "a resolved file is required when automatic dependency resolution is disabled and should be placed at \(self.location.resolvedVersionsFile.pathString)")
2045+
diagnostics.emit(error: "a resolved file is required when automatic dependency resolution is disabled and should be placed at \(self.location.resolvedVersionsFile.pathString). \(reasonString)")
20442046
} else {
2045-
diagnostics.emit(error: "an out-of-date resolved file was detected at \(self.location.resolvedVersionsFile.pathString), which is not allowed when automatic dependency resolution is disabled; please make sure to update the file to reflect the changes in dependencies")
2047+
diagnostics.emit(error: "an out-of-date resolved file was detected at \(self.location.resolvedVersionsFile.pathString), which is not allowed when automatic dependency resolution is disabled; please make sure to update the file to reflect the changes in dependencies. \(reasonString)")
20462048
}
20472049
}
20482050

@@ -2819,6 +2821,58 @@ extension Workspace {
28192821
// Save the state.
28202822
try state.saveState()
28212823
}
2824+
2825+
public static func format(workspaceResolveReason reason: WorkspaceResolveReason) -> String {
2826+
var result = "Running resolver because "
2827+
2828+
switch reason {
2829+
case .forced:
2830+
result.append("it was forced")
2831+
case .newPackages(let packages):
2832+
let dependencies = packages.lazy.map({ "'\($0.location)'" }).joined(separator: ", ")
2833+
result.append("the following dependencies were added: \(dependencies)")
2834+
case .packageRequirementChange(let package, let state, let requirement):
2835+
result.append("dependency '\(package.name)' was ")
2836+
2837+
switch state {
2838+
case .checkout(let checkoutState)?:
2839+
switch checkoutState.requirement {
2840+
case .versionSet(.exact(let version)):
2841+
result.append("resolved to '\(version)'")
2842+
case .versionSet(_):
2843+
// Impossible
2844+
break
2845+
case .revision(let revision):
2846+
result.append("resolved to '\(revision)'")
2847+
case .unversioned:
2848+
result.append("unversioned")
2849+
}
2850+
case .edited?:
2851+
result.append("edited")
2852+
case .local?:
2853+
result.append("versioned")
2854+
case nil:
2855+
result.append("root")
2856+
}
2857+
2858+
result.append(" but now has a ")
2859+
2860+
switch requirement {
2861+
case .versionSet:
2862+
result.append("different version-based")
2863+
case .revision:
2864+
result.append("different revision-based")
2865+
case .unversioned:
2866+
result.append("unversioned")
2867+
}
2868+
2869+
result.append(" requirement.")
2870+
default:
2871+
result.append(" requirements have changed.")
2872+
}
2873+
2874+
return result
2875+
}
28222876
}
28232877

28242878
/// A result which can be loaded.

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3607,7 +3607,7 @@ final class WorkspaceTests: XCTestCase {
36073607
// Check force resolve. This should produce an error because the resolved file is out-of-date.
36083608
workspace.checkPackageGraphFailure(roots: ["Root"], forceResolvedVersions: true) { diagnostics in
36093609
DiagnosticsEngineTester(diagnostics) { result in
3610-
result.check(diagnostic: "an out-of-date resolved file was detected at /tmp/ws/Package.resolved, which is not allowed when automatic dependency resolution is disabled; please make sure to update the file to reflect the changes in dependencies", checkContains: true, behavior: .error)
3610+
result.check(diagnostic: "an out-of-date resolved file was detected at /tmp/ws/Package.resolved, which is not allowed when automatic dependency resolution is disabled; please make sure to update the file to reflect the changes in dependencies. Running resolver because requirements have changed.", checkContains: true, behavior: .error)
36113611
}
36123612
}
36133613
workspace.checkManagedDependencies { result in
@@ -3691,9 +3691,9 @@ final class WorkspaceTests: XCTestCase {
36913691
)
36923692

36933693
workspace.checkPackageGraphFailure(roots: ["Root"], forceResolvedVersions: true) { diagnostics in
3694-
DiagnosticsEngineTester(diagnostics) { result in
3695-
result.check(diagnostic: "a resolved file is required when automatic dependency resolution is disabled and should be placed at /tmp/ws/Package.resolved", checkContains: true, behavior: .error)
3696-
}
3694+
guard let diagnostic = diagnostics.diagnostics.first else { return XCTFail("unexpectedly got no diagnostics") }
3695+
// rdar://82544922 (`WorkspaceResolveReason` is non-deterministic)
3696+
XCTAssertTrue(diagnostic.message.text.hasPrefix("a resolved file is required when automatic dependency resolution is disabled and should be placed at /tmp/ws/Package.resolved. Running resolver because the following dependencies were added:"), "unexpected diagnostic message")
36973697
}
36983698
}
36993699

0 commit comments

Comments
 (0)