Fix stdin timeout flakiness

This commit is contained in:
Nick Lockwood
2019-12-26 00:08:54 +00:00
parent 51f86e4b8f
commit d1c39f04ef
+41 -30
View File
@@ -477,52 +477,63 @@ func processArguments(_ args: [String], in directory: String) -> ExitCode {
}
}
enum Status {
case idle, started, finished(Error?)
}
// If no input file, try stdin
if inputURLs.isEmpty {
var input: String?
var finished = false
var fatalError: Error?
var status = Status.idle
DispatchQueue.global(qos: .userInitiated).async {
status = .started
while let line = CLI.readLine() {
input = (input ?? "") + line
}
if let input = input {
do {
if args["inferoptions"] != nil {
let tokens = tokenize(input)
var options = options
options.formatOptions = inferFormatOptions(from: tokens)
try serializeOptions(options, to: outputURL)
} else if let outputURL = outputURL {
printRunningMessage()
let output = try applyRules(input, options: options, verbose: verbose, lint: lint)
if (try? String(contentsOf: outputURL)) != output, !dryrun {
do {
try output.write(to: outputURL, atomically: true, encoding: .utf8)
} catch {
throw FormatError.writing("Failed to write file \(outputURL.path)")
}
guard let input = input else {
status = .finished(nil)
return
}
do {
if args["inferoptions"] != nil {
let tokens = tokenize(input)
var options = options
options.formatOptions = inferFormatOptions(from: tokens)
try serializeOptions(options, to: outputURL)
} else if let outputURL = outputURL {
printRunningMessage()
let output = try applyRules(input, options: options, verbose: verbose, lint: lint)
if (try? String(contentsOf: outputURL)) != output, !dryrun {
do {
try output.write(to: outputURL, atomically: true, encoding: .utf8)
} catch {
throw FormatError.writing("Failed to write file \(outputURL.path)")
}
print("Swiftformat completed successfully.", as: .success)
} else {
// Write to stdout
let output = try applyRules(input, options: options, verbose: verbose, lint: lint)
print(output, as: .raw)
}
} catch {
fatalError = error
print("Swiftformat completed successfully.", as: .success)
} else {
// Write to stdout
let output = try applyRules(input, options: options, verbose: verbose, lint: lint)
print(output, as: .raw)
}
status = .finished(nil)
} catch {
status = .finished(error)
}
finished = true
}
// Wait for input
while case .idle = status {}
let start = NSDate()
while start.timeIntervalSinceNow > -0.01 {}
while input == nil, start.timeIntervalSinceNow > -0.2 {}
// If no input received by now, assume none is coming
if input != nil {
while !finished, start.timeIntervalSinceNow > -30 {}
if let fatalError = fatalError {
throw fatalError
while start.timeIntervalSinceNow > -30 {
if case let .finished(error) = status {
if let error = error {
throw error
}
break
}
}
} else if args["inferoptions"] != nil {
throw FormatError.options("--inferoptions requires one or more input files")