check-node-version
Advanced tools
Comparing version 4.0.1 to 4.0.2
#!/usr/bin/env node | ||
require('./gatekeeper'); | ||
require('./cli'); | ||
require("./gatekeeper"); | ||
require("./cli"); |
## Releases | ||
### 4.0.2 | ||
* Make notfound-catch locale-independent on Windows | ||
### 4.0.1 | ||
@@ -4,0 +8,0 @@ |
20
cli.js
@@ -102,15 +102,15 @@ "use strict"; | ||
if (isSatisfied) return; | ||
// report any non-compliant versions | ||
if (!isSatisfied) { | ||
const { raw, range } = info.wanted; | ||
const { raw, range } = info.wanted; | ||
console.error(chalk.red(`Wanted ${name} version ` + chalk.bold(`${raw} (${range})`))); | ||
console.error(chalk.red(`Wanted ${name} version ` + chalk.bold(`${raw} (${range})`))); | ||
console.log(chalk.yellow.bold( | ||
tools[name] | ||
.getInstallInstructions( | ||
semver.minVersion(info.wanted) | ||
) | ||
)); | ||
} | ||
console.log(chalk.yellow.bold( | ||
tools[name] | ||
.getInstallInstructions( | ||
semver.minVersion(info.wanted) | ||
) | ||
)); | ||
}); | ||
@@ -117,0 +117,0 @@ } |
204
index.js
@@ -11,3 +11,3 @@ "use strict"; | ||
const tools = require('./tools'); | ||
const tools = require("./tools"); | ||
@@ -27,77 +27,104 @@ const runningOnWindows = (process.platform === "win32"); | ||
module.exports = function check(wanted, callback) { | ||
// Normalize arguments | ||
if (typeof wanted === "function") { | ||
callback = wanted; | ||
wanted = null; | ||
} | ||
function runVersionCommand(command, callback) { | ||
process.env.PATH = globalPath; | ||
const options = { callback }; | ||
exec(command, (execError, stdout, stderr) => { | ||
const commandDescription = JSON.stringify(command); | ||
options.wanted = normalizeWanted(wanted); | ||
if (!execError) { | ||
return callback(null, { | ||
version: stdout, | ||
}); | ||
} | ||
options.commands = mapValues( | ||
( | ||
Object.keys(options.wanted).length | ||
? filterObject(tools, (_, key) => options.wanted[key]) | ||
: tools | ||
), | ||
({ getVersion }) => ( runVersionCommand.bind(null, getVersion) ) | ||
); | ||
if ( | ||
(execError.code === 127) | ||
|| | ||
(runningOnWindows && execError.message.includes("is not recognized")) | ||
) { | ||
return callback(null, { | ||
notfound: true, | ||
}); | ||
if (runningOnWindows) { | ||
runForWindows(options); | ||
} else { | ||
run(options); | ||
} | ||
} | ||
function runForWindows(options) { | ||
// See and understand https://github.com/parshap/check-node-version/issues/35 | ||
// before trying to optimize this function | ||
// | ||
// `chcp` is used instead of `where` on account of its more extensive availablity | ||
// chcp: MS-DOS 6.22+, Windows 95+; where: Windows 7+ | ||
// | ||
// Plus, in order to be absolutely certain, the error message of `where` would still need evaluation. | ||
exec("chcp", (error, stdout) => { | ||
const finalCallback = options.callback; | ||
if (error) { | ||
finalCallback(chcpError(error, 1)); | ||
return; | ||
} | ||
// something went very wrong during execution | ||
let errorMessage = `Command failed: ${commandDescription}` | ||
const codepage = stdout.match(/\d+/)[0]; | ||
if (stderr) { | ||
errorMessage += `\n\nstderr:\n${stderr.toString().trim()}\n`; | ||
if (codepage === "65001" || codepage === "437") { | ||
// need not switch codepage | ||
return run(options); | ||
} | ||
errorMessage += `\n\noriginal error message:\n${execError.message}\n`; | ||
// reset codepage before exiting | ||
options.callback = (...args) => exec(`chcp ${codepage}`, (error) => { | ||
if (error) { | ||
finalCallback(chcpError(error, 3)); | ||
return; | ||
} | ||
return callback(new Error(errorMessage)); | ||
}); | ||
finalCallback(...args); | ||
}); | ||
process.env.PATH = originalPath; | ||
} | ||
// switch to Unicode | ||
exec("chcp 65001", (error) => { | ||
if (error) { | ||
finalCallback(chcpError(error, 2)); | ||
return; | ||
} | ||
// Return object containing only keys that a program exists for and | ||
// something valid was given. | ||
function normalizeWanted(wanted) { | ||
if (!wanted) { | ||
return {}; | ||
} | ||
run(options); | ||
}); | ||
// Validate keys | ||
wanted = filterObject(wanted, Boolean); | ||
function chcpError(error, step) { | ||
switch (step) { | ||
case 1: | ||
error.message = `[CHCP] error while getting current codepage:\n${error.message}`; | ||
break; | ||
// Normalize to strings | ||
wanted = mapValues(wanted, String); | ||
case 2: | ||
error.message = `[CHCP] error while switching to Unicode codepage:\n${error.message}`; | ||
break; | ||
// Filter existing programs | ||
wanted = filterObject(wanted, (_, key) => tools[key]); | ||
case 3: | ||
error.message = ` | ||
[CHCP] error while resetting current codepage: | ||
${error.message} | ||
return wanted; | ||
} | ||
Please note that your terminal is now using the Unicode codepage. | ||
Therefore, codepage-dependent actions may work in an unusual manner. | ||
You can run \`chcp ${codepage}\` yourself in order to reset your codepage, | ||
or just close this terminal and work in another. | ||
`.trim().replace(/^ +/gm,'') // strip indentation | ||
break; | ||
module.exports = function check(wanted, callback) { | ||
// Normalize arguments | ||
if (typeof wanted === "function") { | ||
callback = wanted; | ||
wanted = null; | ||
} | ||
// no default | ||
} | ||
wanted = normalizeWanted(wanted); | ||
return error | ||
} | ||
}); | ||
} | ||
const commands = mapValues( | ||
( | ||
Object.keys(wanted).length | ||
? filterObject(tools, (_, key) => wanted[key]) | ||
: tools | ||
), | ||
({ getVersion }) => ( runVersionCommand.bind(null, getVersion) ) | ||
); | ||
function run({ commands, callback, wanted }) { | ||
parallel(commands, (err, versionsResult) => { | ||
@@ -139,1 +166,64 @@ if (err) { | ||
}; | ||
// Return object containing only keys that a program exists for and | ||
// something valid was given. | ||
function normalizeWanted(wanted) { | ||
if (!wanted) { | ||
return {}; | ||
} | ||
// Validate keys | ||
wanted = filterObject(wanted, Boolean); | ||
// Normalize to strings | ||
wanted = mapValues(wanted, String); | ||
// Filter existing programs | ||
wanted = filterObject(wanted, (_, key) => tools[key]); | ||
return wanted; | ||
} | ||
function runVersionCommand(command, callback) { | ||
process.env.PATH = globalPath; | ||
exec(command, (execError, stdout, stderr) => { | ||
const commandDescription = JSON.stringify(command); | ||
if (!execError) { | ||
return callback(null, { | ||
version: stdout, | ||
}); | ||
} | ||
if (toolNotFound(execError)) { | ||
return callback(null, { | ||
notfound: true, | ||
}); | ||
} | ||
// something went very wrong during execution | ||
let errorMessage = `Command failed: ${commandDescription}` | ||
if (stderr) { | ||
errorMessage += `\n\nstderr:\n${stderr.toString().trim()}\n`; | ||
} | ||
errorMessage += `\n\noriginal error message:\n${execError.message}\n`; | ||
return callback(new Error(errorMessage)); | ||
}); | ||
process.env.PATH = originalPath; | ||
} | ||
function toolNotFound(execError) { | ||
if (runningOnWindows) { | ||
return execError.message.includes("is not recognized"); | ||
} | ||
return execError.code === 127; | ||
} |
{ | ||
"name": "check-node-version", | ||
"version": "4.0.1", | ||
"version": "4.0.2", | ||
"engines": { | ||
@@ -15,3 +15,3 @@ "node": ">=8.3.0" | ||
"build-readme": "gitdown ./README_src.md --output-file ./README.md", | ||
"test": "ava" | ||
"test": "ava -v" | ||
}, | ||
@@ -39,3 +39,3 @@ "husky": { | ||
"dependencies": { | ||
"chalk": "^2.3.0", | ||
"chalk": "^3.0.0", | ||
"map-values": "^1.0.1", | ||
@@ -45,12 +45,12 @@ "minimist": "^1.2.0", | ||
"run-parallel": "^1.1.4", | ||
"semver": "^5.7.0" | ||
"semver": "^6.3.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^1.3.1", | ||
"gitdown": "^2.5.7", | ||
"husky": "^1.3.1", | ||
"ava": "^2.4.0", | ||
"gitdown": "^3.1.2", | ||
"husky": "^3.1.0", | ||
"npm": "3.10.10", | ||
"npm-run-all": "^4.1.5", | ||
"proxyquire": "^2.1.0" | ||
"proxyquire": "^2.1.3" | ||
} | ||
} |
@@ -170,3 +170,3 @@ <a name="check-node-version"></a> | ||
{ node: ">= 18.3", }, | ||
(error, results) => { | ||
(error, result) => { | ||
if (error) { | ||
@@ -177,3 +177,3 @@ console.error(error); | ||
if (results.isSatisfied) { | ||
if (result.isSatisfied) { | ||
console.log("All is well."); | ||
@@ -185,4 +185,4 @@ return; | ||
for (const packageName of Object.keys(results.versions)) { | ||
if (!results.versions[packageName].isSatisfied) { | ||
for (const packageName of Object.keys(result.versions)) { | ||
if (!result.versions[packageName].isSatisfied) { | ||
console.error(`Missing ${packageName}.`); | ||
@@ -189,0 +189,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22646
455
+ Addedansi-styles@4.3.0(transitive)
+ Addedchalk@3.0.0(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedsemver@6.3.1(transitive)
+ Addedsupports-color@7.2.0(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedsemver@5.7.2(transitive)
- Removedsupports-color@5.5.0(transitive)
Updatedchalk@^3.0.0
Updatedsemver@^6.3.0