Skip to content

Commit 26dec69

Browse files
committed
Diagnose inputs modified during the build for multi-job plans
1 parent c835d02 commit 26dec69

File tree

3 files changed

+37
-24
lines changed

3 files changed

+37
-24
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ extension Driver {
635635
let jobExecutor = JobExecutor(
636636
jobs: jobs, resolver: resolver,
637637
executorDelegate: executorDelegate,
638+
diagnosticsEngine: diagnosticEngine,
638639
numParallelJobs: numParallelJobs,
639640
processSet: processSet,
640641
forceResponseFiles: forceResponseFiles,

Sources/SwiftDriver/Execution/JobExecutor.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ public final class JobExecutor {
141141
/// The last time each input file was modified, recorded at the start of the build.
142142
public let recordedInputModificationDates: [TypedVirtualPath: Date]
143143

144+
/// The diagnostics engine to use when reporting errors.
145+
let diagnosticsEngine: DiagnosticsEngine
146+
144147
init(
145148
argsResolver: ArgsResolver,
146149
env: [String: String],
@@ -149,7 +152,8 @@ public final class JobExecutor {
149152
jobQueue: OperationQueue,
150153
processSet: ProcessSet?,
151154
forceResponseFiles: Bool,
152-
recordedInputModificationDates: [TypedVirtualPath: Date]
155+
recordedInputModificationDates: [TypedVirtualPath: Date],
156+
diagnosticsEngine: DiagnosticsEngine
153157
) {
154158
self.producerMap = producerMap
155159
self.argsResolver = argsResolver
@@ -159,6 +163,7 @@ public final class JobExecutor {
159163
self.processSet = processSet
160164
self.forceResponseFiles = forceResponseFiles
161165
self.recordedInputModificationDates = recordedInputModificationDates
166+
self.diagnosticsEngine = diagnosticsEngine
162167
}
163168
}
164169

@@ -183,10 +188,14 @@ public final class JobExecutor {
183188
/// The last time each input file was modified, recorded at the start of the build.
184189
public let recordedInputModificationDates: [TypedVirtualPath: Date]
185190

191+
/// The diagnostics engine to use when reporting errors.
192+
let diagnosticsEngine: DiagnosticsEngine
193+
186194
public init(
187195
jobs: [Job],
188196
resolver: ArgsResolver,
189197
executorDelegate: JobExecutorDelegate,
198+
diagnosticsEngine: DiagnosticsEngine,
190199
numParallelJobs: Int? = nil,
191200
processSet: ProcessSet? = nil,
192201
forceResponseFiles: Bool = false,
@@ -195,6 +204,7 @@ public final class JobExecutor {
195204
self.jobs = jobs
196205
self.argsResolver = resolver
197206
self.executorDelegate = executorDelegate
207+
self.diagnosticsEngine = diagnosticsEngine
198208
self.numParallelJobs = numParallelJobs ?? 1
199209
self.processSet = processSet
200210
self.forceResponseFiles = forceResponseFiles
@@ -238,7 +248,8 @@ public final class JobExecutor {
238248
jobQueue: jobQueue,
239249
processSet: processSet,
240250
forceResponseFiles: forceResponseFiles,
241-
recordedInputModificationDates: recordedInputModificationDates
251+
recordedInputModificationDates: recordedInputModificationDates,
252+
diagnosticsEngine: diagnosticsEngine
242253
)
243254
}
244255
}
@@ -420,6 +431,9 @@ class ExecuteJobRule: LLBuildRule {
420431

421432
value = .jobExecution(success: success)
422433
} catch {
434+
if let diagnostic = error as? DiagnosticData {
435+
context.diagnosticsEngine.emit(error)
436+
}
423437
context.delegateQueue.async {
424438
let result = ProcessResult(
425439
arguments: [],

Tests/SwiftDriverTests/JobExecutorTests.swift

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ final class JobExecutorTests: XCTestCase {
149149
)
150150

151151
let delegate = JobCollectingDelegate()
152-
let executor = JobExecutor(jobs: [compileFoo, compileMain, link], resolver: resolver, executorDelegate: delegate)
152+
let executor = JobExecutor(jobs: [compileFoo, compileMain, link], resolver: resolver, executorDelegate: delegate, diagnosticsEngine: DiagnosticsEngine())
153153
try executor.execute(env: toolchain.env)
154154

155155
let output = try TSCBasic.Process.checkNonZeroExit(args: exec.pathString)
@@ -177,7 +177,8 @@ final class JobExecutorTests: XCTestCase {
177177
delegate.useStubProcess = true
178178
let executor = JobExecutor(
179179
jobs: [job], resolver: try ArgsResolver(),
180-
executorDelegate: delegate
180+
executorDelegate: delegate,
181+
diagnosticsEngine: DiagnosticsEngine()
181182
)
182183
try executor.execute(env: ProcessEnv.vars)
183184

@@ -246,27 +247,24 @@ final class JobExecutorTests: XCTestCase {
246247
try localFileSystem.writeFileContents(other) {
247248
$0 <<< "let bar = 2"
248249
}
249-
250-
var driver = try Driver(args: ["swiftc", main.pathString, other.pathString])
251-
let jobs = try driver.planBuild()
252-
XCTAssertTrue(jobs.count > 1)
253-
let resolver = try ArgsResolver()
254-
255-
// Change the file
256-
try localFileSystem.writeFileContents(other) {
257-
$0 <<< "let bar = 3"
258-
}
259-
260-
let delegate = JobCollectingDelegate()
261-
delegate.useStubProcess = true
262-
XCTAssertThrowsError(try driver.run(jobs: jobs, resolver: resolver,
263-
executorDelegate: delegate)) {
264-
// FIXME: The JobExecutor needs a way of emitting diagnostics or
265-
// propagating errors through llbuild.
266-
XCTAssertEqual($0 as? Diagnostics, .fatalError)
250+
try assertDriverDiagnostics(args: ["swiftc", main.pathString, other.pathString]) {driver, verifier in
251+
let jobs = try driver.planBuild()
252+
XCTAssertTrue(jobs.count > 1)
253+
let resolver = try ArgsResolver()
254+
255+
// Change the file
256+
try localFileSystem.writeFileContents(other) {
257+
$0 <<< "let bar = 3"
258+
}
259+
260+
let delegate = JobCollectingDelegate()
261+
delegate.useStubProcess = true
262+
263+
// FIXME: It's unfortunate we diagnose this twice, once for each job which uses the input.
264+
verifier.expect(.error("input file '\(other.description)' was modified during the build"))
265+
verifier.expect(.error("input file '\(other.description)' was modified during the build"))
266+
XCTAssertThrowsError(try driver.run(jobs: jobs, resolver: resolver, executorDelegate: delegate))
267267
}
268-
269268
}
270269
}
271-
272270
}

0 commit comments

Comments
 (0)