mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-21 09:51:58 +00:00
Add npm preinstall check for npm version 6.9.0 or later
Older npm versions cause the npm-shrinkwrap.json file to be incorrectly updated. This should avoid regression bugs related to issue #1332. https://github.com/balena-io/balena-cli/issues/1332 Change-type: patch Signed-off-by: Paulo Castro <paulo@balena.io>
This commit is contained in:
parent
09444f0cff
commit
e7c89cf77c
@ -79,6 +79,7 @@ some additional development tools to be installed first:
|
|||||||
|
|
||||||
* Node.js version 8, 10 or 12 (on Linux/Mac, [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
|
* Node.js version 8, 10 or 12 (on Linux/Mac, [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
|
||||||
is recommended)
|
is recommended)
|
||||||
|
* npm version 6.9.0 or later
|
||||||
* Python 2.7
|
* Python 2.7
|
||||||
* g++ compiler
|
* g++ compiler
|
||||||
* make
|
* make
|
||||||
|
62
automation/check-npm-version.js
Normal file
62
automation/check-npm-version.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that semver v1 is greater than or equal to semver v2.
|
||||||
|
*
|
||||||
|
* We don't `require('semver')` to allow this script to be run as a npm
|
||||||
|
* 'preinstall' hook, at which point no dependencies have been installed.
|
||||||
|
*/
|
||||||
|
function semverGte(v1, v2) {
|
||||||
|
let v1Array, v2Array; // number[]
|
||||||
|
try {
|
||||||
|
const [, major1, minor1, patch1] = /v?(\d+)\.(\d+).(\d+)/.exec(v1);
|
||||||
|
const [, major2, minor2, patch2] = /v?(\d+)\.(\d+).(\d+)/.exec(v2);
|
||||||
|
v1Array = [parseInt(major1), parseInt(minor1), parseInt(patch1)];
|
||||||
|
v2Array = [parseInt(major2), parseInt(minor2), parseInt(patch2)];
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Invalid semver versions: '${v1}' or '${v2}'`);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (v1Array[i] < v2Array[i]) {
|
||||||
|
return false;
|
||||||
|
} else if (v1Array[i] > v2Array[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _testSemverGet() {
|
||||||
|
const assert = require('assert').strict;
|
||||||
|
assert(semverGte('6.4.1', '6.4.1'));
|
||||||
|
assert(semverGte('6.4.1', 'v6.4.1'));
|
||||||
|
assert(semverGte('v6.4.1', '6.4.1'));
|
||||||
|
assert(semverGte('v6.4.1', 'v6.4.1'));
|
||||||
|
assert(semverGte('6.4.1', '6.4.0'));
|
||||||
|
assert(semverGte('6.4.1', '6.3.1'));
|
||||||
|
assert(semverGte('6.4.1', '5.4.1'));
|
||||||
|
assert(!semverGte('6.4.1', '6.4.2'));
|
||||||
|
assert(!semverGte('6.4.1', '6.5.1'));
|
||||||
|
assert(!semverGte('6.4.1', '7.4.1'));
|
||||||
|
|
||||||
|
assert(semverGte('v6.4.1', 'v4.0.0'));
|
||||||
|
assert(!semverGte('v6.4.1', 'v6.9.0'));
|
||||||
|
assert(!semverGte('v6.4.1', 'v7.0.0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkNpmVersion() {
|
||||||
|
const execSync = require('child_process').execSync;
|
||||||
|
const npmVersion = execSync('npm --version')
|
||||||
|
.toString()
|
||||||
|
.trim();
|
||||||
|
const requiredVersion = '6.9.0';
|
||||||
|
if (!semverGte(npmVersion, requiredVersion)) {
|
||||||
|
console.error(`\
|
||||||
|
Error: npm version '${npmVersion}' detected. Please upgrade to npm v${requiredVersion} or later
|
||||||
|
because of a bug affecting older versions in relation to the npm-shrinkwrap.json file.`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkNpmVersion();
|
@ -39,6 +39,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"preinstall": "node automation/check-npm-version.js",
|
||||||
"postinstall": "patch-package",
|
"postinstall": "patch-package",
|
||||||
"prebuild": "rimraf build/ build-bin/",
|
"prebuild": "rimraf build/ build-bin/",
|
||||||
"build": "npm run build:src",
|
"build": "npm run build:src",
|
||||||
@ -54,7 +55,7 @@
|
|||||||
"test:fast": "npm run build:fast && npm run test",
|
"test:fast": "npm run build:fast && npm run test",
|
||||||
"ci": "npm run test && catch-uncommitted",
|
"ci": "npm run test && catch-uncommitted",
|
||||||
"watch": "gulp watch",
|
"watch": "gulp watch",
|
||||||
"prettify": "prettier --write \"{lib,tests,automation,typings}/**/*.ts\" --config ./node_modules/resin-lint/config/.prettierrc",
|
"prettify": "prettier --write \"{lib,tests,automation,typings}/**/*.[tj]s\" --config ./node_modules/resin-lint/config/.prettierrc",
|
||||||
"lint": "resin-lint lib/ tests/ && resin-lint --typescript automation/ lib/ typings/ tests/",
|
"lint": "resin-lint lib/ tests/ && resin-lint --typescript automation/ lib/ typings/ tests/",
|
||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
},
|
},
|
||||||
|
@ -48,7 +48,7 @@ index a9d4276..75c2f8b 100644
|
|||||||
exports.default = PackWin;
|
exports.default = PackWin;
|
||||||
const scripts = {
|
const scripts = {
|
||||||
diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/build.js b/node_modules/@oclif/dev-cli/lib/tarballs/build.js
|
diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/build.js b/node_modules/@oclif/dev-cli/lib/tarballs/build.js
|
||||||
index 3e613e0..129d041 100644
|
index 3e613e0..dd23903 100644
|
||||||
--- a/node_modules/@oclif/dev-cli/lib/tarballs/build.js
|
--- a/node_modules/@oclif/dev-cli/lib/tarballs/build.js
|
||||||
+++ b/node_modules/@oclif/dev-cli/lib/tarballs/build.js
|
+++ b/node_modules/@oclif/dev-cli/lib/tarballs/build.js
|
||||||
@@ -17,8 +17,11 @@ const pack = async (from, to) => {
|
@@ -17,8 +17,11 @@ const pack = async (from, to) => {
|
||||||
@ -64,7 +64,7 @@ index 3e613e0..129d041 100644
|
|||||||
const packCLI = async () => {
|
const packCLI = async () => {
|
||||||
const stdout = await qq.x.stdout('npm', ['pack', '--unsafe-perm'], { cwd: c.root });
|
const stdout = await qq.x.stdout('npm', ['pack', '--unsafe-perm'], { cwd: c.root });
|
||||||
return path.join(c.root, stdout.split('\n').pop());
|
return path.join(c.root, stdout.split('\n').pop());
|
||||||
@@ -34,6 +37,28 @@ async function build(c, options = {}) {
|
@@ -34,6 +37,34 @@ async function build(c, options = {}) {
|
||||||
await qq.mv(f, '.');
|
await qq.mv(f, '.');
|
||||||
await qq.rm('package', tarball, 'bin/run.cmd');
|
await qq.rm('package', tarball, 'bin/run.cmd');
|
||||||
};
|
};
|
||||||
@ -75,11 +75,17 @@ index 3e613e0..129d041 100644
|
|||||||
+ const sources = [
|
+ const sources = [
|
||||||
+ 'bin', 'build', 'patches', 'typings', 'CHANGELOG.md', 'INSTALL.md',
|
+ 'bin', 'build', 'patches', 'typings', 'CHANGELOG.md', 'INSTALL.md',
|
||||||
+ 'LICENSE', 'package.json', 'npm-shrinkwrap.json', 'README.md',
|
+ 'LICENSE', 'package.json', 'npm-shrinkwrap.json', 'README.md',
|
||||||
+ 'TROUBLESHOOTING.md',
|
+ 'TROUBLESHOOTING.md', 'automation/check-npm-version.js',
|
||||||
+ ];
|
+ ];
|
||||||
+ for (const source of sources) {
|
+ for (const source of sources) {
|
||||||
|
+ let destDir = ws;
|
||||||
|
+ const dirname = path.dirname(source);
|
||||||
|
+ if (dirname && dirname !== '.') {
|
||||||
|
+ destDir = path.join(ws, dirname);
|
||||||
|
+ qq.mkdirp(destDir);
|
||||||
|
+ }
|
||||||
+ console.log(`cp "${source}" -> "${ws}"`);
|
+ console.log(`cp "${source}" -> "${ws}"`);
|
||||||
+ await qq.cp(path.join(c.root, source), ws);
|
+ await qq.cp(path.join(c.root, source), destDir);
|
||||||
+ }
|
+ }
|
||||||
+ // rename the original balena-cli ./bin/balena entry point for oclif compatibility
|
+ // rename the original balena-cli ./bin/balena entry point for oclif compatibility
|
||||||
+ await qq.mv('bin/balena', 'bin/run');
|
+ await qq.mv('bin/balena', 'bin/run');
|
||||||
@ -93,7 +99,7 @@ index 3e613e0..129d041 100644
|
|||||||
const updatePJSON = async () => {
|
const updatePJSON = async () => {
|
||||||
qq.cd(c.workspace());
|
qq.cd(c.workspace());
|
||||||
const pjson = await qq.readJSON('package.json');
|
const pjson = await qq.readJSON('package.json');
|
||||||
@@ -56,7 +81,13 @@ async function build(c, options = {}) {
|
@@ -56,7 +87,13 @@ async function build(c, options = {}) {
|
||||||
lockpath = qq.join(c.root, 'npm-shrinkwrap.json');
|
lockpath = qq.join(c.root, 'npm-shrinkwrap.json');
|
||||||
}
|
}
|
||||||
await qq.cp(lockpath, '.');
|
await qq.cp(lockpath, '.');
|
||||||
@ -108,7 +114,7 @@ index 3e613e0..129d041 100644
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const buildTarget = async (target) => {
|
const buildTarget = async (target) => {
|
||||||
@@ -71,7 +102,8 @@ async function build(c, options = {}) {
|
@@ -71,7 +108,8 @@ async function build(c, options = {}) {
|
||||||
output: path.join(workspace, 'bin', 'node'),
|
output: path.join(workspace, 'bin', 'node'),
|
||||||
platform: target.platform,
|
platform: target.platform,
|
||||||
arch: target.arch,
|
arch: target.arch,
|
||||||
@ -118,7 +124,7 @@ index 3e613e0..129d041 100644
|
|||||||
});
|
});
|
||||||
if (options.pack === false)
|
if (options.pack === false)
|
||||||
return;
|
return;
|
||||||
@@ -124,7 +156,8 @@ async function build(c, options = {}) {
|
@@ -124,7 +162,8 @@ async function build(c, options = {}) {
|
||||||
await qq.writeJSON(c.dist(config.s3Key('manifest')), manifest);
|
await qq.writeJSON(c.dist(config.s3Key('manifest')), manifest);
|
||||||
};
|
};
|
||||||
log_1.log(`gathering workspace for ${config.bin} to ${c.workspace()}`);
|
log_1.log(`gathering workspace for ${config.bin} to ${c.workspace()}`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user