Skip to content

Commit 436598f

Browse files
authored
Merge pull request #1165 from artemcm/NoResponseInLibraryScan
Add ability to override/disable response file use in ArgsResolver
2 parents 7f400b2 + c86aaca commit 436598f

File tree

8 files changed

+67
-30
lines changed

8 files changed

+67
-30
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,7 @@ extension Driver {
13801380
// In verbose mode, print out the job
13811381
if parsedOptions.contains(.v) {
13821382
let arguments: [String] = try executor.resolver.resolveArgumentList(for: inPlaceJob,
1383-
forceResponseFiles: forceResponseFiles)
1383+
useResponseFiles: forceResponseFiles ? .forced : .heuristic)
13841384
stdoutStream <<< arguments.map { $0.spm_shellEscaped() }.joined(separator: " ") <<< "\n"
13851385
stdoutStream.flush()
13861386
}

Sources/SwiftDriver/Execution/ArgsResolver.swift

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ import class Foundation.NSLock
1414
import TSCBasic
1515
@_implementationOnly import Yams
1616

17+
/// How the resolver is to handle usage of response files
18+
public enum ResponseFileHandling {
19+
case forced
20+
case disabled
21+
case heuristic
22+
}
23+
1724
/// Resolver for a job's argument template.
1825
public final class ArgsResolver {
1926
/// The map of virtual path to the actual path.
@@ -45,22 +52,36 @@ public final class ArgsResolver {
4552
}
4653
}
4754

48-
public func resolveArgumentList(for job: Job, forceResponseFiles: Bool,
55+
public func resolveArgumentList(for job: Job, useResponseFiles: ResponseFileHandling = .heuristic,
4956
quotePaths: Bool = false) throws -> [String] {
50-
let (arguments, _) = try resolveArgumentList(for: job, forceResponseFiles: forceResponseFiles,
57+
let (arguments, _) = try resolveArgumentList(for: job, useResponseFiles: useResponseFiles,
5158
quotePaths: quotePaths)
5259
return arguments
5360
}
5461

55-
public func resolveArgumentList(for job: Job, forceResponseFiles: Bool,
62+
public func resolveArgumentList(for job: Job, useResponseFiles: ResponseFileHandling = .heuristic,
5663
quotePaths: Bool = false) throws -> ([String], usingResponseFile: Bool) {
5764
let tool = try resolve(.path(job.tool), quotePaths: quotePaths)
5865
var arguments = [tool] + (try job.commandLine.map { try resolve($0, quotePaths: quotePaths) })
5966
let usingResponseFile = try createResponseFileIfNeeded(for: job, resolvedArguments: &arguments,
60-
forceResponseFiles: forceResponseFiles)
67+
useResponseFiles: useResponseFiles)
6168
return (arguments, usingResponseFile)
6269
}
6370

71+
@available(*, deprecated, message: "use resolveArgumentList(for:,useResponseFiles:,quotePaths:)")
72+
public func resolveArgumentList(for job: Job, forceResponseFiles: Bool,
73+
quotePaths: Bool = false) throws -> [String] {
74+
let useResponseFiles: ResponseFileHandling = forceResponseFiles ? .forced : .heuristic
75+
return try resolveArgumentList(for: job, useResponseFiles: useResponseFiles, quotePaths: quotePaths)
76+
}
77+
78+
@available(*, deprecated, message: "use resolveArgumentList(for:,useResponseFiles:,quotePaths:)")
79+
public func resolveArgumentList(for job: Job, forceResponseFiles: Bool,
80+
quotePaths: Bool = false) throws -> ([String], usingResponseFile: Bool) {
81+
let useResponseFiles: ResponseFileHandling = forceResponseFiles ? .forced : .heuristic
82+
return try resolveArgumentList(for: job, useResponseFiles: useResponseFiles, quotePaths: quotePaths)
83+
}
84+
6485
/// Resolve the given argument.
6586
public func resolve(_ arg: Job.ArgTemplate,
6687
quotePaths: Bool = false) throws -> String {
@@ -167,11 +188,15 @@ public final class ArgsResolver {
167188
return string.trimmingCharacters(in: .whitespacesAndNewlines)
168189
}
169190

170-
private func createResponseFileIfNeeded(for job: Job, resolvedArguments: inout [String], forceResponseFiles: Bool) throws -> Bool {
191+
private func createResponseFileIfNeeded(for job: Job, resolvedArguments: inout [String], useResponseFiles: ResponseFileHandling) throws -> Bool {
171192
func quote(_ string: String) -> String {
172193
return "\"\(String(string.flatMap { ["\\", "\""].contains($0) ? "\\\($0)" : "\($0)" }))\""
173194
}
174-
195+
guard useResponseFiles != .disabled else {
196+
return false
197+
}
198+
199+
let forceResponseFiles = useResponseFiles == .forced
175200
if forceResponseFiles ||
176201
(job.supportsResponseFiles && !commandLineFitsWithinSystemLimits(path: resolvedArguments[0], args: resolvedArguments)) {
177202
assert(!forceResponseFiles || job.supportsResponseFiles,

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public extension Driver {
125125
if isSwiftScanLibAvailable {
126126
let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory!
127127
var command = try itemizedJobCommand(of: preScanJob,
128-
forceResponseFiles: forceResponseFiles,
128+
useResponseFiles: .disabled,
129129
using: executor.resolver)
130130
sanitizeCommandForLibScanInvocation(&command)
131131
imports =
@@ -154,7 +154,7 @@ public extension Driver {
154154
if isSwiftScanLibAvailable {
155155
let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory!
156156
var command = try itemizedJobCommand(of: scannerJob,
157-
forceResponseFiles: forceResponseFiles,
157+
useResponseFiles: .disabled,
158158
using: executor.resolver)
159159
sanitizeCommandForLibScanInvocation(&command)
160160
dependencyGraph =
@@ -183,7 +183,7 @@ public extension Driver {
183183
if isSwiftScanLibAvailable {
184184
let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory!
185185
var command = try itemizedJobCommand(of: batchScanningJob,
186-
forceResponseFiles: forceResponseFiles,
186+
useResponseFiles: .disabled,
187187
using: executor.resolver)
188188
sanitizeCommandForLibScanInvocation(&command)
189189
moduleVersionedGraphMap =
@@ -328,10 +328,10 @@ public extension Driver {
328328
contents)
329329
}
330330

331-
fileprivate func itemizedJobCommand(of job: Job, forceResponseFiles: Bool,
331+
fileprivate func itemizedJobCommand(of job: Job, useResponseFiles: ResponseFileHandling,
332332
using resolver: ArgsResolver) throws -> [String] {
333333
let (args, _) = try resolver.resolveArgumentList(for: job,
334-
forceResponseFiles: forceResponseFiles)
334+
useResponseFiles: useResponseFiles)
335335
return args
336336
}
337337
}

Sources/SwiftDriverExecution/MultiJobExecutor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ class ExecuteJobRule: LLBuildRule {
579579
var pid = 0
580580
do {
581581
let arguments: [String] = try resolver.resolveArgumentList(for: job,
582-
forceResponseFiles: context.forceResponseFiles)
582+
useResponseFiles: context.forceResponseFiles ? .forced : .heuristic)
583583

584584

585585
let process : ProcessProtocol

Sources/SwiftDriverExecution/SwiftDriverExecutor.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ public final class SwiftDriverExecutor: DriverExecutor {
3535
public func execute(job: Job,
3636
forceResponseFiles: Bool = false,
3737
recordedInputModificationDates: [TypedVirtualPath: Date] = [:]) throws -> ProcessResult {
38+
let useResponseFiles : ResponseFileHandling = forceResponseFiles ? .forced : .heuristic
3839
let arguments: [String] = try resolver.resolveArgumentList(for: job,
39-
forceResponseFiles: forceResponseFiles)
40+
useResponseFiles: useResponseFiles)
4041

4142
try job.verifyInputsNotModified(since: recordedInputModificationDates,
4243
fileSystem: fileSystem)
@@ -86,7 +87,8 @@ public final class SwiftDriverExecutor: DriverExecutor {
8687
}
8788

8889
public func description(of job: Job, forceResponseFiles: Bool) throws -> String {
89-
let (args, usedResponseFile) = try resolver.resolveArgumentList(for: job, forceResponseFiles: forceResponseFiles)
90+
let useResponseFiles : ResponseFileHandling = forceResponseFiles ? .forced : .heuristic
91+
let (args, usedResponseFile) = try resolver.resolveArgumentList(for: job, useResponseFiles: useResponseFiles)
9092
var result = args.map { $0.spm_shellEscaped() }.joined(separator: " ")
9193

9294
if usedResponseFile {

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,8 +1054,7 @@ final class ExplicitModuleBuildTests: XCTestCase {
10541054

10551055
let resolver = try ArgsResolver(fileSystem: localFileSystem)
10561056
let (args, _) = try resolver.resolveArgumentList(for: scannerJob,
1057-
forceResponseFiles: false,
1058-
quotePaths: true)
1057+
useResponseFiles: .disabled)
10591058
XCTAssertTrue(args.count > 1)
10601059
XCTAssertFalse(args[0].hasSuffix(".resp"))
10611060
}

Tests/SwiftDriverTests/ParsableMessageTests.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ final class ParsableMessageTests: XCTestCase {
150150
"-working-directory", workdir.pathString])
151151
let jobs = try driver.planBuild()
152152
let compileJob = jobs[0]
153-
let args : [String] = try resolver.resolveArgumentList(for: compileJob, forceResponseFiles: false)
153+
let args : [String] = try resolver.resolveArgumentList(for: compileJob, useResponseFiles: .disabled)
154154
let toolDelegate = ToolExecutionDelegate(mode: .parsableOutput,
155155
buildRecordInfo: nil,
156156
showJobLifecycle: false,
@@ -237,7 +237,7 @@ final class ParsableMessageTests: XCTestCase {
237237
"-working-directory", "/WorkDir"])
238238
let jobs = try driver.planBuild()
239239
compileJob = jobs[0]
240-
args = try resolver.resolveArgumentList(for: compileJob!, forceResponseFiles: false)
240+
args = try resolver.resolveArgumentList(for: compileJob!)
241241
toolDelegate = ToolExecutionDelegate(mode: .parsableOutput,
242242
buildRecordInfo: nil,
243243
showJobLifecycle: false,
@@ -313,8 +313,7 @@ final class ParsableMessageTests: XCTestCase {
313313
"-working-directory", "/WorkDir"])
314314
let jobs = try driver.planBuild()
315315
compileJob = jobs[0]
316-
args = try resolver.resolveArgumentList(for: compileJob!,
317-
forceResponseFiles: false)
316+
args = try resolver.resolveArgumentList(for: compileJob!)
318317
toolDelegate = ToolExecutionDelegate(mode: .parsableOutput,
319318
buildRecordInfo: nil,
320319
showJobLifecycle: false,

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ final class SwiftDriverTests: XCTestCase {
14851485
XCTAssertTrue(jobs.count == 1 && jobs[0].kind == .interpret)
14861486
let interpretJob = jobs[0]
14871487
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1488-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob, forceResponseFiles: false)
1488+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob)
14891489
XCTAssertTrue(resolvedArgs.count == 2)
14901490
XCTAssertEqual(resolvedArgs[1].first, "@")
14911491
let responseFilePath = try AbsolutePath(validating: String(resolvedArgs[1].dropFirst()))
@@ -1494,14 +1494,26 @@ final class SwiftDriverTests: XCTestCase {
14941494
XCTAssertTrue(contents.contains("\"-D\"\n\"TEST_20000\""))
14951495
XCTAssertTrue(contents.contains("\"-D\"\n\"TEST_1\""))
14961496
}
1497+
1498+
// Needs response file + disable override
1499+
do {
1500+
var driver = try Driver(args: ["swift"] + manyArgs + ["foo.swift"])
1501+
let jobs = try driver.planBuild()
1502+
XCTAssertTrue(jobs.count == 1 && jobs[0].kind == .interpret)
1503+
let interpretJob = jobs[0]
1504+
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1505+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob, useResponseFiles: .disabled)
1506+
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
1507+
}
1508+
14971509
// Forced response file
14981510
do {
14991511
var driver = try Driver(args: ["swift"] + ["foo.swift"])
15001512
let jobs = try driver.planBuild()
15011513
XCTAssertTrue(jobs.count == 1 && jobs[0].kind == .interpret)
15021514
let interpretJob = jobs[0]
15031515
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1504-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob, forceResponseFiles: true)
1516+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob, useResponseFiles: .forced)
15051517
XCTAssertTrue(resolvedArgs.count == 2)
15061518
XCTAssertEqual(resolvedArgs[1].first, "@")
15071519
let responseFilePath = try AbsolutePath(validating: String(resolvedArgs[1].dropFirst()))
@@ -1516,8 +1528,8 @@ final class SwiftDriverTests: XCTestCase {
15161528
XCTAssertTrue(jobs.count == 1 && jobs[0].kind == .interpret)
15171529
let interpretJob = jobs[0]
15181530
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1519-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob, forceResponseFiles: false)
1520-
XCTAssertFalse(resolvedArgs.map { $0.hasPrefix("@") }.reduce(false){ $0 || $1 })
1531+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob)
1532+
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
15211533
}
15221534
}
15231535

@@ -1539,15 +1551,15 @@ final class SwiftDriverTests: XCTestCase {
15391551

15401552
let emitModuleJob = jobs.first(where: { $0.kind == .emitModule })!
15411553
let emitModuleResolvedArgs: [String] =
1542-
try resolver.resolveArgumentList(for: emitModuleJob, forceResponseFiles: false)
1554+
try resolver.resolveArgumentList(for: emitModuleJob)
15431555
XCTAssertEqual(emitModuleResolvedArgs.count, 2)
15441556
XCTAssertEqual(emitModuleResolvedArgs[1].first, "@")
15451557

15461558
let compileJobs = jobs.filter { $0.kind == .compile }
15471559
for compileJob in compileJobs {
15481560
XCTAssertEqual(compileJobs.count, 2)
15491561
let compileResolvedArgs: [String] =
1550-
try resolver.resolveArgumentList(for: compileJob, forceResponseFiles: false)
1562+
try resolver.resolveArgumentList(for: compileJob)
15511563
XCTAssertEqual(compileResolvedArgs.count, 2)
15521564
XCTAssertEqual(compileResolvedArgs[1].first, "@")
15531565
}
@@ -1565,15 +1577,15 @@ final class SwiftDriverTests: XCTestCase {
15651577

15661578
let mergeModuleJob = jobs.first(where: { $0.kind == .mergeModule })!
15671579
let mergeModuleResolvedArgs: [String] =
1568-
try resolver.resolveArgumentList(for: mergeModuleJob, forceResponseFiles: false)
1580+
try resolver.resolveArgumentList(for: mergeModuleJob)
15691581
XCTAssertEqual(mergeModuleResolvedArgs.count, 2)
15701582
XCTAssertEqual(mergeModuleResolvedArgs[1].first, "@")
15711583

15721584
let compileJobs = jobs.filter { $0.kind == .compile }
15731585
for compileJob in compileJobs {
15741586
XCTAssertEqual(compileJobs.count, 2)
15751587
let compileResolvedArgs: [String] =
1576-
try resolver.resolveArgumentList(for: compileJob, forceResponseFiles: false)
1588+
try resolver.resolveArgumentList(for: compileJob)
15771589
XCTAssertEqual(compileResolvedArgs.count, 2)
15781590
XCTAssertEqual(compileResolvedArgs[1].first, "@")
15791591
}
@@ -1590,7 +1602,7 @@ final class SwiftDriverTests: XCTestCase {
15901602

15911603
let generatePCMJob = jobs[0]
15921604
let generatePCMResolvedArgs: [String] =
1593-
try resolver.resolveArgumentList(for: generatePCMJob, forceResponseFiles: false)
1605+
try resolver.resolveArgumentList(for: generatePCMJob)
15941606
XCTAssertEqual(generatePCMResolvedArgs.count, 2)
15951607
XCTAssertEqual(generatePCMResolvedArgs[1].first, "@")
15961608
}

0 commit comments

Comments
 (0)