123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- var mout = require('mout');
- var cmd = require('../util/cmd');
- var Q = require('q');
- var shellquote = require('shell-quote');
- var orderByDependencies = function (packages, installed, json) {
- var ordered = [];
- installed = mout.object.keys(installed);
- var depsSatisfied = function (packageName) {
- return mout.array.difference(mout.object.keys(packages[packageName].dependencies), installed, ordered).length === 0;
- };
- var depsFromBowerJson = json && json.dependencies ? mout.object.keys(json.dependencies) : [];
- var packageNames = mout.object.keys(packages);
- //get the list of the packages that are specified in bower.json in that order
- //its nice to maintain that order for users
- var desiredOrder = mout.array.intersection(depsFromBowerJson, packageNames);
- //then add to the end any remaining packages that werent in bower.json
- desiredOrder = desiredOrder.concat(mout.array.difference(packageNames, desiredOrder));
- //the desired order isn't necessarily a correct dependency specific order
- //so we ensure that below
- var resolvedOne = true;
- while (resolvedOne) {
- resolvedOne = false;
- for (var i = 0; i < desiredOrder.length; i++) {
- var packageName = desiredOrder[i];
- if (depsSatisfied(packageName)) {
- ordered.push(packageName);
- mout.array.remove(desiredOrder, packageName);
- //as soon as we resolve a package start the loop again
- resolvedOne = true;
- break;
- }
- }
- if (!resolvedOne && desiredOrder.length > 0) {
- //if we're here then some package(s) doesn't have all its deps satisified
- //so lets just jam those names on the end
- ordered = ordered.concat(desiredOrder);
- }
- }
- return ordered;
- };
- var run = function (cmdString, action, logger, config) {
- logger.action(action, cmdString);
- //pass env + BOWER_PID so callees can identify a preinstall+postinstall from the same bower instance
- var env = mout.object.mixIn({ 'BOWER_PID': process.pid }, process.env);
- var args = shellquote.parse(cmdString, env);
- var cmdName = args[0];
- mout.array.remove(args, cmdName); //no rest() in mout
- var options = {
- cwd: config.cwd,
- env: env
- };
- var promise = cmd(cmdName, args, options);
- promise.progress(function (progress) {
- progress.split('\n').forEach(function (line) {
- if (line) {
- logger.action(action, line);
- }
- });
- });
- return promise;
- };
- var hook = function (action, ordered, config, logger, packages, installed, json) {
- if (mout.object.keys(packages).length === 0 || !config.scripts || !config.scripts[action]) {
- /*jshint newcap: false */
- return Q();
- }
- var orderedPackages = ordered ? orderByDependencies(packages, installed, json) : mout.object.keys(packages);
- var cmdString = mout.string.replace(config.scripts[action], '%', orderedPackages.join(' '));
- return run(cmdString, action, logger, config);
- };
- module.exports = {
- preuninstall: mout.function.partial(hook, 'preuninstall', false),
- preinstall: mout.function.partial(hook, 'preinstall', true),
- postinstall: mout.function.partial(hook, 'postinstall', true),
- //only exposed for test
- _orderByDependencies: orderByDependencies
- };
|