Skip to content

Commit e01d706

Browse files
committed
Add 'resolveArgumentList' API which contains original command-line if a response file is used
1 parent 051e0a3 commit e01d706

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
@@ -1806,37 +1806,38 @@ final class SwiftDriverTests: XCTestCase {
18061806
}
18071807
}
18081808

1809-
// No response file
1809+
// Response file query with full command-line API
18101810
do {
1811-
var driver = try Driver(args: ["swift"] + ["foo.swift"])
1811+
let source = try AbsolutePath(validating: "/foo.swift")
1812+
var driver = try Driver(args: ["swift"] + [source.nativePathString(escaped: false)])
18121813
let jobs = try driver.planBuild()
18131814
XCTAssertEqual(jobs.count, 1)
18141815
XCTAssertEqual(jobs[0].kind, .interpret)
18151816
let interpretJob = jobs[0]
18161817
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1817-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob)
1818-
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
1818+
let resolved: ResolvedCommandLine = try resolver.resolveArgumentList(for: interpretJob, useResponseFiles: .forced)
1819+
guard case .usingResponseFile(resolved: let resolvedArgs, responseFileContents: let contents) = resolved else {
1820+
XCTFail("Argument wasn't a response file")
1821+
return
1822+
}
1823+
XCTAssertEqual(resolvedArgs.count, 3)
1824+
XCTAssertEqual(resolvedArgs[1], "-frontend")
1825+
XCTAssertEqual(resolvedArgs[2].first, "@")
1826+
1827+
XCTAssertTrue(contents.contains(subsequence: ["-frontend", "-interpret"]))
1828+
XCTAssertTrue(contents.contains(subsequence: ["-module-name", "foo"]))
18191829
}
1820-
}
18211830

1822-
func testResponseFileDeterministicNaming() throws {
1823-
#if !os(macOS)
1824-
try XCTSkipIf(true, "Test assumes macOS response file quoting behavior")
1825-
#endif
1831+
// No response file
18261832
do {
1827-
let testJob = Job(moduleName: "Foo",
1828-
kind: .compile,
1829-
tool: .init(path: try AbsolutePath(validating: "/swiftc"), supportsResponseFiles: true),
1830-
commandLine: (1...20000).map { .flag("-DTEST_\($0)") },
1831-
inputs: [],
1832-
primaryInputs: [],
1833-
outputs: [])
1833+
var driver = try Driver(args: ["swift"] + ["foo.swift"])
1834+
let jobs = try driver.planBuild()
1835+
XCTAssertEqual(jobs.count, 1)
1836+
XCTAssertEqual(jobs[0].kind, .interpret)
1837+
let interpretJob = jobs[0]
18341838
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1835-
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: testJob)
1836-
XCTAssertEqual(resolvedArgs.count, 3)
1837-
XCTAssertEqual(resolvedArgs[2].first, "@")
1838-
let responseFilePath = try AbsolutePath(validating: String(resolvedArgs[2].dropFirst()))
1839-
XCTAssertEqual(responseFilePath.basename, "arguments-847d15e70d97df7c18033735497ca8dcc4441f461d5a9c2b764b127004524e81.resp")
1839+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: interpretJob)
1840+
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
18401841
}
18411842
}
18421843

0 commit comments

Comments
 (0)