Skip to content

Commit 3a5d055

Browse files
CyanChangesshigma
andcommitted
feat(market): support yarn json output (#294)
Co-authored-by: Shigma <[email protected]>
1 parent 498e486 commit 3a5d055

File tree

1 file changed

+45
-12
lines changed

1 file changed

+45
-12
lines changed

plugins/market/src/node/installer.ts

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@ export interface Dependency {
3232
latest?: string
3333
}
3434

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+
3549
export interface LocalPackage extends PackageJson {
3650
private?: boolean
3751
$workspace?: boolean
@@ -58,7 +72,7 @@ class Installer extends Service {
5872
public tempCache: Dict<Dict<Pick<RemotePackage, DependencyMetaKey>>> = {}
5973

6074
private pkgTasks: Dict<Promise<Dict<Pick<RemotePackage, DependencyMetaKey>>>> = {}
61-
private agent = which()?.name || 'npm'
75+
private agent = which()
6276
private manifest: PackageJson
6377
private depTask: Promise<Dict<Dependency>>
6478
private flushData: () => void
@@ -171,23 +185,43 @@ class Installer extends Service {
171185
this.refreshData()
172186
}
173187

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')
175192
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 })
177195
child.on('exit', (code) => resolve(code))
178196
child.on('error', () => resolve(-1))
197+
198+
let stderr = ''
179199
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) {
183204
logger.warn(line)
184205
}
185206
})
207+
208+
let stdout = ''
186209
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+
}
191225
}
192226
})
193227
})
@@ -208,11 +242,10 @@ class Installer extends Service {
208242

209243
private _install() {
210244
const args: string[] = []
211-
if (this.agent !== 'yarn') args.push('install')
212245
if (this.config.endpoint) {
213246
args.push('--registry', this.endpoint)
214247
}
215-
return this.exec(this.agent, args)
248+
return this.exec(args)
216249
}
217250

218251
private _getLocalDeps(override: Dict<string>) {

0 commit comments

Comments
 (0)