Skip to content
This repository has been archived by the owner on Feb 18, 2021. It is now read-only.

Commit

Permalink
Implement check
Browse files Browse the repository at this point in the history
  • Loading branch information
ntindall committed Aug 26, 2017
1 parent b2be60f commit 1915eb5
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 10 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ Options:

- `--dirname` defaults to `process.cwd()`

#### `npm-shrinkwrap check`

Asserts that your `npm-shrinkwrap.json` file and node_modules
directory are in sync. If any excess modules are in your
node_modules folder, `check` will return an error and print
a list of the excess dependencies that are installed.

Options:
--dirname sets the directory of the npm-shrinkwrap.json

- `--dirname` defaults to `process.cwd()`

#### `npm-shrinkwrap install`

Will write a `shrinkwrap` script to your `package.json` file.
Expand Down
47 changes: 47 additions & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,53 @@ function main(opts, callback) {
console.log('synced npm-shrinkwrap.json ' +
'into node_modules');
});
} else if (command === 'check') {
// Otherwise, we check to see if any erroneous dependencies are
// installed.
//
// We set opts.dry to true, which suppresses all side effects in the
// shrinkShrinkwrap routine.
opts.dry = true;

return syncShrinkwrap(opts, function (err, errorReport) {
if (callback) {
return callback(err, errorReport);
}

if (err) {
if (errorReport === undefined) {
console.log('error', err);
console.error('stack', new Error().stack);
throw err;
}

if (errorReport.excessPackageJsonDependencies !== null &&
errorReport.excessPackageJsonDependencies.length !== 0) {
console.error('package.json has dependencies that are ' +
'not present in npm-shrinkwrap.json');
console.log(errorReport.excessPackageJsonDependencies);
}

if (errorReport.excessShrinkwrapDependencies !== null &&
errorReport.excessShrinkwrapDependencies.length !== 0) {
console.error('npm-shrinkwrap.json has dependencies that are ' +
'not present in package.json');
console.log(errorReport.excessShrinkwrapDependencies);
}

if (errorReport.erroneouslyInstalledDependencies !== null &&
errorReport.erroneouslyInstalledDependencies.length !== 0) {
console.error('npm-shrinkwrap.json is out of sync ' +
'with node_modules');
console.log(errorReport.erroneouslyInstalledDependencies);
}

return process.exit(1);
}

console.log('npm-shrinkwrap.json is in sync ' +
'with package.json');
});
}

shrinkwrap(opts, function (err, warnings) {
Expand Down
12 changes: 12 additions & 0 deletions bin/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ Options:

- `--dirname` defaults to `process.cwd()`

## `{cmd} check`

Asserts that your `npm-shrinkwrap.json` file and node_modules
directory are in sync. If any excess modules are in your
node_modules folder, `check` will return an error and print
a list of the excess dependencies that are installed.

Options:
--dirname sets the directory of the npm-shrinkwrap.json

- `--dirname` defaults to `process.cwd()`

## `{cmd} install`

Will write a `shrinkwrap` script to your `package.json` file.
Expand Down
22 changes: 18 additions & 4 deletions sync/force-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ function forceInstall(nodeModules, shrinkwrap, opts, cb) {

// if no dependencies object then terminate recursion
if (shrinkwrap.name && !shrinkwrap.dependencies) {
return purgeExcess(nodeModules, shrinkwrap, opts, cb);
return purgeExcess(nodeModules, shrinkwrap, opts, function(err, results) {
cb(err, results || []);
});
}

var deps = shrinkwrap.dependencies;
Expand All @@ -46,7 +48,7 @@ function forceInstall(nodeModules, shrinkwrap, opts, cb) {
opts.dev = false;

// remove purgeExcess result
results.pop();
var excess = results.pop();

var incorrects = results.filter(function (dep) {
return !dep.correct;
Expand Down Expand Up @@ -78,7 +80,6 @@ function forceInstall(nodeModules, shrinkwrap, opts, cb) {
var name = correct.name;
var folder = path.join(nodeModules, name,
'node_modules');

return forceInstall.bind(
null, folder, correct, opts);
});
Expand All @@ -90,7 +91,20 @@ function forceInstall(nodeModules, shrinkwrap, opts, cb) {

var tasks = [].concat(inCorrectTasks, correctTasks);

parallel(tasks, cb);
parallel(tasks, function(err, results) {
if (err) {
return cb(err);
}

// Results is an array of arrays representing the excess
// installed dependencies of our children.
var flattened = [].concat.apply([], results);

/*
return the excess dependencies that may have been purged
*/
cb(null, (excess || []).concat(flattened));
});
});
}

Expand Down
51 changes: 48 additions & 3 deletions sync/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,64 @@ function syncShrinkwrap(opts, cb) {

parallel({
shrinkwrap: read.shrinkwrap.bind(null, dirname),
devDependencies: read.devDependencies.bind(null, dirname)
dependencies: read.dependencies.bind(null, dirname)
}, function (err, tuple) {
if (err) {
return cb(err);
}

var nodeModules = path.join(dirname, 'node_modules');
var dependencies = tuple.dependencies;
var shrinkwrap = tuple.shrinkwrap;
shrinkwrap.devDependencies = tuple.devDependencies;

// first, we check that package.json dependencies and shrinkwrap
// top-level dependencies are in sync. this should cover the case
// where a dependency was added or removed to package.json, but
// shrinkwrap was not subsequently run.
var packageJsonDependencies =
Object.keys(dependencies.dependencies);
var shrinkwrapTopLevelDependencies =
Object.keys(shrinkwrap.dependencies);

var excessPackageJsonDependencies = packageJsonDependencies
.filter(function (x) {
return shrinkwrapTopLevelDependencies.indexOf(x) === -1;
});
var excessShrinkwrapDependencies = shrinkwrapTopLevelDependencies
.filter(function (x) {
return packageJsonDependencies.indexOf(x) === -1;
});

shrinkwrap.devDependencies = tuple.dependencies.devDependencies;

opts.dev = true;

forceInstall(nodeModules, shrinkwrap, opts, cb);
forceInstall(nodeModules, shrinkwrap, opts,
function(err, erroneousDependencies) {
// If there is a legitimate error, or we are not running
// `check`, bubble it up immediately
if (err || opts.dry !== true) {
return cb(err);
}

// Generate the error report
if (erroneousDependencies.length !== 0 ||
excessPackageJsonDependencies.length !== 0 ||
excessShrinkwrapDependencies.length !== 0
) {
return cb(
new Error('npm-shrinkwrap.json is out of sync'),
{
excessPackageJsonDependencies:
excessPackageJsonDependencies,
excessShrinkwrapDependencies:
excessShrinkwrapDependencies,
erroneouslyInstalledDependencies:
erroneousDependencies,
});
}
cb(null);
});
});
});
}
Expand Down
5 changes: 5 additions & 0 deletions sync/install-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ module.exports = installModule;
*/
function installModule(nodeModules, dep, opts, cb) {
// Suppress side-effects if running `check`
if (opts.dry === true) {
return cb(null, dep);
}

var where = path.join(nodeModules, '..');

console.log('installing ', where, dep.resolved);
Expand Down
7 changes: 7 additions & 0 deletions sync/purge-excess.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ function purgeExcess(dir, shrinkwrap, opts, cb) {

var tasks = excessFiles.map(function (file) {
var filePath = path.join(dir, file);

// Suppress side-effects if running `check`
if (opts.dry === true) {
return function (cb) {
return cb(null, filePath);
};
}
console.log('removing', filePath);
return rimraf.bind(null, filePath);
});
Expand Down
9 changes: 6 additions & 3 deletions sync/read.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var FileNotFound = TypedError({
module.exports = {
shrinkwrap: readShrinkwrap,
package: readPackage,
devDependencies: readDevDependencies
dependencies: readDependencies
};

function readPackage(dirname, cb) {
Expand All @@ -33,12 +33,15 @@ function readShrinkwrap(dirname, cb) {
});
}

function readDevDependencies(dirname, cb) {
function readDependencies(dirname, cb) {
readPackage(dirname, function (err, json) {
if (err) {
return cb(err);
}

cb(null, json.devDependencies);
cb(null, {
dependencies: json.dependencies,
devDependencies: json.devDependencies
});
});
}

0 comments on commit 1915eb5

Please sign in to comment.