66 * @author Pawel Psztyc
77 */
88const { DependenciesOptions} = require ( './dependencies-options' ) ;
9- const { spawn} = require ( 'child_process' ) ;
109const fs = require ( 'fs-extra' ) ;
1110const path = require ( 'path' ) ;
12- const platform = process . platform ;
13- const isWin = platform !== 'darwin' && platform . indexOf ( 'win' ) !== - 1 ;
11+ const bower = require ( 'bower' ) ;
1412/**
1513 * A class responsible for installing API Console dependencies.
1614 *
@@ -26,10 +24,10 @@ class DependendenciesManager {
2624 * Constructs the processor.
2725 *
2826 * @param {String } workingDir Path to a working directory instance.
29- * @param {Winston } logger Logger to use to log debug output
30- * @param {DependenciesOptions } opts Options passed to the module
27+ * @param {?DependenciesOptions } opts Options passed to the module
28+ * @param {?Object } logger Logger to use to log debug output
3129 */
32- constructor ( workingDir , logger , opts ) {
30+ constructor ( workingDir , opts , logger ) {
3331 if ( ! ( opts instanceof DependenciesOptions ) ) {
3432 opts = new DependenciesOptions ( opts ) ;
3533 }
@@ -40,104 +38,43 @@ class DependendenciesManager {
4038 /**
4139 * Looger object to be used to pring verbose or error messages.
4240 */
43- this . logger = logger ;
41+ this . logger = this . _setupLogger ( logger ) ;
4442 /**
4543 * A directory where all operations will be performed
4644 *
4745 * @type {String }
4846 */
4947 this . workingDir = workingDir ;
50- /**
51- * A bower command root. It's a path to the bower command and it depends
52- * on install location.
53- *
54- * @type {String }
55- */
56- this . commandRoot = undefined ;
57- /**
58- * Is updated when `installDependencies()` is called.
59- * Alters the command so bower will not fail if current user is root.
60- */
61- this . runningRoot = false ;
48+ }
49+ /**
50+ * Returns a logger object. Either passed object or `console` is used.
51+ *
52+ * @param {?Object } logger A logger object with common logging functions
53+ * like `info`, `log`, `warn` and `error`
54+ * @return {Object }
55+ */
56+ _setupLogger ( logger ) {
57+ if ( logger ) {
58+ return logger ;
59+ }
60+ return console ;
6261 }
6362 /**
6463 * Installs bower dependencies if the `bower.json` file exists in `workingDir`
6564 *
6665 * @return {Promise } Resolved promise when operation is completed.
6766 */
6867 installDependencies ( ) {
69- this . __startDir = process . cwd ( ) ;
70- try {
71- process . chdir ( this . workingDir ) ;
72- } catch ( err ) {
73- return Promise . reject ( new Error ( err ) ) ;
74- }
75- return this . checkIsRoot ( )
76- . then ( isRoot => {
77- this . runningRoot = isRoot ;
78- } )
79- . then ( ( ) => this . hasBower ( ) )
80- . then ( hasFile => {
81- if ( ! hasFile ) {
68+ return fs . pathExists ( path . join ( this . workingDir , 'bower.json' ) )
69+ . then ( ( exists ) => {
70+ if ( ! exists ) {
8271 // no bower file, exit.
8372 this . logger . info ( 'No bower file. Skipping dependencies.' ) ;
8473 return ;
8574 }
8675 return this . _processDependencies ( ) ;
87- } )
88- . then ( ( ) => {
89- process . chdir ( this . __startDir ) ;
90- } )
91- . catch ( cause => {
92- process . chdir ( this . __startDir ) ;
93- throw cause ;
9476 } ) ;
9577 }
96- /**
97- * Checks if bower file exists in `workingDir`.
98- *
99- * @return {Promise } A promise resolved to boolean value determining if the
100- * `bower.json` file exists.
101- */
102- hasBower ( ) {
103- return fs . lstat ( 'bower.json' )
104- . then ( stats => {
105- return stats . isFile ( ) ;
106- } )
107- . catch ( ( ) => {
108- return false ;
109- } ) ;
110- }
111- /**
112- * Prepares bower command options depending on environment and options.
113- *
114- * @param {String } command to execute, what is after `$ bower`
115- * @return {object } Object containing the command and arguments
116- * - cmd {String} Command to call
117- * - args {Array<String>} List of arguments to send to the child process.
118- */
119- _prepareBowerCommand ( ...command ) {
120- var args = [ ] ;
121- if ( ! this . opts . verbose ) {
122- args . push ( '--quiet' ) ;
123- }
124- if ( this . runningRoot ) {
125- args . push ( '--allow-root' ) ;
126- }
127- if ( command && command . length ) {
128- command . forEach ( item => {
129- if ( item instanceof Array ) {
130- args = args . concat ( item ) ;
131- } else {
132- args . push ( item ) ;
133- }
134- } ) ;
135- }
136- return {
137- cmd : this . commandRoot ,
138- args : args
139- } ;
140- }
14178 /**
14279 * Processes dependencies installation.
14380 * It checks if bower is already installed in local machine and if it is
@@ -152,75 +89,20 @@ class DependendenciesManager {
15289 * installed.
15390 */
15491 _processDependencies ( ) {
155- var promise ;
156- if ( this . commandRoot ) {
157- promise = Promise . resolve ( ) ;
158- } else {
159- promise = this . _setBowerCommandRoot ( ) ;
160- }
161- return promise . then ( ( ) => {
162- this . logger . info ( 'Installing bower dependencies...' ) ;
163- let cmd = this . _prepareBowerCommand ( 'install' ) ;
164- return this . spawn ( cmd . cmd , cmd . args ) ;
92+ this . logger . info ( 'Installing bower dependencies...' ) ;
93+ return new Promise ( ( resolve , reject ) => {
94+ const factory = bower . commands . install ( [ ] , { } , {
95+ cwd : this . workingDir ,
96+ quiet : true
97+ } ) ;
98+ factory . on ( 'end' , ( ) => resolve ( ) ) ;
99+ factory . on ( 'error' , ( e ) => reject ( e ) ) ;
165100 } )
166101 . then ( ( ) => {
167102 this . logger . info ( 'Dependencies installed.' ) ;
168103 return this . _installAdditionalDependencies ( ) ;
169104 } ) ;
170105 }
171- /**
172- * Checks if bower is installed and if not it installs it locally.
173- * After that it constructs a bower command root depending on the OS.
174- *
175- * @return {Promise } Resolved promise when command is set and bower is
176- * installed.
177- */
178- _setBowerCommandRoot ( ) {
179- var localCommand = path . join ( '.' , 'node_modules' , '.bin' , 'bower' ) ;
180- if ( isWin ) {
181- localCommand += '.cmd' ;
182- }
183- return fs . pathExists ( localCommand )
184- . then ( exists => {
185- if ( ! exists ) {
186- return this . _ensureNpmPackage ( )
187- . then ( ( ) => {
188- this . logger . info ( 'installing bower in ' + process . cwd ( ) ) ;
189- return this . spawn ( 'npm' , [ 'install' , 'bower' , '--no-save' , '--silent' ] ) ;
190- } ) ;
191- }
192- } )
193- . then ( ( ) => {
194- this . commandRoot = localCommand ;
195- } ) ;
196- }
197- /**
198- * Checks if `package.json` file exists in current location and creates it
199- * if it doesn't so the `npm install` command install bower in current
200- * directory.
201- */
202- _ensureNpmPackage ( ) {
203- return fs . pathExists ( 'package.json' )
204- . then ( exists => {
205- if ( ! exists ) {
206- this . logger . info ( 'package.json file do not exists. Creating dummy file for npm.' ) ;
207- return this . _createDummyNpmPackage ( ) ;
208- }
209- } ) ;
210- }
211- /**
212- * Creates a dummy `package.json` file in current directory.
213- * TODO: Some way to clean it later.
214- */
215- _createDummyNpmPackage ( ) {
216- const content = {
217- name : 'api-console' ,
218- version : '0.0.1' ,
219- description : 'Dummy package. To be removed.' ,
220- license : 'CPAL-1.0'
221- } ;
222- return fs . writeJson ( 'package.json' , content ) ;
223- }
224106 /**
225107 * If required (for certain types of the console build options) it installs
226108 * additional bower dependencies like router, parser and enhancer.
@@ -229,7 +111,7 @@ class DependendenciesManager {
229111 * installed.
230112 */
231113 _installAdditionalDependencies ( ) {
232- var deps = [ ] ;
114+ let deps = [ ] ;
233115 if ( this . opts . parser ) {
234116 deps [ deps . length ] = 'advanced-rest-client/raml-js-parser' ;
235117 deps [ deps . length ] = 'advanced-rest-client/raml-json-enhance' ;
@@ -240,65 +122,16 @@ class DependendenciesManager {
240122 if ( deps . length ) {
241123 this . logger . info ( 'Installing additional bower dependencies...' ) ;
242124 this . logger . info ( 'Installing: ' , deps ) ;
243- let cmd = this . _prepareBowerCommand ( 'install' , deps ) ;
244- return this . spawn ( cmd . cmd , cmd . args ) ;
245- }
246- return Promise . resolve ( ) ;
247- }
248- /**
249- * Spawns process and execute task with output printed to the logger.
250- * @param {String } cmd Command to execute
251- * @param {Array<String> } args Arguments to pass to the command
252- * @return {Promise<String> } A promise resolved to an output of command execution.
253- */
254- spawn ( cmd , args ) {
255- args = args || [ ] ;
256- let log = `Executing command: ${ cmd } with arguments: ${ args . join ( ' ' ) } in ${ process . cwd ( ) } ` ;
257- this . logger . info ( log ) ;
258- return new Promise ( ( resolve , reject ) => {
259- const proc = spawn ( cmd , args , {
260- shell : true
261- } ) ;
262- var result = '' ;
263- proc . stdout . on ( 'data' , ( data ) => {
264- let _res = data . toString ( 'utf8' ) ;
265- result += _res ;
266- this . logger . info ( _res ) ;
267- } ) ;
268- proc . stderr . on ( 'data' , ( data ) => {
269- let _res = data . toString ( 'utf8' ) ;
270- result += _res ;
271- this . logger . error ( _res ) ;
272- } ) ;
273- proc . on ( 'close' , ( code ) => {
274- if ( code !== 0 ) {
275- reject ( 'Command ' + cmd + ' failde with code ' + code ) ;
276- } else {
277- resolve ( result ) ;
278- }
125+ return new Promise ( ( resolve , reject ) => {
126+ const factory = bower . commands . install ( deps , { } , {
127+ cwd : this . workingDir ,
128+ quiet : true
129+ } ) ;
130+ factory . on ( 'end' , ( ) => resolve ( ) ) ;
131+ factory . on ( 'error' , ( e ) => reject ( e ) ) ;
279132 } ) ;
280- } ) ;
281- }
282- /**
283- * Commands executed as root will fail under linux.
284- * This checks if current user is root
285- */
286- checkIsRoot ( ) {
287- if ( isWin ) {
288- return Promise . resolve ( false ) ;
289133 }
290- return this . spawn ( 'id' , [ '-u' ] )
291- . then ( ( response ) => {
292- if ( ! response ) {
293- return false ;
294- }
295- response = response . trim ( ) ;
296- if ( response . indexOf ( '0' ) === 0 ) {
297- return true ;
298- }
299- return false ;
300- } )
301- . catch ( ( ) => false ) ;
134+ return Promise . resolve ( ) ;
302135 }
303136}
304137exports . DependendenciesManager = DependendenciesManager ;
0 commit comments