Rely on npm version rather than node version to determine which scanner to use. Fixes #46

This commit is contained in:
Sander Declerck 2025-09-15 09:39:41 +02:00
parent 5658eb04af
commit 4e3fe7b738
No known key found for this signature in database
5 changed files with 30 additions and 22 deletions

View file

@ -1,8 +1,19 @@
#!/usr/bin/env node #!/usr/bin/env node
import { execSync } from "child_process";
import { main } from "../src/main.js"; import { main } from "../src/main.js";
import { initializePackageManager } from "../src/packagemanager/currentPackageManager.js"; import { initializePackageManager } from "../src/packagemanager/currentPackageManager.js";
const packageManagerName = "npm"; const packageManagerName = "npm";
initializePackageManager(packageManagerName, process.versions.node); initializePackageManager(packageManagerName, getNpmVersion());
await main(process.argv.slice(2)); await main(process.argv.slice(2));
function getNpmVersion() {
try {
return execSync("npm --version").toString().trim();
} catch {
// Default to 0.0.0 if npm is not found
// That way we don't use any unsupported features
return "0.0.0";
}
}

View file

@ -14,10 +14,13 @@ import {
} from "./utils/npmCommands.js"; } from "./utils/npmCommands.js";
export function createNpmPackageManager(version) { export function createNpmPackageManager(version) {
const supportedScanners = // From npm v10.4.0 onwards, the npm commands output detailed information
getMajorVersion(version) >= 22 // when using the --dry-run flag.
? npm22AndAboveSupportedScanners // We use that information to scan for dependency changes.
: npm21AndBelowSupportedScanners; // For older versions of npm we have to rely on parsing the command arguments.
const supportedScanners = isPriorToNpm10_4(version)
? npm10_3AndBelowSupportedScanners
: npm10_4AndAboveSupportedScanners;
function isSupportedCommand(args) { function isSupportedCommand(args) {
const scanner = findDependencyScannerForCommand(supportedScanners, args); const scanner = findDependencyScannerForCommand(supportedScanners, args);
@ -30,14 +33,13 @@ export function createNpmPackageManager(version) {
} }
return { return {
getWarningMessage: () => warnForLimitedSupport(version),
runCommand: runNpm, runCommand: runNpm,
isSupportedCommand, isSupportedCommand,
getDependencyUpdatesForCommand, getDependencyUpdatesForCommand,
}; };
} }
const npm22AndAboveSupportedScanners = { const npm10_4AndAboveSupportedScanners = {
[npmInstallCommand]: dryRunScanner(), [npmInstallCommand]: dryRunScanner(),
[npmUpdateCommand]: dryRunScanner(), [npmUpdateCommand]: dryRunScanner(),
[npmCiCommand]: dryRunScanner(), [npmCiCommand]: dryRunScanner(),
@ -53,23 +55,22 @@ const npm22AndAboveSupportedScanners = {
[npmInstallCiTestCommand]: dryRunScanner({ dryRunCommand: npmCiCommand }), [npmInstallCiTestCommand]: dryRunScanner({ dryRunCommand: npmCiCommand }),
}; };
const npm21AndBelowSupportedScanners = { const npm10_3AndBelowSupportedScanners = {
[npmInstallCommand]: commandArgumentScanner(), [npmInstallCommand]: commandArgumentScanner(),
[npmUpdateCommand]: commandArgumentScanner(), [npmUpdateCommand]: commandArgumentScanner(),
[npmExecCommand]: commandArgumentScanner({ ignoreDryRun: true }), // exec command doesn't support dry-run [npmExecCommand]: commandArgumentScanner({ ignoreDryRun: true }), // exec command doesn't support dry-run
}; };
function warnForLimitedSupport(version) { function isPriorToNpm10_4(version) {
if (getMajorVersion(version) >= 22) { try {
return null; const [major, minor] = version.split(".").map(Number);
if (major < 10) return true;
if (major === 10 && minor < 4) return true;
return false;
} catch {
// Default to true: if version parsing fails, assume it's an older version
return true;
} }
return `Aikido-npm will only scan the arguments of the install command for Node.js version prior to version 22.
Please update your Node.js version to 22 or higher for full coverage. Current version: v${version}`;
}
function getMajorVersion(version) {
return parseInt(version.split(".")[0]);
} }
function findDependencyScannerForCommand(scanners, args) { function findDependencyScannerForCommand(scanners, args) {

View file

@ -5,7 +5,6 @@ export function createNpxPackageManager() {
const scanner = commandArgumentScanner(); const scanner = commandArgumentScanner();
return { return {
getWarningMessage: () => null,
runCommand: runNpx, runCommand: runNpx,
isSupportedCommand: (args) => scanner.shouldScan(args), isSupportedCommand: (args) => scanner.shouldScan(args),
getDependencyUpdatesForCommand: (args) => scanner.scan(args), getDependencyUpdatesForCommand: (args) => scanner.scan(args),

View file

@ -6,7 +6,6 @@ const scanner = commandArgumentScanner();
export function createPnpmPackageManager() { export function createPnpmPackageManager() {
return { return {
getWarningMessage: () => null,
runCommand: (args) => runPnpmCommand(args, "pnpm"), runCommand: (args) => runPnpmCommand(args, "pnpm"),
isSupportedCommand: (args) => isSupportedCommand: (args) =>
matchesCommand(args, "add") || matchesCommand(args, "add") ||
@ -26,7 +25,6 @@ export function createPnpmPackageManager() {
export function createPnpxPackageManager() { export function createPnpxPackageManager() {
return { return {
getWarningMessage: () => null,
runCommand: (args) => runPnpmCommand(args, "pnpx"), runCommand: (args) => runPnpmCommand(args, "pnpx"),
isSupportedCommand: () => true, isSupportedCommand: () => true,
getDependencyUpdatesForCommand: (args) => getDependencyUpdatesForCommand: (args) =>

View file

@ -5,7 +5,6 @@ const scanner = commandArgumentScanner();
export function createYarnPackageManager() { export function createYarnPackageManager() {
return { return {
getWarningMessage: () => null,
runCommand: runYarnCommand, runCommand: runYarnCommand,
isSupportedCommand: (args) => isSupportedCommand: (args) =>
matchesCommand(args, "add") || matchesCommand(args, "add") ||