Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 9c1f8ea

Browse files
committed
chore(check-node-modules): make check/reinstall node_modules work across platforms
The previous implementations (based on shell scripts) threw errors on Windows, because it was not able to `rm -rf` 'node_modules' (due to the 255 character limit in file-paths). This implementation works consistently across platforms and is heavily based on 'https://github.com/angular/angular/blob/3b9c08676a4c921bbfa847802e08566fb601ba7a/tools/npm/check-node-modules.js'. Fixes #11143 Closes #11353 Closes #12792
1 parent 9fde564 commit 9c1f8ea

6 files changed

+140
-18
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ install:
4848
- npm config set loglevel http
4949
- npm install -g npm@2.5
5050
# Instal npm dependecies and ensure that npm cache is not stale
51-
- scripts/npm/install-dependencies.sh
51+
- npm install
5252

5353
before_script:
5454
- mkdir -p $LOGS_DIR

Gruntfile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ module.exports = function(grunt) {
305305

306306
shell: {
307307
"npm-install": {
308-
command: path.normalize('scripts/npm/install-dependencies.sh')
308+
command: 'node scripts/npm/check-node-modules.js'
309309
},
310310

311311
"promises-aplus-tests": {

package.json

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
"npm": "~2.5"
1414
},
1515
"engineStrict": true,
16+
"scripts": {
17+
"preinstall": "node scripts/npm/check-node-modules.js --purge",
18+
"postinstall": "node scripts/npm/copy-npm-shrinkwrap.js"
19+
},
1620
"devDependencies": {
1721
"angular-benchpress": "0.x.x",
1822
"benchmark": "1.x.x",

scripts/npm/check-node-modules.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Implementation based on:
2+
// https://github.com/angular/angular/blob/3b9c08676a4c921bbfa847802e08566fb601ba7a/tools/npm/check-node-modules.js
3+
'use strict';
4+
5+
// Imports
6+
var fs = require('fs');
7+
var path = require('path');
8+
9+
// Constants
10+
var PROJECT_ROOT = path.join(__dirname, '../../');
11+
var NODE_MODULES_DIR = 'node_modules';
12+
var NPM_SHRINKWRAP_FILE = 'npm-shrinkwrap.json';
13+
var NPM_SHRINKWRAP_CACHED_FILE = NODE_MODULES_DIR + '/npm-shrinkwrap.cached.json';
14+
15+
// Run
16+
_main();
17+
18+
// Functions - Definitions
19+
function _main() {
20+
var purgeIfStale = process.argv.indexOf('--purge') !== -1;
21+
22+
process.chdir(PROJECT_ROOT);
23+
checkNodeModules(purgeIfStale);
24+
}
25+
26+
function checkNodeModules(purgeIfStale) {
27+
var nodeModulesOk = compareMarkerFiles(NPM_SHRINKWRAP_FILE, NPM_SHRINKWRAP_CACHED_FILE);
28+
29+
if (nodeModulesOk) {
30+
console.log(':-) npm dependencies are looking good!');
31+
} else if (purgeIfStale) {
32+
console.log(':-( npm dependencies are stale or in an unknown state!');
33+
console.log(' Purging \'' + NODE_MODULES_DIR + '\'...');
34+
deleteDirSync(NODE_MODULES_DIR);
35+
} else {
36+
var separator = new Array(81).join('!');
37+
38+
console.warn(separator);
39+
console.warn(':-( npm dependencies are stale or in an unknown state!');
40+
console.warn('You can rebuild the dependencies by running `npm install`.');
41+
console.warn(separator);
42+
}
43+
44+
return nodeModulesOk;
45+
}
46+
47+
function compareMarkerFiles(markerFilePath, cachedMarkerFilePath) {
48+
if (!fs.existsSync(cachedMarkerFilePath)) return false;
49+
50+
var opts = {encoding: 'utf-8'};
51+
var markerContent = fs.readFileSync(markerFilePath, opts);
52+
var cachedMarkerContent = fs.readFileSync(cachedMarkerFilePath, opts);
53+
54+
return markerContent === cachedMarkerContent;
55+
}
56+
57+
// Custom implementation of `rm -rf` that works consistently across OSes
58+
function deleteDirSync(path) {
59+
if (fs.existsSync(path)) {
60+
fs.readdirSync(path).forEach(deleteDirOrFileSync);
61+
fs.rmdirSync(path);
62+
}
63+
64+
// Helpers
65+
function deleteDirOrFileSync(subpath) {
66+
var curPath = path + '/' + subpath;
67+
68+
if (fs.lstatSync(curPath).isDirectory()) {
69+
deleteDirSync(curPath);
70+
} else {
71+
fs.unlinkSync(curPath);
72+
}
73+
}
74+
}

scripts/npm/copy-npm-shrinkwrap.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
// Imports
4+
var fs = require('fs');
5+
var path = require('path');
6+
7+
// Constants
8+
var PROJECT_ROOT = path.join(__dirname, '../../');
9+
var NODE_MODULES_DIR = 'node_modules';
10+
var NPM_SHRINKWRAP_FILE = 'npm-shrinkwrap.json';
11+
var NPM_SHRINKWRAP_CACHED_FILE = NODE_MODULES_DIR + '/npm-shrinkwrap.cached.json';
12+
13+
// Run
14+
_main();
15+
16+
// Functions - Definitions
17+
function _main() {
18+
process.chdir(PROJECT_ROOT);
19+
copyFile(NPM_SHRINKWRAP_FILE, NPM_SHRINKWRAP_CACHED_FILE, onCopied);
20+
}
21+
22+
// Implementation based on:
23+
// https://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js#answer-21995878
24+
function copyFile(srcPath, dstPath, callback) {
25+
var callbackCalled = false;
26+
27+
if (!fs.existsSync(srcPath)) {
28+
done(new Error('Missing source file: ' + srcPath));
29+
return;
30+
}
31+
32+
var rs = fs.createReadStream(srcPath);
33+
rs.on('error', done);
34+
35+
var ws = fs.createWriteStream(dstPath);
36+
ws.on('error', done);
37+
ws.on('finish', done);
38+
39+
rs.pipe(ws);
40+
41+
// Helpers
42+
function done(err) {
43+
if (callback && !callbackCalled) {
44+
callbackCalled = true;
45+
callback(err);
46+
}
47+
}
48+
}
49+
50+
function onCopied(err) {
51+
if (err) {
52+
var separator = new Array(81).join('!');
53+
54+
console.error(separator);
55+
console.error(
56+
'Failed to copy `' + NPM_SHRINKWRAP_FILE + '` to `' + NPM_SHRINKWRAP_CACHED_FILE + '`:');
57+
console.error(err);
58+
console.error(separator);
59+
}
60+
}

scripts/npm/install-dependencies.sh

-16
This file was deleted.

0 commit comments

Comments
 (0)