1- const readline = require ( 'readline' )
2- const stripAnsi = require ( 'strip-ansi' )
31const spawn = require ( 'cross-spawn' )
4- const wcwidth = require ( 'wcwidth ' )
2+ const logUpdate = require ( 'log-update ' )
53const spinner = require ( './spinner' )
64const logger = require ( './logger' )
75const SAOError = require ( './SAOError' )
86
97let cachedNpmClient = null
108
119function setNpmClient ( npmClient ) {
12- if ( npmClient ) {
13- cachedNpmClient = npmClient
14- return npmClient
15- }
16-
17- const { stdout, status } = spawn . sync ( 'yarn' , [ '--version' ] )
18- cachedNpmClient = status === 0 && stdout ? 'yarn' : 'npm'
19- return cachedNpmClient
10+ cachedNpmClient = npmClient
2011}
2112
2213function getNpmClient ( ) {
23- return cachedNpmClient || setNpmClient ( )
14+ if ( cachedNpmClient ) {
15+ return cachedNpmClient
16+ }
17+
18+ if ( spawn . sync ( 'pnpm' , [ '--version' ] ) . status === 0 ) {
19+ cachedNpmClient = 'pnpm'
20+ } else if ( spawn . sync ( 'yarn' , [ '--version' ] ) . status === 0 ) {
21+ cachedNpmClient = 'yarn'
22+ }
23+
24+ return cachedNpmClient
2425}
2526
2627module . exports = async ( {
@@ -35,6 +36,8 @@ module.exports = async ({
3536 const packageName = packages ? packages . join ( ', ' ) : 'packages'
3637
3738 return new Promise ( ( resolve , reject ) => {
39+ // `npm/pnpm/yarn add <packages>`
40+ // `npm/pnpm/yarn install`
3841 const args = [ packages ? 'add' : 'install' ] . concat ( packages ? packages : [ ] )
3942 if ( saveDev ) {
4043 args . push ( npmClient === 'npm' ? '-D' : '--dev' )
@@ -48,6 +51,7 @@ module.exports = async ({
4851 }
4952
5053 logger . debug ( npmClient , args . join ( ' ' ) )
54+ logger . debug ( 'install directory' , cwd )
5155 spinner . start ( `Installing ${ packageName } with ${ npmClient } ` )
5256 const ps = spawn ( npmClient , args , {
5357 stdio : [ 0 , 'pipe' , 'pipe' ] ,
@@ -64,42 +68,41 @@ module.exports = async ({
6468 )
6569 } )
6670
67- let output = ''
68- const stream = process . stderr
71+ let stdoutLogs = ''
72+ let stderrLogs = ''
6973
7074 ps . stdout &&
71- ps . stdout . on ( 'data' , data => {
72- output += data
75+ ps . stdout . setEncoding ( 'utf8' ) . on ( 'data' , data => {
76+ if ( npmClient === 'pnpm' ) {
77+ stdoutLogs = data
78+ } else {
79+ stdoutLogs += data
80+ }
7381 spinner . stop ( )
74- stream . write ( data )
82+ logUpdate ( stdoutLogs )
7583 spinner . start ( )
7684 } )
7785
7886 ps . stderr &&
79- ps . stderr . on ( 'data' , data => {
80- output += data
87+ ps . stderr . setEncoding ( 'utf8' ) . on ( 'data' , data => {
88+ if ( npmClient === 'pnpm' ) {
89+ stderrLogs = data
90+ } else {
91+ stderrLogs += data
92+ }
8193 spinner . stop ( )
82- stream . write ( data )
94+ logUpdate . clear ( )
95+ logUpdate . stderr ( stderrLogs )
96+ logUpdate ( stdoutLogs )
8397 spinner . start ( )
8498 } )
8599
86100 ps . on ( 'close' , code => {
87101 spinner . stop ( )
88102 // Clear output when succeeded
89103 if ( code === 0 ) {
90- const columns = stream . columns || 80
91- const lineCount = stripAnsi ( output )
92- . split ( '\n' )
93- . reduce ( ( count , line ) => {
94- return count + Math . max ( 1 , Math . ceil ( wcwidth ( line ) / columns ) )
95- } , 0 )
96- for ( let i = 0 ; i < lineCount ; i ++ ) {
97- if ( i > 0 ) {
98- readline . moveCursor ( stream , 0 , - 1 )
99- }
100- readline . clearLine ( stream , 0 )
101- readline . cursorTo ( stream , 0 )
102- }
104+ logUpdate . clear ( )
105+ logUpdate . stderr . clear ( )
103106 logger . success ( `Installed ${ packageName } ` )
104107 } else {
105108 throw new SAOError ( `Failed to install ${ packageName } in ${ cwd } ` )
0 commit comments