Nucleic: Gitea Runner macOS VM Support
This commit is contained in:
@@ -137,24 +137,50 @@ final class ProgressPrinter: @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
private var lastLine = ""
|
||||
|
||||
/// Whether carriage-return rewriting means anything here.
|
||||
///
|
||||
/// Piped to a file or captured by `launchd`, `\r` produces one unreadable
|
||||
/// mega-line, so each update becomes its own line instead. `FileHandle`
|
||||
/// writes go straight to the descriptor either way — there is no buffer to
|
||||
/// flush, which is what makes a stall attributable to the stage last
|
||||
/// printed rather than to output sitting unwritten.
|
||||
private let isInteractive = isatty(fileno(stderr)) == 1
|
||||
|
||||
/// Rewrites the current line.
|
||||
func update(_ line: String) {
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
guard line != lastLine else { return }
|
||||
lastLine = line
|
||||
guard isInteractive else {
|
||||
FileHandle.standardError.write(Data((line + "\n").utf8))
|
||||
return
|
||||
}
|
||||
let padding = String(repeating: " ", count: max(0, 78 - line.count))
|
||||
FileHandle.standardError.write(Data(("\r" + line + padding).utf8))
|
||||
}
|
||||
|
||||
/// Emits a standalone line without losing the status line under it.
|
||||
func line(_ text: String) {
|
||||
lock.lock()
|
||||
let carried = lastLine
|
||||
lock.unlock()
|
||||
|
||||
finish(text)
|
||||
if !carried.isEmpty {
|
||||
update(carried)
|
||||
}
|
||||
}
|
||||
|
||||
/// Ends the line so subsequent output starts cleanly.
|
||||
func finish(_ line: String? = nil) {
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
if let line {
|
||||
let padding = String(repeating: " ", count: max(0, 78 - line.count))
|
||||
FileHandle.standardError.write(Data(("\r" + line + padding + "\n").utf8))
|
||||
} else if !lastLine.isEmpty {
|
||||
let padding = isInteractive ? String(repeating: " ", count: max(0, 78 - line.count)) : ""
|
||||
let prefix = isInteractive ? "\r" : ""
|
||||
FileHandle.standardError.write(Data((prefix + line + padding + "\n").utf8))
|
||||
} else if !lastLine.isEmpty, isInteractive {
|
||||
FileHandle.standardError.write(Data("\n".utf8))
|
||||
}
|
||||
lastLine = ""
|
||||
|
||||
Reference in New Issue
Block a user