Merge nucleic/mellow-dewy-falcon-rjhr into main

This commit is contained in:
2026-08-07 03:12:18 -07:00
parent e7163de22f
commit adb7dedd80
5 changed files with 292 additions and 30 deletions
+31 -8
View File
@@ -136,6 +136,7 @@ final class OnceFlag: @unchecked Sendable {
final class ProgressPrinter: @unchecked Sendable {
private let lock = NSLock()
private var lastLine = ""
private var lastGroup: String?
/// Whether carriage-return rewriting means anything here.
///
@@ -147,17 +148,31 @@ final class ProgressPrinter: @unchecked Sendable {
private let isInteractive = isatty(fileno(stderr)) == 1
/// Rewrites the current line.
func update(_ line: String) {
///
/// - Parameters:
/// - line: The text to show.
/// - group: Names the stage this line belongs to. When it changes, the
/// outgoing stage's final line is sealed with a newline rather than
/// overwritten — so `installing macOS [####] 100%` is still on screen
/// when the operator scrolls back to work out where the last hour went,
/// instead of being replaced by whatever came next.
func update(_ line: String, group: String? = nil) {
lock.lock()
defer { lock.unlock() }
if let group, let lastGroup, group != lastGroup, !lastLine.isEmpty, isInteractive {
emit("\n")
lastLine = ""
}
if let group { lastGroup = group }
guard line != lastLine else { return }
lastLine = line
guard isInteractive else {
FileHandle.standardError.write(Data((line + "\n").utf8))
emit(line + "\n")
return
}
let padding = String(repeating: " ", count: max(0, 78 - line.count))
FileHandle.standardError.write(Data(("\r" + line + padding).utf8))
emit("\r" + line + pad(line))
}
/// Emits a standalone line without losing the status line under it.
@@ -177,12 +192,20 @@ final class ProgressPrinter: @unchecked Sendable {
lock.lock()
defer { lock.unlock() }
if let line {
let padding = isInteractive ? String(repeating: " ", count: max(0, 78 - line.count)) : ""
let prefix = isInteractive ? "\r" : ""
FileHandle.standardError.write(Data((prefix + line + padding + "\n").utf8))
emit((isInteractive ? "\r" : "") + line + (isInteractive ? pad(line) : "") + "\n")
} else if !lastLine.isEmpty, isInteractive {
FileHandle.standardError.write(Data("\n".utf8))
emit("\n")
}
lastLine = ""
}
/// Trailing blanks that erase whatever the previous, longer line left behind.
private func pad(_ line: String) -> String {
String(repeating: " ", count: max(0, 78 - line.count))
}
/// Writes straight to the descriptor. Call with ``lock`` held.
private func emit(_ text: String) {
FileHandle.standardError.write(Data(text.utf8))
}
}