Skip to content

Commit

Permalink
Merge pull request #64 from CleverStack/feat-module-dependencies
Browse files Browse the repository at this point in the history
feat(peerDependencies): Re-implement module installation dependencies without bundledDependencies[]
  • Loading branch information
pilsy committed Apr 6, 2015
2 parents 5c69f55 + 875bf3e commit 238406a
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 105 deletions.
66 changes: 46 additions & 20 deletions bin/clever-init
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var path = require('path')
, rimraf = require('rimraf')
, async = require('async')
, exec = require('child_process').exec
, spawn = require('child_process').spawn
, Promise = require('bluebird')
, singleSeed = true
, seedsToInstall = []
Expand Down Expand Up @@ -58,7 +59,7 @@ program.on('--help', function() {
/** Parse CLI Arguments
================================*/
program.parse(process.argv);
if (!program.args[ 0 ] || program.args[ 0 ].toString().trim() === '') {
if (!program.args[0] || program.args[0].toString().trim() === '') {
program.help();
}

Expand All @@ -76,13 +77,16 @@ if (!program.args[ 0 ] || program.args[ 0 ].toString().trim() === '') {
* @api private
*/
function writeLocalJSON(projectDir) {
var configDir = path.resolve(path.join(projectDir, 'config'));

return new Promise(function(resolve, reject) {
var localJSONFile = require(path.join(projectDir, 'config', 'local.example.json'));
var localJSONFile = require(path.join(configDir, 'local.example.json'));

utils.info([ ' Creating local configuration file config/local.json', '...' ].join(''));
utils.running('Creating config/local.json...');
utils
.info(' Creating local configuration file config/local.json...')
.running('Creating config/local.json...');

fs.writeFile(path.join(projectDir, 'config', 'local.json'), JSON.stringify(localJSONFile, null, 2), function (err) {
fs.writeFile(path.join(configDir, 'local.json'), JSON.stringify(localJSONFile, null, 2), function(err) {
if (!!err) {
return reject(err);
}
Expand All @@ -101,22 +105,34 @@ function writeLocalJSON(projectDir) {
*/
function installNPMPackages(projectDir) {
return new Promise(function(resolve, reject) {
utils.info([ ' Installing NPM modules...' ].join(''));
utils.running('Installing NPM modules...');
var proc = exec('npm install --silent', { cwd: projectDir }, function(err) {
if (!!err && err.message !== 'Command failed: ') {
utils.fail(err);
reject(err);
utils
.info(' Installing NPM modules...')
.running('Installing NPM modules...');

var args = ['install']
, opts = { env: process.env, cwd: projectDir };

if (!!program.verbose) {
opts.stdio = 'inherit';
} else {
args.push('--silent');
}

var proc = spawn('npm', args, opts)
, error = '';

proc.on('error', function(err) {
error += err;
});

proc.on('close', function(code) {
if (code !== 0 || !!error && error !== 'Command failed: ') {
utils.fail(error);
reject(error);
} else {
resolve();
}
});

// Pipe the output of exec if verbose has been specified
if (program.verbose) {
proc.stdout.pipe(process.stdout);
proc.stderr.pipe(process.stdout);
}
});
}

Expand Down Expand Up @@ -147,8 +163,10 @@ function setupBackend() {
return reject(err);
}

utils.info([ ' Downloading and extracting ', csPackage.name, '...' ].join(''));
utils.running('Downloading and extracting...');
utils
.info('Downloading and extracting ' + csPackage.name + '...')
.running('Downloading and extracting ' + csPackage.name + '...');

lib.packages
.get(csPackage, projectDir)
.then(function() {
Expand All @@ -159,6 +177,14 @@ function setupBackend() {
utils.progress();
return installNPMPackages(projectDir);
})
.then(function() {
utils
.info(' Installing module dependencies...', '└── ')
.running('Installing module dependencies...')
.progress();

return lib.util.dependencies.installPeerDependencies(projectDir);
})
.then(function() {
utils.progress();

Expand Down Expand Up @@ -546,7 +572,7 @@ async.waterfall(
lib.utils.finishProgress();
process.exit(0);
} else {
utils.fail(err);
utils.fail(err.stack ? (err + '\n' + err.stack) : err);
}
}
);
91 changes: 76 additions & 15 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var Promise = require('bluebird')
, path = require('path')
, _ = require('lodash')
, https = require('follow-redirects').https
, async = require('async')
, utils = GLOBAL.lib.utils
, search = GLOBAL.lib.search
, packages = GLOBAL.lib.packages
Expand Down Expand Up @@ -76,31 +77,91 @@ function install(repos) {
});
}

function installBackendModules(backendPath, npm) {
return new Promise(function(resolve, reject) {
npm = npm.map(function(n) {
return n.name;
});

var walker = require('findit')(path.join(backendPath.moduleDir, backendPath.modulePath))
, dirs = [];

walker.on('directory', function(dir, stat, stop) {
var _dirs = dir.split(path.sep)
, _dir = _dirs.pop()
, mdir = path.dirname(dir).split(path.sep).pop();

if (mdir === 'modules') {
if (npm.indexOf(_dir) === -1) {
return stop();
}

dirs.push(path.join(_dirs.join(path.sep), _dir));
}
});

walker.on('end', function() {
if (dirs.length > 0) {
lib.utils.info([ ' Installing module peerDependencies...' ].join(''));

async.each(
dirs,
function installModulePeerDependencies(dir, installed) {
util
.dependencies
.installPeerDependencies(dir, path.join(backendPath.moduleDir, backendPath.modulePath))
.then(function () {
installed();
})
.catch(installed);
},
function peerDependenciesInstalled(err) {
if (!!err) {
return reject(err);
}

async.eachSeries(
npm,
function(module, next) {
util
.grunt
.runTasks(backendPath.moduleDir, path.join(backendPath.moduleDir, backendPath.modulePath, module))
.then(next, next);
},
function( err) {
if (!!err) {
return reject(err);
}

resolve();
}
);
}
);
}
});
});
}


exports.run = function(args) {
return new Promise(function(resolve, reject) {
install(args)
.spread(function(backendPath, frontendPath, npm /*, bower */) {
var actions = [];

npm.forEach(function(module) {
actions.push(
util
.grunt
.runTasks(backendPath.moduleDir, path.join(backendPath.moduleDir, backendPath.modulePath, module.name))
);
});
if (npm.length > 0) {
actions.push(installBackendModules(backendPath, npm));
}

Promise
.all(actions)
.then(function() {
.then(function runNpmTasksForModules() {
resolve();
}, function (err) {
reject(err);
});

}, function (err) {
reject(err);
});
})
.catch(reject);
})
.catch(reject);
});
};

Expand Down
26 changes: 8 additions & 18 deletions lib/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,29 @@ var searchNPMRegistry = exports.npmRegistry = function(queries) {
return new Promise(function(resolve, reject) {
var repos = [];

// Keep this as SERIES until we come up with a better system
// than bundleDeps.. when we do clever install clever-orm clever-auth
// auth HAS to come AFTER ORM.. kind of a bad system
// so we'll definitely need some sort of dependency management system.
async.eachSeries(
async.each(
queries,
function(q, next) {
var search = q.split('@');
if (typeof search[ 1 ] === 'undefined') {
search[ 1 ] = '*';
if (typeof search[1] === 'undefined') {
search[1] = '*';
}

_pkg.getJSON({
hostname: 'registry.npmjs.org',
path: '/' + encodeURIComponent(search[ 0 ])
path: '/' + encodeURIComponent(search[0])
})
.then(function(body) {
if (typeof body === 'undefined' || (body.error && body.error === 'not_found')) {
return next();
}

var versions = Object.keys(body.versions)
, maxVersion;
var versions = Object.keys(body.versions)
, maxVersion = semver.maxSatisfying(versions, search[1])
, pkg = body.versions[maxVersion];

if ([ '>', '<', '=', '*' ].indexOf(search[ 1 ]) > -1) {
maxVersion = semver.maxSatisfying(versions, search[ 1 ]);
} else {
maxVersion = semver.clean(search[ 1 ]);
}

var pkg = body.versions[ maxVersion ];
if (typeof pkg === 'undefined') {
utils.fail('Invalid version ' + search[ 1 ] + ' for module ' + search[ 0 ], true);
utils.fail('Invalid version ' + search[1] + ' for module ' + search[0], true);
return next();
}

Expand Down
Loading

0 comments on commit 238406a

Please sign in to comment.