From 3a5d0558efc7f98898981ba7c667d347eb615e48 Mon Sep 17 00:00:00 2001 From: Cyan Date: Thu, 1 Feb 2024 01:46:38 +0800 Subject: [PATCH] feat(market): support yarn json output (#294) Co-authored-by: Shigma --- plugins/market/src/node/installer.ts | 57 ++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/plugins/market/src/node/installer.ts b/plugins/market/src/node/installer.ts index 0083bd19..b2181277 100644 --- a/plugins/market/src/node/installer.ts +++ b/plugins/market/src/node/installer.ts @@ -32,6 +32,20 @@ export interface Dependency { latest?: string } +export interface YarnLog { + type: 'warning' | 'info' | 'error' | string + name: number | null + displayName: string + indent?: string + data: string +} + +const levelMap = { + 'info': 'info', + 'warning': 'debug', + 'error': 'warn', +} + export interface LocalPackage extends PackageJson { private?: boolean $workspace?: boolean @@ -58,7 +72,7 @@ class Installer extends Service { public tempCache: Dict>> = {} private pkgTasks: Dict>>> = {} - private agent = which()?.name || 'npm' + private agent = which() private manifest: PackageJson private depTask: Promise> private flushData: () => void @@ -171,23 +185,43 @@ class Installer extends Service { this.refreshData() } - async exec(command: string, args: string[]) { + async exec(args: string[]) { + const name = this.agent?.name ?? 'npm' + const useJson = name === 'yarn' && this.agent.version >= '2' + if (name !== 'yarn') args.unshift('install') return new Promise((resolve) => { - const child = spawn(command, args, { cwd: this.cwd }) + if (useJson) args.push('--json') + const child = spawn(name, args, { cwd: this.cwd }) child.on('exit', (code) => resolve(code)) child.on('error', () => resolve(-1)) + + let stderr = '' child.stderr.on('data', (data) => { - data = data.toString().trim() - if (!data) return - for (const line of data.split('\n')) { + data = stderr + data.toString() + const lines = data.split('\n') + stderr = lines.pop()! + for (const line of lines) { logger.warn(line) } }) + + let stdout = '' child.stdout.on('data', (data) => { - data = data.toString().trim() - if (!data) return - for (const line of data.split('\n')) { - logger.info(line) + data = stdout + data.toString() + const lines = data.split('\n') + stdout = lines.pop()! + for (const line of lines) { + if (!useJson) { + logger.info(line) + continue + } + try { + const { type, data } = JSON.parse(line) as YarnLog + logger[levelMap[type] ?? 'info'](data) + } catch (error) { + logger.warn(line) + logger.warn(error) + } } }) }) @@ -208,11 +242,10 @@ class Installer extends Service { private _install() { const args: string[] = [] - if (this.agent !== 'yarn') args.push('install') if (this.config.endpoint) { args.push('--registry', this.endpoint) } - return this.exec(this.agent, args) + return this.exec(args) } private _getLocalDeps(override: Dict) {