@@ -32,6 +32,20 @@ export interface Dependency {
32
32
latest ?: string
33
33
}
34
34
35
+ export interface YarnLog {
36
+ type : 'warning' | 'info' | 'error' | string
37
+ name : number | null
38
+ displayName : string
39
+ indent ?: string
40
+ data : string
41
+ }
42
+
43
+ const levelMap = {
44
+ 'info' : 'info' ,
45
+ 'warning' : 'debug' ,
46
+ 'error' : 'warn' ,
47
+ }
48
+
35
49
export interface LocalPackage extends PackageJson {
36
50
private ?: boolean
37
51
$workspace ?: boolean
@@ -58,7 +72,7 @@ class Installer extends Service {
58
72
public tempCache : Dict < Dict < Pick < RemotePackage , DependencyMetaKey > > > = { }
59
73
60
74
private pkgTasks : Dict < Promise < Dict < Pick < RemotePackage , DependencyMetaKey > > > > = { }
61
- private agent = which ( ) ?. name || 'npm'
75
+ private agent = which ( )
62
76
private manifest : PackageJson
63
77
private depTask : Promise < Dict < Dependency > >
64
78
private flushData : ( ) => void
@@ -171,23 +185,43 @@ class Installer extends Service {
171
185
this . refreshData ( )
172
186
}
173
187
174
- async exec ( command : string , args : string [ ] ) {
188
+ async exec ( args : string [ ] ) {
189
+ const name = this . agent ?. name ?? 'npm'
190
+ const useJson = name === 'yarn' && this . agent . version >= '2'
191
+ if ( name !== 'yarn' ) args . unshift ( 'install' )
175
192
return new Promise < number > ( ( resolve ) => {
176
- const child = spawn ( command , args , { cwd : this . cwd } )
193
+ if ( useJson ) args . push ( '--json' )
194
+ const child = spawn ( name , args , { cwd : this . cwd } )
177
195
child . on ( 'exit' , ( code ) => resolve ( code ) )
178
196
child . on ( 'error' , ( ) => resolve ( - 1 ) )
197
+
198
+ let stderr = ''
179
199
child . stderr . on ( 'data' , ( data ) => {
180
- data = data . toString ( ) . trim ( )
181
- if ( ! data ) return
182
- for ( const line of data . split ( '\n' ) ) {
200
+ data = stderr + data . toString ( )
201
+ const lines = data . split ( '\n' )
202
+ stderr = lines . pop ( ) !
203
+ for ( const line of lines ) {
183
204
logger . warn ( line )
184
205
}
185
206
} )
207
+
208
+ let stdout = ''
186
209
child . stdout . on ( 'data' , ( data ) => {
187
- data = data . toString ( ) . trim ( )
188
- if ( ! data ) return
189
- for ( const line of data . split ( '\n' ) ) {
190
- logger . info ( line )
210
+ data = stdout + data . toString ( )
211
+ const lines = data . split ( '\n' )
212
+ stdout = lines . pop ( ) !
213
+ for ( const line of lines ) {
214
+ if ( ! useJson ) {
215
+ logger . info ( line )
216
+ continue
217
+ }
218
+ try {
219
+ const { type, data } = JSON . parse ( line ) as YarnLog
220
+ logger [ levelMap [ type ] ?? 'info' ] ( data )
221
+ } catch ( error ) {
222
+ logger . warn ( line )
223
+ logger . warn ( error )
224
+ }
191
225
}
192
226
} )
193
227
} )
@@ -208,11 +242,10 @@ class Installer extends Service {
208
242
209
243
private _install ( ) {
210
244
const args : string [ ] = [ ]
211
- if ( this . agent !== 'yarn' ) args . push ( 'install' )
212
245
if ( this . config . endpoint ) {
213
246
args . push ( '--registry' , this . endpoint )
214
247
}
215
- return this . exec ( this . agent , args )
248
+ return this . exec ( args )
216
249
}
217
250
218
251
private _getLocalDeps ( override : Dict < string > ) {
0 commit comments