Skip to content

Commit

Permalink
refactor: don't create .npminstall.done file (#277)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Jul 31, 2018
1 parent 6e6d4fc commit 05a31ee
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 63 deletions.
17 changes: 16 additions & 1 deletion bin/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ if (inChina) {
registry = registry || globalConfig.chineseRegistry;
}
// for env.npm_config_registry
registry = registry || 'https://registry.npmjs.org';
registry = registry || 'https://registry.npmjs.com';

const proxy = argv.proxy || process.env.npm_proxy || process.env.npm_config_proxy;

Expand Down Expand Up @@ -279,6 +279,21 @@ co(function* () {
const exists = yield fs.exists(pkgFile);
if (!exists) {
console.warn(chalk.yellow(`npminstall WARN package.json not exists: ${pkgFile}`));
} else {
// try to read npminstall config from package.json
const pkg = yield utils.readJSON(pkgFile);
pkg.config = pkg.config || {};
pkg.config.npminstall = pkg.config.npminstall || {};
// {
// "config": {
// "npminstall": {
// "prune": true
// }
// }
// }
if (pkg.config.npminstall.prune === true) {
config.prune = true;
}
}
}
yield installLocal(config);
Expand Down
6 changes: 3 additions & 3 deletions lib/download/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ function* getFullPackageMeta(name, options) {
timeout: options.timeout,
followRedirect: true,
gzip: true,
dataType: 'json',
}, options);
options.totalJSONSize += result.res.size;
options.totalJSONCount += 1;
Expand All @@ -126,7 +127,6 @@ function* getFullPackageMeta(name, options) {

function* download(pkg, options) {
const ungzipDir = options.ungzipDir || utils.getPackageStorePath(options.storeDir, pkg);
const donefile = path.join(ungzipDir, '.npminstall.done');

// make sure only one download for a version
const key = `download:${pkg.name}@${pkg.version}`;
Expand All @@ -147,7 +147,7 @@ function* download(pkg, options) {
done: false,
};

if (yield fs.exists(donefile)) {
if (yield utils.isInstallDone(ungzipDir)) {
options.cache[key].done = true;
options.events.emit(key);
// debug('[%s@%s] Exists', pkg.name, pkg.version);
Expand Down Expand Up @@ -204,7 +204,7 @@ function* download(pkg, options) {
pkg.dependencies = Object.assign({}, pkg.dependencies, pkg.__fixDependencies);
}

yield fs.writeFile(donefile, Date());
yield utils.setInstallDone(ungzipDir);

const pkgMeta = {
_from: `${pkg.name}@${pkg.version}`,
Expand Down
2 changes: 1 addition & 1 deletion lib/format_install_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ module.exports = function formatInstallOptions(options) {
options.latestPackages = new Map();
options.cache = {};
assert(options.root && typeof options.root === 'string', 'options.root required and must be string');
options.registry = options.registry || 'https://registry.npmjs.org';
options.registry = options.registry || 'https://registry.npmjs.com';
if (!options.targetDir) {
options.targetDir = options.root;
}
Expand Down
13 changes: 3 additions & 10 deletions lib/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,14 @@ function* get(url, options, globalOptions) {

function* _get(url, options, retry, globalOptions) {
try {
const result = yield urllib.request(url, options);
if (result.data && Buffer.isBuffer(result.data) && result.data.length > 0 &&
options.headers.accept &&
options.headers.accept.indexOf('application/vnd.npm.install-v1+json') >= 0) {
result.data = JSON.parse(result.data);
debug('%s support vnd.npm.install-v1+json format, modified', result.data.name, result.data.modified);
}
return result;
return yield urllib.request(url, options);
} catch (err) {
retry--;
if (retry > 0) {
const delay = 100 * (MAX_RETRY - retry);
const logger = globalOptions && globalOptions.console || console;
logger.warn('[npminstall:get] retry GET %s after %sms, retry left %s, error: %s',
url, delay, retry, err);
logger.warn('[npminstall:get] retry GET %s after %sms, retry left %s, error: %s, status: %s, headers: %j, \nstack: %s',
url, delay, retry, err, err.status, err.headers, err.stack);
yield utils.sleep(delay);
return yield _get(url, options, retry, globalOptions);
}
Expand Down
1 change: 0 additions & 1 deletion lib/global_install.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ module.exports = function* globalInstall(options) {
console.info(chalk.gray(`Copying ${result.dir} to ${targetDir}`));
yield utils.rimraf(targetDir);
yield fs.rename(result.dir, targetDir);
yield fs.unlink(path.join(targetDir, '.npminstall.done'));
yield utils.rimraf(tmpDir);

console.info(chalk.gray(`Installing ${realPkg.name}'s dependencies to ${targetDir}/node_modules`));
Expand Down
5 changes: 2 additions & 3 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ function* _install(parentDir, pkg, ancestors, options) {
const info = yield download(p, options);
const realPkg = info.package;
const realPkgDir = info.dir;
const donefile = path.join(realPkgDir, '.npminstall.done');

// record version
options.packageVersions[realPkg.name] = options.packageVersions[realPkg.name] || new Set();
Expand Down Expand Up @@ -283,9 +282,9 @@ function* _install(parentDir, pkg, ancestors, options) {
} catch (err) {
// delete donefile when install error, make sure this package won't be skipped during next installation.
try {
yield utils.rimraf(donefile);
yield utils.unsetInstallDone(realPkgDir);
} catch (e) {
options.console.warn(chalk.yellow(`rmdir donefile: ${donefile} error: ${e}, ignore it`));
options.console.warn(chalk.yellow(`unsetInstallDone: ${realPkgDir} error: ${e}, ignore it`));
}
throw err;
}
Expand Down
10 changes: 3 additions & 7 deletions lib/local_install.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const bin = require('./bin');
* npm install
* @param {Object} options - install options
* - {String} root - npm install root dir
* - {String} [registry] - npm registry url, default is `https://registry.npmjs.org`
* - {String} [registry] - npm registry url, default is `https://registry.npmjs.com`
* - {String} [targetDir] - node_modules target dir, default is ${root}.
* - {String} [storeDir] - npm modules store dir, default is `${targetDir}/node_modules`
* - {Number} [timeout] - npm registry request timeout, default is 60000 ms
Expand Down Expand Up @@ -339,7 +339,6 @@ function* runPostInstallTasks(options) {
const pkg = task.pkg;
const root = task.root;
const displayName = task.displayName;
const donefile = path.join(root, '.npminstall.done');
const installScript = pkg.scripts.install;
const postinstallScript = pkg.scripts.postinstall;
try {
Expand Down Expand Up @@ -378,9 +377,9 @@ function* runPostInstallTasks(options) {
} catch (err) {
// If post install execute error, make sure this package won't be skipped during next installation.
try {
yield utils.rimraf(donefile);
yield utils.unsetInstallDone(root);
} catch (e) {
options.console.warn(chalk.yellow(`rmdir donefile: ${donefile} error: ${e}, ignore it`));
options.console.warn(chalk.yellow(`unsetInstallDone: ${root} error: ${e}, ignore it`));
}
if (task.optional) {
console.warn(chalk.red('%s optional error: %s'), displayName, err.stack);
Expand Down Expand Up @@ -492,7 +491,4 @@ function finishInstall(options) {
} else {
options.console.info.apply(console, logArguments);
}

const doneFile = path.join(options.storeDir, '.npminstall.done');
fs.writeFileSync(doneFile, `All packages installed at ${Date()}`);
}
30 changes: 25 additions & 5 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ exports.readPackageJSON = function* readPackageJSON(root) {
return pkg;
};

const INSTALL_DONE_KEY = '__npminstall_done';

// 设置 pkg 安装完成的标记
exports.setInstallDone = function* setInstallDone(pkgRoot) {
yield exports.addMetaToJSONFile(path.join(pkgRoot, 'package.json'), {
[INSTALL_DONE_KEY]: Date(),
});
};

exports.unsetInstallDone = function* setInstallDone(pkgRoot) {
yield exports.addMetaToJSONFile(path.join(pkgRoot, 'package.json'), {
[INSTALL_DONE_KEY]: false,
});
};

// 判断 pkg 是否已经安装完成
exports.isInstallDone = function* isInstallDone(pkgRoot) {
const pkg = yield exports.readJSON(path.join(pkgRoot, 'package.json'));
return !!pkg[INSTALL_DONE_KEY];
};

exports.addMetaToJSONFile = function* (filepath, meta) {
yield fs.chmod(filepath, '644');
const pkg = yield exports.readJSON(filepath);
Expand Down Expand Up @@ -128,7 +149,7 @@ function setNpmPackageEnv(env, key, value) {
exports.formatPackageUrl = function formatUrl(registry, name) {
if (name[0] === '@') {
// dont encodeURIComponent @ char, it will be 405
// https://registry.npmjs.org/%40rstacruz%2Ftap-spec/%3E%3D4.1.1
// https://registry.npmjs.com/%40rstacruz%2Ftap-spec/%3E%3D4.1.1
name = '@' + utility.encodeURIComponent(name.substring(1));
}
const parsed = url.parse(registry);
Expand Down Expand Up @@ -348,7 +369,6 @@ exports.copyInstall = function* (src, options) {
}

const targetdir = options.ungzipDir || exports.getPackageStorePath(options.storeDir, realPkg);
const donefile = path.join(targetdir, '.npminstall.done');
const key = `copy:${targetdir}`;
const result = {
dir: targetdir,
Expand All @@ -370,10 +390,10 @@ exports.copyInstall = function* (src, options) {
done: false,
};

if (!(yield fs.exists(donefile))) {
if (!(yield exports.isInstallDone(targetdir))) {
yield fse.emptydir(targetdir);
yield fse.copy(src, targetdir);
yield fs.writeFile(donefile, Date());
yield exports.setInstallDone(targetdir);
result.exists = false;
}

Expand Down Expand Up @@ -412,7 +432,7 @@ function* getRemotePackage(name, registry, globalOptions) {
const registries = [ registry ].concat([
'https://registry.npm.taobao.org',
'https://r.cnpmjs.org',
'https://registry.npmjs.org',
'https://registry.npmjs.com',
]);
let lastErr;
let pkg;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"runscript": "^1.2.1",
"semver": "^5.3.0",
"tar": "^4.0.1",
"urllib": "^2.24.0",
"urllib": "^2.29.1",
"utility": "^1.14.0",
"uuid": "^3.0.1"
},
Expand Down
4 changes: 2 additions & 2 deletions test/bundleDependencies.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('test/bundleDependencies.test.js', () => {

// only node-pre-gyp dir exists
const dirs = yield fs.readdir(path.join(tmp, 'node_modules/'));
assert.deepEqual(dirs.sort(), [ '.bin', '_node-pre-gyp@0.6.19@node-pre-gyp', '.npminstall.done', 'node-pre-gyp' ].sort());
assert.deepEqual(dirs.sort(), [ '.bin', '_node-pre-gyp@0.6.19@node-pre-gyp', 'node-pre-gyp' ].sort());
});

it('should install bundleDependencies not exist(nyc@6.4.2)', function* () {
Expand All @@ -53,7 +53,7 @@ describe('test/bundleDependencies.test.js', () => {
root: tmp,
pkgs: [{
name: 'sqlite3',
version: '4.0.0',
version: '4.0.2',
// version: '3.1.3',
}],
});
Expand Down
17 changes: 9 additions & 8 deletions test/cleanup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const path = require('path');
const rimraf = require('rimraf');
const fs = require('mz/fs');
const mkdirp = require('mkdirp');
const utils = require('../lib/utils');
const npminstall = require('./npminstall');

describe('test/cleanup.test.js', () => {
Expand Down Expand Up @@ -34,8 +35,8 @@ describe('test/cleanup.test.js', () => {
}
assert(throwError);

let exists = yield fs.exists(path.join(tmp, 'node_modules/_install-error@1.0.1@install-error/.npminstall.done'));
assert.equal(exists, false);
let done = yield utils.isInstallDone(path.join(tmp, 'node_modules/_install-error@1.0.1@install-error/package.json'));
assert.equal(done, false);
const dirs = yield fs.readdir(path.join(tmp, 'node_modules'));
assert.deepEqual(dirs, [ '_install-error@1.0.1@install-error' ]);

Expand All @@ -52,8 +53,8 @@ describe('test/cleanup.test.js', () => {
throwError = true;
}
assert.equal(throwError, true);
exists = yield fs.exists(path.join(tmp, 'node_modules/_install-error@1.0.1@install-error/.npminstall.done'));
assert.equal(exists, false);
done = yield utils.isInstallDone(path.join(tmp, 'node_modules/_install-error@1.0.1@install-error/.npminstall.done'));
assert.equal(done, false);
});

it('should remove donefile when execute postinstall script failed', function* () {
Expand All @@ -69,8 +70,8 @@ describe('test/cleanup.test.js', () => {
}
assert.equal(throwError, true);

let exists = yield fs.exists(path.join(tmp, 'node_modules/_postinstall-error@1.0.0@postinstall-error/.npminstall.done'));
assert.equal(exists, false);
let done = yield utils.isInstallDone(path.join(tmp, 'node_modules/_postinstall-error@1.0.0@postinstall-error/.npminstall.done'));
assert.equal(done, false);

// install again will try to download
throwError = false;
Expand All @@ -83,7 +84,7 @@ describe('test/cleanup.test.js', () => {
throwError = true;
}
assert.equal(throwError, true);
exists = yield fs.exists(path.join(tmp, 'node_modules/_postinstall-error@1.0.0@postinstall-error/.npminstall.done'));
assert.equal(exists, false);
done = yield utils.isInstallDone(path.join(tmp, 'node_modules/_postinstall-error@1.0.0@postinstall-error/.npminstall.done'));
assert.equal(done, false);
});
});
14 changes: 14 additions & 0 deletions test/fixtures/install-enable-prune-on-pkg/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "install-enable-prune-on-pkg",
"dependencies": {
"pedding": "~1.0.0",
"npm": "*",
"egg": "*",
"antd": "*"
},
"config": {
"npminstall": {
"prune": true
}
}
}
4 changes: 2 additions & 2 deletions test/ignoreScripts.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ describe('test/ignoreScripts.test.js', () => {
});

const dirs = yield fs.readdir(path.join(root, 'node_modules'));
assert.deepEqual(dirs.sort(), [ '_pkg@1.0.0@pkg', '.npminstall.done', '.package_versions.json', 'pkg' ].sort());
assert.deepEqual(dirs.sort(), [ '_pkg@1.0.0@pkg', '.package_versions.json', 'pkg' ].sort());
const files = yield fs.readdir(path.join(root, 'node_modules/pkg'));
assert.deepEqual(files, [ '.npminstall.done', 'index.js', 'package.json' ]);
assert.deepEqual(files, [ 'index.js', 'package.json' ]);
});
});
6 changes: 3 additions & 3 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const fs = require('mz/fs');
const path = require('path');
const rimraf = require('rimraf');
const npminstall = require('./npminstall');
const utils = require('../lib/utils');
const mkdirp = require('../lib/utils').mkdirp;
const readJSON = require('../lib/utils').readJSON;

Expand All @@ -31,8 +32,7 @@ describe('test/index.test.js', () => {
{ name: 'contributors' },
],
});
// tmp/node_modules/.npminstall.done file should exists
assert(fs.existsSync(path.join(tmp, 'node_modules/.npminstall.done')));
assert(yield utils.isInstallDone(path.join(tmp, 'node_modules/mocha')));
});

it('should handle @types/escodegen@0.0.2 tgz', function* () {
Expand All @@ -42,7 +42,7 @@ describe('test/index.test.js', () => {
{ name: '@types/escodegen', version: '0.0.2' },
],
});
assert(fs.existsSync(path.join(tmp, 'node_modules/.npminstall.done')));
assert(yield utils.isInstallDone(path.join(tmp, 'node_modules/@types/escodegen')));
assert(fs.existsSync(path.join(tmp, 'node_modules/@types/escodegen/package.json')));
assert(require(path.join(tmp, 'node_modules/@types/escodegen/package.json')).name === '@types/escodegen');
});
Expand Down

0 comments on commit 05a31ee

Please sign in to comment.