npm support: simplify and rename

This commit is contained in:
Avital Oliver
2013-01-22 22:16:05 -08:00
committed by David Glasser
parent 19b8b32dc6
commit 65e8b86421
2 changed files with 35 additions and 34 deletions

View File

@@ -29,8 +29,15 @@ var meteorNpm = module.exports = {
// we can then atomically rename it. we also make sure to
// randomize the name, in case we're bundling this package
// multiple times in parallel.
var tmpPackageNpmDir = packageNpmDir + '-new-' + self._randomToken();
fs.mkdirSync(tmpPackageNpmDir);
var newPackageNpmDir = packageNpmDir + '-new-' + self._randomToken();
fs.mkdirSync(newPackageNpmDir);
// create .gitignore -- node_modules shouldn't be in git since we
// recreate it as needed by using `npm install`. since we use `npm
// shrinkwrap` we're guaranteed to have the same version installed
// each time.
fs.writeFileSync(
path.join(newPackageNpmDir, '.gitignore'),
['node_modules'].join('\n'));
try {
if (fs.existsSync(packageNpmDir)) {
@@ -43,22 +50,21 @@ var meteorNpm = module.exports = {
// - call `npm prune` to remove any unused packages from node_modules
// - call `npm shrinkwrap` to update npm-shrinkwrap.json
// - copy the temporary directory back to .npm
self._updateExistingNpmDirectory(packageName, tmpPackageNpmDir, packageNpmDir, npmDependencies);
self._updateExistingNpmDirectory(packageName, newPackageNpmDir, packageNpmDir, npmDependencies);
} else {
// create a temporary directory for the new contents of .npm:
// - create .gitignore
// - install npm modules
// - call `npm shrinkwrap` to create npm-shrinkwrap.json
// - copy the temporary directory to .npm
self._createFreshNpmDirectory(packageName, tmpPackageNpmDir, packageNpmDir, npmDependencies);
self._createFreshNpmDirectory(packageName, newPackageNpmDir, packageNpmDir, npmDependencies);
}
} finally {
if (fs.existsSync(tmpPackageNpmDir))
files.rm_recursive(tmpPackageNpmDir);
if (fs.existsSync(newPackageNpmDir))
files.rm_recursive(newPackageNpmDir);
}
},
_updateExistingNpmDirectory: function(packageName, tmpPackageNpmDir, packageNpmDir, npmDependencies) {
_updateExistingNpmDirectory: function(packageName, newPackageNpmDir, packageNpmDir, npmDependencies) {
var self = this;
// sanity check on contents of .npm directory
@@ -79,47 +85,38 @@ var meteorNpm = module.exports = {
// don't do npm work unnecessarily
if (!_.isEqual(installedDependencies, npmDependencies)) {
// copy over npm-shrinkwrap.json
fs.writeFileSync(path.join(tmpPackageNpmDir, 'npm-shrinkwrap.json'),
fs.writeFileSync(path.join(newPackageNpmDir, 'npm-shrinkwrap.json'),
fs.readFileSync(path.join(packageNpmDir, 'npm-shrinkwrap.json')));
// construct package.json
self._constructPackageJson(packageName, tmpPackageNpmDir, npmDependencies);
self._constructPackageJson(packageName, newPackageNpmDir, npmDependencies);
// `npm install`
self._installFromShrinkwrap(tmpPackageNpmDir);
self._installFromShrinkwrap(newPackageNpmDir);
// `npm install name@version` for modules that need updating
_.each(npmDependencies, function(version, name) {
if (installedDependencies[name] !== version) {
self._installNpmModule(name, version, tmpPackageNpmDir);
self._installNpmModule(name, version, newPackageNpmDir);
}
});
// remove ununsed packages
self._prune(tmpPackageNpmDir);
self._prune(newPackageNpmDir);
self._finalizeTmpPackageDirAndRename(tmpPackageNpmDir, packageNpmDir);
self._finalizeTmpPackageDirAndRename(newPackageNpmDir, packageNpmDir);
}
},
_createFreshNpmDirectory: function(packageName, tmpPackageNpmDir, packageNpmDir, npmDependencies) {
_createFreshNpmDirectory: function(packageName, newPackageNpmDir, packageNpmDir, npmDependencies) {
var self = this;
// create .gitignore -- node_modules shouldn't be in git since we
// recreate it as needed by using `npm install`. since we use `npm
// shrinkwrap` we're guaranteed to have the same version installed
// each time.
fs.writeFileSync(path.join(tmpPackageNpmDir, '.gitignore'),
['node_modules'].join('\n'));
// install dependencies
_.each(npmDependencies, function(version, name) {
self._installNpmModule(name, version, tmpPackageNpmDir);
self._installNpmModule(name, version, newPackageNpmDir);
});
// construct package.json, which is needed for consistent results of `npm shrinkwrap`
self._constructPackageJson(packageName, tmpPackageNpmDir, npmDependencies);
self._finalizeTmpPackageDirAndRename(tmpPackageNpmDir, packageNpmDir);
self._finalizeTmpPackageDirAndRename(newPackageNpmDir, packageNpmDir);
},
_execFileSync: function(file, args, opts) {
@@ -136,14 +133,14 @@ var meteorNpm = module.exports = {
})().wait();
},
_constructPackageJson: function(packageName, tmpPackageNpmDir, npmDependencies) {
_constructPackageJson: function(packageName, newPackageNpmDir, npmDependencies) {
var packageJsonContents = JSON.stringify({
// name and version are unimportant but required for `npm install`
name: 'packages-for-meteor-smartpackage-' + packageName,
version: '0.0.0',
dependencies: npmDependencies
});
var packageJsonPath = path.join(tmpPackageNpmDir, 'package.json');
var packageJsonPath = path.join(newPackageNpmDir, 'package.json');
fs.writeFileSync(packageJsonPath, packageJsonContents);
},
@@ -152,20 +149,20 @@ var meteorNpm = module.exports = {
// - rename original .npm dir to another name (require for atomicity in next step)
// - atomically rename temporary package npm dir to the original package's .npm dir
// - delete the renamed original .npm directory
_finalizeTmpPackageDirAndRename: function(tmpPackageNpmDir, packageNpmDir) {
_finalizeTmpPackageDirAndRename: function(newPackageNpmDir, packageNpmDir) {
var self = this;
if (fs.existsSync(path.join(tmpPackageNpmDir, 'package.json')))
fs.unlinkSync(path.join(tmpPackageNpmDir, 'package.json'));
self._shrinkwrap(tmpPackageNpmDir);
if (fs.existsSync(path.join(newPackageNpmDir, 'package.json')))
fs.unlinkSync(path.join(newPackageNpmDir, 'package.json'));
self._shrinkwrap(newPackageNpmDir);
if (fs.existsSync(packageNpmDir)) {
var oldPackageNpmDir = packageNpmDir + '-old-' + self._randomToken();;
fs.renameSync(packageNpmDir, oldPackageNpmDir);
fs.renameSync(tmpPackageNpmDir, packageNpmDir);
fs.renameSync(newPackageNpmDir, packageNpmDir);
files.rm_recursive(oldPackageNpmDir);
} else {
fs.renameSync(tmpPackageNpmDir, packageNpmDir);
fs.renameSync(newPackageNpmDir, packageNpmDir);
}
},

View File

@@ -41,6 +41,10 @@ var _assertCorrectPackageNpmDir = function(deps) {
JSON.stringify({
dependencies: expectedMeteorNpmShrinkwrapDependencies}, null, /*indentation, the way npm does it*/2) + '\n');
assert.equal(
fs.readFileSync(path.join(testPackageDir, ".npm", ".gitignore"), 'utf8'),
"node_modules");
// verify the contents of the `node_modules` dir
var nodeModulesDir = path.join(testPackageDir, ".npm", "node_modules");