@@ -2,6 +2,7 @@ const { URL } = require('url')
2
2
const https = require ( 'https' )
3
3
const chalk = require ( 'chalk' )
4
4
const execa = require ( 'execa' )
5
+ const readline = require ( 'readline' )
5
6
const inquirer = require ( 'inquirer' )
6
7
const { loadOptions, saveOptions } = require ( '../options' )
7
8
const { pauseSpinner, resumeSpinner } = require ( '@vue/cli-shared-utils' )
@@ -74,6 +75,26 @@ const shouldUseTaobao = async (command) => {
74
75
return save ( useTaobaoRegistry )
75
76
}
76
77
78
+ const toStartOfLine = stream => {
79
+ if ( ! chalk . supportsColor ) {
80
+ stream . write ( '\r' )
81
+ return
82
+ }
83
+ readline . cursorTo ( stream , 0 )
84
+ }
85
+
86
+ const renderProgressBar = ( curr , total ) => {
87
+ const ratio = Math . min ( Math . max ( curr / total , 0 ) , 1 )
88
+ const bar = ` ${ curr } /${ total } `
89
+ const availableSpace = Math . max ( 0 , process . stderr . columns - bar . length - 3 )
90
+ const width = Math . min ( total , availableSpace )
91
+ const completeLength = Math . round ( width * ratio )
92
+ const complete = `#` . repeat ( completeLength )
93
+ const incomplete = `-` . repeat ( width - completeLength )
94
+ toStartOfLine ( process . stderr )
95
+ process . stderr . write ( `[${ complete } ${ incomplete } ]${ bar } ` )
96
+ }
97
+
77
98
module . exports = async function installDeps ( targetDir , command , cliRegistry ) {
78
99
const args = [ ]
79
100
if ( command === 'npm' ) {
@@ -105,9 +126,28 @@ module.exports = async function installDeps (targetDir, command, cliRegistry) {
105
126
await new Promise ( ( resolve , reject ) => {
106
127
const child = execa ( command , args , {
107
128
cwd : targetDir ,
108
- stdio : 'inherit'
129
+ stdio : [ 'inherit' , 'inherit' , command === 'yarn' ? 'pipe' : 'inherit' ]
109
130
} )
110
131
132
+ // filter out unwanted yarn output
133
+ if ( command === 'yarn' ) {
134
+ child . stderr . on ( 'data' , buf => {
135
+ const str = buf . toString ( )
136
+ if ( / w a r n i n g / . test ( str ) ) {
137
+ return
138
+ }
139
+ // progress bar
140
+ const progressBarMatch = str . match ( / \[ .* \] ( \d + ) \/ ( \d + ) / )
141
+ if ( progressBarMatch ) {
142
+ // since yarn is in a child process, it's unable to get the width of
143
+ // the terminal. reimplement the progress bar ourselves!
144
+ renderProgressBar ( progressBarMatch [ 1 ] , progressBarMatch [ 2 ] )
145
+ return
146
+ }
147
+ process . stderr . write ( buf )
148
+ } )
149
+ }
150
+
111
151
child . on ( 'close' , code => {
112
152
if ( code !== 0 ) {
113
153
reject ( `command failed: ${ command } ${ args . join ( ' ' ) } ` )
0 commit comments