Skip to content

Commit 9f9f9fe

Browse files
authored
Merge pull request #79 from owenv/multi-job-diag
Diagnose inputs modified during the build for multi-job plans
2 parents dc23e2a + f46fb70 commit 9f9f9fe

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
@@ -669,6 +669,7 @@ extension Driver {
669669
let jobExecutor = JobExecutor(
670670
jobs: jobs, resolver: resolver,
671671
executorDelegate: executorDelegate,
672+
diagnosticsEngine: diagnosticEngine,
672673
numParallelJobs: numParallelJobs,
673674
processSet: processSet,
674675
forceResponseFiles: forceResponseFiles,

Sources/SwiftDriver/Execution/JobExecutor.swift

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

151+
/// The diagnostics engine to use when reporting errors.
152+
let diagnosticsEngine: DiagnosticsEngine
153+
151154
init(
152155
argsResolver: ArgsResolver,
153156
env: [String: String],
@@ -157,7 +160,8 @@ public final class JobExecutor {
157160
jobQueue: OperationQueue,
158161
processSet: ProcessSet?,
159162
forceResponseFiles: Bool,
160-
recordedInputModificationDates: [TypedVirtualPath: Date]
163+
recordedInputModificationDates: [TypedVirtualPath: Date],
164+
diagnosticsEngine: DiagnosticsEngine
161165
) {
162166
self.producerMap = producerMap
163167
self.argsResolver = argsResolver
@@ -168,6 +172,7 @@ public final class JobExecutor {
168172
self.processSet = processSet
169173
self.forceResponseFiles = forceResponseFiles
170174
self.recordedInputModificationDates = recordedInputModificationDates
175+
self.diagnosticsEngine = diagnosticsEngine
171176
}
172177
}
173178

@@ -192,10 +197,14 @@ public final class JobExecutor {
192197
/// The last time each input file was modified, recorded at the start of the build.
193198
public let recordedInputModificationDates: [TypedVirtualPath: Date]
194199

200+
/// The diagnostics engine to use when reporting errors.
201+
let diagnosticsEngine: DiagnosticsEngine
202+
195203
public init(
196204
jobs: [Job],
197205
resolver: ArgsResolver,
198206
executorDelegate: JobExecutorDelegate,
207+
diagnosticsEngine: DiagnosticsEngine,
199208
numParallelJobs: Int? = nil,
200209
processSet: ProcessSet? = nil,
201210
forceResponseFiles: Bool = false,
@@ -204,6 +213,7 @@ public final class JobExecutor {
204213
self.jobs = jobs
205214
self.argsResolver = resolver
206215
self.executorDelegate = executorDelegate
216+
self.diagnosticsEngine = diagnosticsEngine
207217
self.numParallelJobs = numParallelJobs ?? 1
208218
self.processSet = processSet
209219
self.forceResponseFiles = forceResponseFiles
@@ -248,7 +258,8 @@ public final class JobExecutor {
248258
jobQueue: jobQueue,
249259
processSet: processSet,
250260
forceResponseFiles: forceResponseFiles,
251-
recordedInputModificationDates: recordedInputModificationDates
261+
recordedInputModificationDates: recordedInputModificationDates,
262+
diagnosticsEngine: diagnosticsEngine
252263
)
253264
}
254265
}
@@ -429,6 +440,9 @@ class ExecuteJobRule: LLBuildRule {
429440

430441
value = .jobExecution(success: success)
431442
} catch {
443+
if error is DiagnosticData {
444+
context.diagnosticsEngine.emit(error)
445+
}
432446
context.delegateQueue.async {
433447
let result = ProcessResult(
434448
arguments: [],

Tests/SwiftDriverTests/JobExecutorTests.swift

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

152152
let delegate = JobCollectingDelegate()
153-
let executor = JobExecutor(jobs: [compileFoo, compileMain, link], resolver: resolver, executorDelegate: delegate)
153+
let executor = JobExecutor(jobs: [compileFoo, compileMain, link], resolver: resolver, executorDelegate: delegate, diagnosticsEngine: DiagnosticsEngine())
154154
try executor.execute(env: toolchain.env, fileSystem: localFileSystem)
155155

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

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

0 commit comments

Comments
 (0)