Skip to content
This repository was archived by the owner on Jan 21, 2024. It is now read-only.

Commit 6bac517

Browse files
committed
Updating the command to use internall bower module.
1 parent 68f51aa commit 6bac517

File tree

9 files changed

+82
-374
lines changed

9 files changed

+82
-374
lines changed

.jshintrc

Lines changed: 0 additions & 21 deletions
This file was deleted.

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ language: node_js
22
node_js: stable
33
script:
44
- npm test
5+
cache:
6+
- "~/.cache/bower/"

bower.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"test","description":"test","version":"0.0.1","license":"Apache-2.0 OR CC-BY-4.0","authors":["The Advanced REST client authors <arc@mulesoft.com>"],"dependencies":{"arc-polyfills":"advanced-rest-client/arc-polyfills#latest"}}

lib/dependencies-options.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
* Options object for the DependendenciesManager class.
1010
*/
1111
class DependenciesOptions {
12+
/**
13+
* @constructor
14+
* @param {Object} opts User passed options.
15+
*/
1216
constructor(opts) {
1317
opts = opts || {};
1418
/**

lib/dependencies.js

Lines changed: 38 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
* @author Pawel Psztyc
77
*/
88
const {DependenciesOptions} = require('./dependencies-options');
9-
const {spawn} = require('child_process');
109
const fs = require('fs-extra');
1110
const 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
}
304137
exports.DependendenciesManager = DependendenciesManager;

package-lock.json

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "api-console-dependency-manager",
3-
"version": "0.1.2",
3+
"version": "1.0.0",
44
"description": "Module to detect and install Mulesoft's API console dependencies.",
55
"main": "main.js",
66
"scripts": {
@@ -31,6 +31,7 @@
3131
"mocha": "^3.2.0"
3232
},
3333
"dependencies": {
34+
"bower": "^1.8.4",
3435
"fs-extra": "^3.0.0"
3536
}
3637
}

0 commit comments

Comments
 (0)