diff --git a/lib/dependency-manager-adapters/bower.js b/lib/dependency-manager-adapters/bower.js index 338a148b..74a8bedd 100644 --- a/lib/dependency-manager-adapters/bower.js +++ b/lib/dependency-manager-adapters/bower.js @@ -108,17 +108,31 @@ module.exports = CoreObject.extend({ }, _install: function() { var adapter = this; - var options = this.managerOptions || []; - return rimraf(path.join(adapter.cwd, 'bower_components')) .then(function() { - debug('Remove bower_components'); - return adapter._findBowerPath(adapter.cwd); - }) - .then(function(bowerPath) { - debug('Run bower install using bower at %s', bowerPath); - return adapter.run('node', [].concat([bowerPath, 'install', '--config.interactive=false'], options), { cwd: adapter.cwd }); + debug('Removed bower_components'); + return adapter._runBowerInstall(); + }); + }, + _runBowerInstall: function() { + var adapter = this; + var options = this.managerOptions || []; + var commandParts = ['install', '--config.interactive=false']; + return adapter._findBowerPath(adapter.cwd).then(function(bowerPath) { + debug('Run bower install using bower at %s', bowerPath); + return adapter.run('node', [].concat([bowerPath], commandParts, options), { cwd: adapter.cwd }); + }).catch(function() { + debug('Local bower not found'); + return adapter._checkForGlobalBower().then(function() { + debug('Using global bower'); + return adapter.run('bower', [].concat(commandParts, options), { cwd: adapter.cwd }); }); + }); + }, + _checkForGlobalBower: function() { + return this.run('bower', ['-v'], { stdio: 'ignore' }).catch(function() { + throw new Error("Bower must be installed either locally or globally to have bower scenarios"); + }); }, _bowerJSONForDependencySet: function(bowerJSON, depSet) { if (!bowerJSON.resolutions) { @@ -172,26 +186,13 @@ module.exports = CoreObject.extend({ }, _findBowerPath: function() { var adapter = this; - return findEmberPath(adapter.cwd) - .then(function(emberPath) { - /* Find bower's entry point module relative to - ember-cli's entry point script */ - return adapter._resolveModule('bower', { basedir: path.dirname(emberPath) }) - .catch(function() { - debug('Bower not found'); - return adapter._installBower(); - }).then(function() { - return adapter._resolveModule('bower', { basedir: path.dirname(emberPath) }); - }); - }) - .then(function(bowerPath) { - return path.join(bowerPath, '..', '..', 'bin', 'bower'); - }); - }, - _installBower: function() { - var adapter = this; - debug('Installing bower via npm'); - return adapter.run('npm', [].concat(['install', 'bower@^1.3.12']), { cwd: adapter.cwd }); + return findEmberPath(adapter.cwd).then(function(emberPath) { + /* Find bower's entry point module relative to ember-cli's entry point script */ + return adapter._resolveModule('bower', { basedir: path.dirname(emberPath) }) + .then(function(bowerPath) { + return path.join(bowerPath, '..', '..', 'bin', 'bower'); + }); + }); }, _resolveModule: function(moduleName, options) { return resolve(moduleName, options); diff --git a/lib/utils/run.js b/lib/utils/run.js index 0ea12cd5..3de0f198 100644 --- a/lib/utils/run.js +++ b/lib/utils/run.js @@ -6,7 +6,8 @@ var debug = require('debug')('ember-try:utils:run'); function run(command, args, opts) { opts = opts || {}; - opts.stdio = 'inherit'; + + opts.stdio = opts.stdio || 'inherit'; if (process.env.SHUT_UP) { opts.stdio = 'ignore'; diff --git a/test/dependency-manager-adapters/bower-adapter-test.js b/test/dependency-manager-adapters/bower-adapter-test.js index f9aaee10..6e1bd6f3 100644 --- a/test/dependency-manager-adapters/bower-adapter-test.js +++ b/test/dependency-manager-adapters/bower-adapter-test.js @@ -121,6 +121,36 @@ describe('bowerAdapter', function() { return new BowerAdapter({ cwd: tmpdir, run: stubbedRun })._install(); }); + it('runs bower install with global bower if local bower is not found', function() { + var actualCommand, actualArgs, actualOpts; + + var doNotFindLocalBower = function() { + return RSVP.reject(); + }; + + var findGlobalBower = function() { + return RSVP.resolve(); + }; + + var stubbedRun = function(command, args, opts) { + actualCommand = command; + actualArgs = args; + actualOpts = opts; + return RSVP.resolve(); + }; + + return new BowerAdapter({ + cwd: tmpdir, + _findBowerPath: doNotFindLocalBower, + _checkForGlobalBower: findGlobalBower, + run: stubbedRun + })._install().then(function() { + expect(actualCommand).to.equal('bower'); + expect(actualArgs).to.eql(['install', '--config.interactive=false']); + expect(actualOpts).to.have.property('cwd', tmpdir); + }); + }); + it('runs bower install including managerOptions', function() { writeJSONFile('bower.json', fixtureBower); var stubbedRun = function(command, args) { @@ -252,59 +282,32 @@ describe('bowerAdapter', function() { expect(path).to.include('node_modules/bower/bin/bower'); }); }); + }); - it('does not attempt to install bower if bower is found', function() { - var installCount = 0; - var stubbedResolveModule = function() { - return RSVP.resolve('blip/bloop/foo/lib/index.js'); - }; - var stubbedInstallBower = function() { - installCount++; - }; - return new BowerAdapter({ cwd: tmpdir, _installBower: stubbedInstallBower, _resolveModule: stubbedResolveModule })._findBowerPath().then(function(path) { - expect(path).to.include('blip/bloop/foo/bin/bower'); - expect(installCount).to.equal(0); - }); - }); - - it('installs bower if bower is not found', function() { - var installCount = 0; - var resolveModuleCount = 0; - var stubbedResolveModule = function() { - resolveModuleCount++; - if (resolveModuleCount === 1) { - return RSVP.reject(); - } - if (resolveModuleCount === 2) { - return RSVP.resolve('flip/flop/gloop/lib/index.js'); - } - }; - - var stubbedInstallBower = function() { - installCount++; + describe('#_checkForGlobalBower()', function() { + it('runs bower -v to see if bower exists', function() { + let actualCommand, actualArgs, actualOpts; + var stubbedRun = function(command, args, opts) { + actualCommand = command; + actualArgs = args; + actualOpts = opts; + return RSVP.resolve(); }; - return new BowerAdapter({ cwd: tmpdir, _installBower: stubbedInstallBower, _resolveModule: stubbedResolveModule })._findBowerPath().then(function(path) { - expect(path).to.include('flip/flop/gloop/bin/bower'); - expect(installCount).to.equal(1); + return new BowerAdapter({ cwd: tmpdir, run: stubbedRun })._checkForGlobalBower().then(function() { + expect(actualCommand).to.equal('bower'); + expect(actualArgs).to.eql(['-v']); + expect(actualOpts.stdio).to.equal('ignore'); }); }); - }); - describe('#_installBower()', function() { - it('installs bower via npm', function() { - var command, args, opts; - var stubbedRun = function(c, a, o) { - command = c; - args = a; - opts = o; - return RSVP.resolve(); + it('throws if running bower -v fails', function() { + var stubbedRun = function() { + return RSVP.reject(); }; - return new BowerAdapter({ cwd: tmpdir, run: stubbedRun })._installBower().then(function() { - expect(command).to.equal('npm'); - expect(args[0]).to.equal('install'); - expect(args[1]).to.equal('bower@^1.3.12'); - expect(opts).to.have.property('cwd', tmpdir); + + return new BowerAdapter({ cwd: tmpdir, run: stubbedRun })._checkForGlobalBower().catch(function(err) { + expect(err).to.match(/Bower must be installed either locally or globally to have bower scenarios/); }); }); }); diff --git a/test/tasks/try-each-test.js b/test/tasks/try-each-test.js index 57050d7e..f6f5e574 100644 --- a/test/tasks/try-each-test.js +++ b/test/tasks/try-each-test.js @@ -279,8 +279,7 @@ describe('tryEach', function() { expect(true).to.equal(false, 'Assertions should run'); }); }); - - + it('fails scenarios when scenario\'s tests fail', function() { this.timeout(300000);