Skip to content

Commit 896cf3d

Browse files
neonichumattt
authored andcommitted
Print reason for requiring resolution (swiftlang#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 7af2937 commit 896cf3d

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
@@ -2042,11 +2042,13 @@ extension Workspace {
20422042
pinsStore: pinsStore
20432043
)
20442044

2045-
if precomputationResult.isRequired {
2045+
if case let .required(reason) = precomputationResult {
2046+
let reasonString = Self.format(workspaceResolveReason: reason)
2047+
20462048
if !fileSystem.exists(self.location.resolvedVersionsFile) {
2047-
diagnostics.emit(error: "a resolved file is required when automatic dependency resolution is disabled and should be placed at \(self.location.resolvedVersionsFile.pathString)")
2049+
diagnostics.emit(error: "a resolved file is required when automatic dependency resolution is disabled and should be placed at \(self.location.resolvedVersionsFile.pathString). \(reasonString)")
20482050
} else {
2049-
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")
2051+
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)")
20502052
}
20512053
}
20522054

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

28162870
/// A result which can be loaded.

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3612,7 +3612,7 @@ final class WorkspaceTests: XCTestCase {
36123612
// Check force resolve. This should produce an error because the resolved file is out-of-date.
36133613
workspace.checkPackageGraphFailure(roots: ["Root"], forceResolvedVersions: true) { diagnostics in
36143614
DiagnosticsEngineTester(diagnostics) { result in
3615-
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)
3615+
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)
36163616
}
36173617
}
36183618
workspace.checkManagedDependencies { result in
@@ -3696,9 +3696,9 @@ final class WorkspaceTests: XCTestCase {
36963696
)
36973697

36983698
workspace.checkPackageGraphFailure(roots: ["Root"], forceResolvedVersions: true) { diagnostics in
3699-
DiagnosticsEngineTester(diagnostics) { result in
3700-
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)
3701-
}
3699+
guard let diagnostic = diagnostics.diagnostics.first else { return XCTFail("unexpectedly got no diagnostics") }
3700+
// rdar://82544922 (`WorkspaceResolveReason` is non-deterministic)
3701+
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")
37023702
}
37033703
}
37043704

0 commit comments

Comments
 (0)