-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for npm-shrinkwrap.json #26
Changes from 4 commits
c289ab5
bbdbc3a
b801452
ebf2e39
9d6dac7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,15 @@ | ||
'use strict'; | ||
|
||
module.exports = require('./lib/dependency-checker'); | ||
var Reporter = require('./lib/reporter'); | ||
var DependencyChecker = require('./lib/dependency-checker'); | ||
|
||
module.exports = { | ||
name: 'ember-cli-dependency-checker', | ||
|
||
included: function(app) { | ||
var reporter = new Reporter(); | ||
var dependencyChecker = new DependencyChecker(app.project, reporter); | ||
|
||
return dependencyChecker.checkDependencies(); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
'use strict'; | ||
|
||
function installCommand(type) { | ||
switch (type) { | ||
case 'npm': | ||
return 'npm install'; | ||
case 'npm-shrinkwrap': | ||
return 'rm -rf node_modules/ && npm install'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure about this, but isn't it better to just uninstall the problematic dependency and install it again? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing that once dependency seems tricky to explain- and this message prints for a display of what may be many dependency errors. This is aggressive, but it seems appropriate for a start. |
||
case 'bower': | ||
return 'bower install'; | ||
} | ||
} | ||
|
||
var Reporter = function() { | ||
this.messages = []; | ||
}; | ||
|
||
Reporter.prototype.unsatisifedPackages = function(type, packages) { | ||
this.chalk = this.chalk || require('chalk'); | ||
this.EOL = this.EOL || require('os').EOL; | ||
|
||
var chalk = this.chalk; | ||
var EOL = this.EOL; | ||
|
||
if (packages.length > 0) { | ||
var message = ''; | ||
message += EOL + chalk.red('Missing ' + type + ' packages: ') + EOL; | ||
|
||
packages.forEach(function(pkg) { | ||
message += chalk.reset('Package: ') + chalk.cyan(pkg.name) + EOL; | ||
if (pkg.parents) { | ||
message += chalk.reset('Required by: ') + chalk.cyan(pkg.parents.join(' / ')) + EOL; | ||
} | ||
message += chalk.grey(' * Specified: ') + chalk.reset(pkg.versionSpecified) + EOL; | ||
message += chalk.grey(' * Installed: ') + chalk.reset(pkg.versionInstalled || '(not installed)') + EOL + EOL; | ||
}); | ||
|
||
message += chalk.red('Run `'+ installCommand(type) +'` to install missing dependencies.') + EOL; | ||
this.messages.push(message); | ||
} | ||
}; | ||
|
||
Reporter.prototype.report = function() { | ||
if (this.messages.length) { | ||
var DependencyError = require('./dependency-error'); | ||
throw new DependencyError(this.messages.join('')); | ||
} | ||
}; | ||
|
||
module.exports = Reporter; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
'use strict'; | ||
|
||
var readPackageJSON = require('./utils/read-package-json'); | ||
var ShrinkwrapPackage = require('./shrinkwrap-package'); | ||
var path = require('path'); | ||
|
||
var ShrinkwrapChecker = function(root, name, versionSpecified, parents){ | ||
this.root = root; | ||
this.name = name; | ||
this.versionSpecified = versionSpecified; | ||
this.parents = parents; | ||
}; | ||
|
||
ShrinkwrapChecker.prototype.check = function() { | ||
var packageJSON = readPackageJSON(this.root) || {}; | ||
var versionInstalled = packageJSON.version; | ||
|
||
return new ShrinkwrapPackage( | ||
this.name, this.versionSpecified, versionInstalled, this.parents); | ||
}; | ||
|
||
ShrinkwrapChecker.checkDependencies = function(root, shrinkWrapJSON) { | ||
var resolvedDependencies = []; | ||
var currentNode; | ||
|
||
var nodesToCheck = [{ | ||
root: root, | ||
parents: [], | ||
childDependencies: shrinkWrapJSON.dependencies, | ||
name: shrinkWrapJSON.name, | ||
version: shrinkWrapJSON.version | ||
}]; | ||
|
||
var checker, resolved; | ||
|
||
while (currentNode = nodesToCheck.pop()) { | ||
checker = new ShrinkwrapChecker( | ||
currentNode.root, currentNode.name, currentNode.version, currentNode.parents); | ||
|
||
resolved = checker.check(); | ||
resolvedDependencies.push(resolved); | ||
|
||
if (!resolved.needsUpdate && currentNode.childDependencies) { | ||
/* jshint loopfunc:true*/ | ||
var parents = currentNode.parents.concat(currentNode.name); | ||
Object.keys(currentNode.childDependencies).forEach(function(childDepName){ | ||
var childDep = currentNode.childDependencies[childDepName]; | ||
|
||
nodesToCheck.push({ | ||
root: path.join(currentNode.root, 'node_modules', childDepName), | ||
parents: parents, | ||
name: childDepName, | ||
childDependencies: childDep.dependencies, | ||
version: childDep.version | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
return resolvedDependencies; | ||
}; | ||
|
||
module.exports = ShrinkwrapChecker; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
'use strict'; | ||
|
||
var Package = require('./package'); | ||
|
||
function ShrinkwrapPackage(name, versionSpecified, versionInstalled, parents) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The We did not want to leak the The checker itself just gathers information. Similar to the main dependency checker, it doesn't presume to make a decision about what actions must occur. |
||
this._super$init.call(this, name, versionSpecified, versionInstalled); | ||
this.init(name, versionSpecified, versionInstalled, parents); | ||
} | ||
|
||
ShrinkwrapPackage.prototype = Object.create(Package.prototype); | ||
ShrinkwrapPackage.prototype.constructor = ShrinkwrapPackage; | ||
|
||
ShrinkwrapPackage.prototype._super$init = Package.prototype.init; | ||
ShrinkwrapPackage.prototype.init = function(name, versionSpecified, versionInstalled, parents) { | ||
this.parents = parents; | ||
}; | ||
|
||
ShrinkwrapPackage.prototype.updateRequired = function() { | ||
return this.versionSpecified !== this.versionInstalled; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mixonic Do you think we should change this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe shrinkwrap will output a file with a range, so it seems unlikely to make a difference in practice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Good to know. |
||
}; | ||
|
||
module.exports = ShrinkwrapPackage; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
'use strict'; | ||
|
||
var path = require('path'); | ||
var fs = require('fs'); | ||
function readFile(path){ | ||
if (fs.existsSync(path)) { | ||
return fs.readFileSync(path); | ||
} | ||
} | ||
|
||
module.exports = function readPackageJSON(projectRoot) { | ||
var filePath = path.join(projectRoot, 'package.json'); | ||
try { | ||
return JSON.parse(readFile(filePath)); | ||
} catch (e) { | ||
return null; | ||
} | ||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to check dependencies on
init
, not in theincluded
hook since only build commands invokeincluded
. See @rwjblue 's comment on #23.