@@ -18,14 +18,15 @@ extension ProgressAnimation {
1818 @_spi ( SwiftPMInternal)
1919 public static func ninja(
2020 stream: WritableByteStream ,
21- verbose: Bool
21+ verbose: Bool ,
22+ normalizeStep: Bool = true
2223 ) -> any ProgressAnimationProtocol {
2324 Self . dynamic (
2425 stream: stream,
2526 verbose: verbose,
26- ttyTerminalAnimationFactory: { RedrawingNinjaProgressAnimation ( terminal: $0) } ,
27+ ttyTerminalAnimationFactory: { RedrawingNinjaProgressAnimation ( terminal: $0, normalizeStep : normalizeStep ) } ,
2728 dumbTerminalAnimationFactory: { SingleLinePercentProgressAnimation ( stream: stream, header: nil ) } ,
28- defaultAnimationFactory: { MultiLineNinjaProgressAnimation ( stream: stream) }
29+ defaultAnimationFactory: { MultiLineNinjaProgressAnimation ( stream: stream, normalizeStep : normalizeStep ) }
2930 )
3031 }
3132}
@@ -34,17 +35,24 @@ extension ProgressAnimation {
3435final class RedrawingNinjaProgressAnimation : ProgressAnimationProtocol {
3536 private let terminal : TerminalController
3637 private var hasDisplayedProgress = false
38+ private let normalizeStep : Bool
3739
38- init ( terminal: TerminalController ) {
40+ init ( terminal: TerminalController , normalizeStep : Bool ) {
3941 self . terminal = terminal
42+ self . normalizeStep = normalizeStep
4043 }
4144
4245 func update( step: Int , total: Int , text: String ) {
4346 assert ( step <= total)
4447
4548 terminal. clearLine ( )
46-
47- let progressText = " [ \( step) / \( total) ] \( text) "
49+ var progressText = " "
50+ if step < 0 && normalizeStep {
51+ let normalizedStep = max ( 0 , step)
52+ progressText = " [ \( normalizedStep) / \( total) ] \( text) "
53+ } else {
54+ progressText = " \( text) "
55+ }
4856 let width = terminal. width
4957 if progressText. utf8. count > width {
5058 let suffix = " … "
@@ -78,17 +86,24 @@ final class MultiLineNinjaProgressAnimation: ProgressAnimationProtocol {
7886
7987 private let stream : WritableByteStream
8088 private var lastDisplayedText : String ? = nil
89+ private let normalizeStep : Bool
8190
82- init ( stream: WritableByteStream ) {
91+ init ( stream: WritableByteStream , normalizeStep : Bool ) {
8392 self . stream = stream
93+ self . normalizeStep = normalizeStep
8494 }
8595
8696 func update( step: Int , total: Int , text: String ) {
8797 assert ( step <= total)
8898
8999 guard text != lastDisplayedText else { return }
90100
91- stream. send ( " [ \( step) / \( total) ] " ) . send ( text)
101+ if step < 0 && normalizeStep {
102+ let normalizedStep = max ( 0 , step)
103+ stream. send ( " [ \( normalizedStep) / \( total) ] " )
104+ }
105+
106+ stream. send ( text)
92107 stream. send ( " \n " )
93108 stream. flush ( )
94109 lastDisplayedText = text
0 commit comments