install.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. var _ = require('lodash');
  2. var dargs = require('dargs');
  3. var async = require('async');
  4. var chalk = require('chalk');
  5. var install = module.exports;
  6. /**
  7. * Combine package manager cmd line arguments and run the `install` command.
  8. *
  9. * @param {String} installer Which package manager to use
  10. * @param {String|Array} paths Packages to install, empty string for `npm install`
  11. * @param {Object} options Options to invoke `install` with
  12. * @param {Function} cb
  13. */
  14. install.runInstall = function (installer, paths, options, cb) {
  15. if (!cb && _.isFunction(options)) {
  16. cb = options;
  17. options = {};
  18. }
  19. options = options || {};
  20. cb = cb || function () {};
  21. paths = Array.isArray(paths) ? paths : (paths && paths.split(' ') || []);
  22. this.emit(installer + 'Install', paths);
  23. var args = ['install'].concat(paths).concat(dargs(options));
  24. this.spawnCommand(installer, args, cb)
  25. .on('error', cb)
  26. .on('exit', this.emit.bind(this, installer + 'Install:end', paths))
  27. .on('exit', function (err) {
  28. if (err === 127) {
  29. this.log.error('Could not find ' + installer + '. Please install with ' +
  30. '`npm install -g ' + installer + '`.');
  31. }
  32. cb(err);
  33. }.bind(this));
  34. return this;
  35. };
  36. /**
  37. * Runs `npm` and `bower` in the generated directory concurrently and prints a
  38. * message to let the user know.
  39. *
  40. * ### Options:
  41. *
  42. * - `npm` Boolean whether to run `npm install` (`true`)
  43. * - `bower` Boolean whether to run `bower install` (`true`)
  44. * - `skipInstall` Boolean whether to skip automatic installation (`false`)
  45. * - `skipMessage` Boolean whether to show the used bower/npm commands (`false`)
  46. *
  47. * ### Examples:
  48. *
  49. * this.installDependencies({
  50. * bower: true,
  51. * npm: true,
  52. * skipInstall: false,
  53. * callback: function () {
  54. * console.log('Everything is ready!');
  55. * }
  56. * });
  57. *
  58. * @param {Object} options
  59. */
  60. install.installDependencies = function (options) {
  61. var msg = {
  62. commands: [],
  63. template: _.template('\n\nI\'m all done. ' +
  64. '<%= skipInstall ? "Just run" : "Running" %> <%= commands %> ' +
  65. '<%= skipInstall ? "" : "for you " %>to install the required dependencies.' +
  66. '<% if (!skipInstall) { %> If this fails, try running the command yourself.<% } %>\n\n')
  67. };
  68. var commands = [];
  69. if (_.isFunction(options)) {
  70. options = {
  71. callback: options
  72. };
  73. }
  74. options = _.defaults(options || {}, {
  75. bower: true,
  76. npm: true,
  77. skipInstall: false,
  78. skipMessage: false,
  79. callback: function () {}
  80. });
  81. if (options.bower) {
  82. msg.commands.push('bower install');
  83. commands.push(function (cb) {
  84. this.bowerInstall(null, null, cb);
  85. }.bind(this));
  86. }
  87. if (options.npm) {
  88. msg.commands.push('npm install');
  89. commands.push(function (cb) {
  90. this.npmInstall(null, null, cb);
  91. }.bind(this));
  92. }
  93. if (msg.commands.length === 0) {
  94. throw new Error('installDependencies needs at least one of npm or bower to run.');
  95. }
  96. if (!options.skipMessage) {
  97. console.log(msg.template(_.extend(options, { commands: chalk.yellow.bold(msg.commands.join(' & ')) })));
  98. }
  99. if (!options.skipInstall) {
  100. async.parallel(commands, options.callback);
  101. }
  102. };
  103. /**
  104. * Receives a list of `paths`, and an Hash of `options` to install through bower.
  105. *
  106. * @param {String|Array} paths Packages to install
  107. * @param {Object} options Options to invoke `bower install` with, see `bower help install`
  108. * @param {Function} cb
  109. */
  110. install.bowerInstall = function install(paths, options, cb) {
  111. return this.runInstall('bower', paths, options, cb);
  112. };
  113. /**
  114. * Receives a list of `paths`, and an Hash of `options` to install through npm.
  115. *
  116. * @param {String|Array} paths Packages to install
  117. * @param {Object} options Options to invoke `npm install` with, see `npm help install`
  118. * @param {Function} cb
  119. */
  120. install.npmInstall = function install(paths, options, cb) {
  121. return this.runInstall('npm', paths, options, cb);
  122. };