@@ -12,6 +12,9 @@ import { formatIpcMatches } from '../util/formatMatches'
12
12
import { AstxWorkerPool , astxCosmiconfig } from '../node'
13
13
import { invertIpcError } from '../node/ipc'
14
14
import { Transform } from '../Astx'
15
+ import ansiEscapes from 'ansi-escapes'
16
+ import { Progress } from '../node/AstxWorkerPool'
17
+ import { spinner } from './spinner'
15
18
16
19
/* eslint-disable no-console */
17
20
@@ -64,6 +67,8 @@ const transform: CommandModule<Options> = {
64
67
} ) ,
65
68
66
69
handler : async ( argv : Arguments < Options > ) => {
70
+ const startTime = Date . now ( )
71
+
67
72
const paths = ( argv . filesAndDirectories || [ ] ) . filter (
68
73
( x ) => typeof x === 'string'
69
74
) as string [ ]
@@ -93,91 +98,133 @@ const transform: CommandModule<Options> = {
93
98
let errorCount = 0
94
99
let changedCount = 0
95
100
let unchangedCount = 0
101
+
102
+ let progress : Progress = {
103
+ type : 'progress' ,
104
+ completed : 0 ,
105
+ total : 0 ,
106
+ globDone : false ,
107
+ }
108
+
109
+ let progressDisplayed = false
110
+ function clearProgress ( ) {
111
+ if ( progressDisplayed ) {
112
+ process . stderr . write ( ansiEscapes . cursorLeft + ansiEscapes . eraseLine )
113
+ progressDisplayed = false
114
+ }
115
+ }
116
+ function showProgress ( ) {
117
+ clearProgress ( )
118
+ progressDisplayed = true
119
+ const { completed, total, globDone } = progress
120
+ process . stderr . write (
121
+ chalk . magenta (
122
+ `${ spinner ( ) } Running... ${ completed } /${ total } ${
123
+ globDone && total
124
+ ? ` (${ ( ( completed * 100 ) / total ) . toFixed ( 1 ) } %)`
125
+ : ''
126
+ } ${ ( ( Date . now ( ) - startTime ) / 1000 ) . toFixed ( 2 ) } s`
127
+ )
128
+ )
129
+ }
130
+ let spinnerInterval
131
+
96
132
const config = ( await astxCosmiconfig . search ( ) ) ?. config
97
133
const pool = new AstxWorkerPool ( { capacity : config ?. workers } )
98
- for await ( const event of pool . runTransform ( {
99
- transform,
100
- transformFile,
101
- paths,
102
- config : {
103
- parser : parser as any ,
104
- parserOptions : parserOptions ? JSON . parse ( parserOptions ) : undefined ,
105
- } ,
106
- } ) ) {
107
- if ( event . type === 'progress' ) {
108
- continue
134
+ try {
135
+ if ( process . stderr . isTTY ) {
136
+ spinnerInterval = setInterval ( showProgress , 30 )
109
137
}
110
- const {
111
- file,
112
- source,
113
- transformed,
114
- reports,
115
- matches,
116
- error : _error ,
117
- } = event . result
118
- const error = _error ? invertIpcError ( _error ) : undefined
119
- const relpath = path . relative ( process . cwd ( ) , file )
120
- const logHeader = once ( ( logFn : ( value : string ) => any ) =>
121
- logFn (
122
- chalk . blue ( dedent `
138
+ for await ( const event of pool . runTransform ( {
139
+ transform,
140
+ transformFile,
141
+ paths,
142
+ config : {
143
+ parser : parser as any ,
144
+ parserOptions : parserOptions ? JSON . parse ( parserOptions ) : undefined ,
145
+ } ,
146
+ } ) ) {
147
+ if ( event . type === 'progress' ) {
148
+ progress = event
149
+ if ( process . stderr . isTTY ) showProgress ( )
150
+ continue
151
+ }
152
+ clearProgress ( )
153
+ const {
154
+ file,
155
+ source,
156
+ transformed,
157
+ reports,
158
+ matches,
159
+ error : _error ,
160
+ } = event . result
161
+ const error = _error ? invertIpcError ( _error ) : undefined
162
+ const relpath = path . relative ( process . cwd ( ) , file )
163
+ const logHeader = once ( ( logFn : ( value : string ) => any ) =>
164
+ logFn (
165
+ chalk . blue ( dedent `
123
166
${ '=' . repeat ( relpath . length ) }
124
167
${ chalk . bold ( relpath ) }
125
168
${ '=' . repeat ( relpath . length ) }
126
169
` )
170
+ )
127
171
)
128
- )
129
172
130
- if ( error ) {
131
- errorCount ++
132
- logHeader ( console . error )
133
- if ( error instanceof CodeFrameError ) {
134
- console . error (
135
- error . format ( {
136
- highlightCode : true ,
137
- forceColor : true ,
138
- stack : true ,
139
- } )
140
- )
141
- } else {
142
- console . error ( chalk . red ( error . stack ) )
143
- }
144
- } else if ( source && transformed && source !== transformed ) {
145
- changedCount ++
146
- results [ file ] = transformed
147
- if ( ! argv . yes ) {
173
+ if ( error ) {
174
+ errorCount ++
175
+ logHeader ( console . error )
176
+ if ( error instanceof CodeFrameError ) {
177
+ console . error (
178
+ error . format ( {
179
+ highlightCode : true ,
180
+ forceColor : true ,
181
+ stack : true ,
182
+ } )
183
+ )
184
+ } else {
185
+ console . error ( chalk . red ( error . stack ) )
186
+ }
187
+ } else if ( source && transformed && source !== transformed ) {
188
+ changedCount ++
189
+ results [ file ] = transformed
190
+ if ( ! argv . yes ) {
191
+ logHeader ( console . log )
192
+ console . log ( formatDiff ( source , transformed ) )
193
+ }
194
+ } else if (
195
+ matches ?. length &&
196
+ source &&
197
+ transform . find &&
198
+ ! transform . replace &&
199
+ ! transform . astx
200
+ ) {
148
201
logHeader ( console . log )
149
- console . log ( formatDiff ( source , transformed ) )
202
+ console . log ( formatIpcMatches ( source , matches ) )
203
+ } else {
204
+ unchangedCount ++
150
205
}
151
- } else if (
152
- matches ?. length &&
153
- source &&
154
- transform . find &&
155
- ! transform . replace &&
156
- ! transform . astx
157
- ) {
158
- logHeader ( console . log )
159
- console . log ( formatIpcMatches ( source , matches ) )
160
- } else {
161
- unchangedCount ++
162
- }
163
206
164
- if ( reports ?. length ) {
165
- logHeader ( console . error )
166
- console . error (
167
- chalk . blue ( dedent `
207
+ if ( reports ?. length ) {
208
+ logHeader ( console . error )
209
+ console . error (
210
+ chalk . blue ( dedent `
168
211
Reports
169
212
-------
170
213
` )
171
- )
172
- reports ?. forEach ( ( r : any ) =>
173
- console . error (
174
- // r instanceof Astx && source
175
- // ? formatIpcMatches(source, r.matches)
176
- // : r
177
- r
178
214
)
179
- )
215
+ reports ?. forEach ( ( r : any ) =>
216
+ console . error (
217
+ // r instanceof Astx && source
218
+ // ? formatIpcMatches(source, r.matches)
219
+ // : r
220
+ r
221
+ )
222
+ )
223
+ }
180
224
}
225
+ } finally {
226
+ if ( spinnerInterval != null ) clearInterval ( spinnerInterval )
227
+ clearProgress ( )
181
228
}
182
229
183
230
if ( transform . replace || transform . astx ) {
0 commit comments