Skip to content

Commit 91ce741

Browse files
committed
Add 'resolveArgumentList' API which contains original command-line if a response file is used
1 parent 1eca355 commit 91ce741

File tree

2 files changed

+39
-21
lines changed

2 files changed

+39
-21
lines changed

Sources/SwiftDriver/Execution/ArgsResolver.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public enum ResponseFileHandling {
2626
case heuristic
2727
}
2828

29+
public enum ResolvedCommandLine {
30+
case plain([String])
31+
case usingResponseFile(resolved: [String], responseFileContents: [String])
32+
}
33+
2934
/// Resolver for a job's argument template.
3035
public final class ArgsResolver {
3136
/// The map of virtual path to the actual path.
@@ -76,6 +81,18 @@ public final class ArgsResolver {
7681
return (arguments, usingResponseFile)
7782
}
7883

84+
public func resolveArgumentList(for job: Job, useResponseFiles: ResponseFileHandling = .heuristic)
85+
throws -> ResolvedCommandLine {
86+
let tool = try resolve(.path(job.tool))
87+
let resolvedArguments = [tool] + (try resolveArgumentList(for: job.commandLine))
88+
var actualArguments = resolvedArguments
89+
let usingResponseFile = try createResponseFileIfNeeded(for: job, resolvedArguments: &actualArguments,
90+
useResponseFiles: useResponseFiles)
91+
return usingResponseFile ? .usingResponseFile(resolved: actualArguments,
92+
responseFileContents: resolvedArguments)
93+
: .plain(actualArguments)
94+
}
95+
7996
public func resolveArgumentList(for commandLine: [Job.ArgTemplate]) throws -> [String] {
8097
return try commandLine.map { try resolve($0) }
8198
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,37 +1840,38 @@ final class SwiftDriverTests: XCTestCase {
18401840
}
18411841
}
18421842

1843-
// No response file
1843+
// Response file query with full command-line API
18441844
do {
1845-
var driver = try Driver(args: ["swift"] + ["foo.swift"])
1845+
let source = try AbsolutePath(validating: "/foo.swift")
1846+
var driver = try Driver(args: ["swift"] + [source.nativePathString(escaped: false)])
18461847
let jobs = try driver.planBuild()
18471848
XCTAssertEqual(jobs.count, 1)
18481849
XCTAssertEqual(jobs[0].kind, .interpret)
18491850
let interpretJob = jobs[0]
18501851
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1851-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob)
1852-
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
1852+
let resolved: ResolvedCommandLine = try resolver.resolveArgumentList(for: interpretJob, useResponseFiles: .forced)
1853+
guard case .usingResponseFile(resolved: let resolvedArgs, responseFileContents: let contents) = resolved else {
1854+
XCTFail("Argument wasn't a response file")
1855+
return
1856+
}
1857+
XCTAssertEqual(resolvedArgs.count, 3)
1858+
XCTAssertEqual(resolvedArgs[1], "-frontend")
1859+
XCTAssertEqual(resolvedArgs[2].first, "@")
1860+
1861+
XCTAssertTrue(contents.contains(subsequence: ["-frontend", "-interpret"]))
1862+
XCTAssertTrue(contents.contains(subsequence: ["-module-name", "foo"]))
18531863
}
1854-
}
18551864

1856-
func testResponseFileDeterministicNaming() throws {
1857-
#if !os(macOS)
1858-
try XCTSkipIf(true, "Test assumes macOS response file quoting behavior")
1859-
#endif
1865+
// No response file
18601866
do {
1861-
let testJob = Job(moduleName: "Foo",
1862-
kind: .compile,
1863-
tool: .init(path: try AbsolutePath(validating: "/swiftc"), supportsResponseFiles: true),
1864-
commandLine: (1...20000).map { .flag("-DTEST_\($0)") },
1865-
inputs: [],
1866-
primaryInputs: [],
1867-
outputs: [])
1867+
var driver = try Driver(args: ["swift"] + ["foo.swift"])
1868+
let jobs = try driver.planBuild()
1869+
XCTAssertEqual(jobs.count, 1)
1870+
XCTAssertEqual(jobs[0].kind, .interpret)
1871+
let interpretJob = jobs[0]
18681872
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1869-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: testJob)
1870-
XCTAssertEqual(resolvedArgs.count, 3)
1871-
XCTAssertEqual(resolvedArgs[2].first, "@")
1872-
let responseFilePath = try AbsolutePath(validating: String(resolvedArgs[2].dropFirst()))
1873-
XCTAssertEqual(responseFilePath.basename, "arguments-847d15e70d97df7c18033735497ca8dcc4441f461d5a9c2b764b127004524e81.resp")
1873+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob)
1874+
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
18741875
}
18751876
}
18761877

0 commit comments

Comments
 (0)