mirror of
https://github.com/warkanum/monorepo-dep-checker.git
synced 2025-10-22 11:43:54 +00:00
Added strict mode to check version ranges
This commit is contained in:
parent
2ffa2bd0ca
commit
3ca78de94c
@ -52,9 +52,16 @@ const cli = async () => {
|
|||||||
default: 'text',
|
default: 'text',
|
||||||
type:'string'
|
type:'string'
|
||||||
})
|
})
|
||||||
|
.option('strict', {
|
||||||
|
alias: 's',
|
||||||
|
describe: 'Strict mode: only update packages with version ranges (~, ^, >=) if they are incompatible',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
.example('$0 --check-versions', 'Show only version differences')
|
.example('$0 --check-versions', 'Show only version differences')
|
||||||
.example('$0 --check-missing', 'Show missing dependencies')
|
.example('$0 --check-missing', 'Show missing dependencies')
|
||||||
.example('$0 --update --dry-run', 'Show what would be updated')
|
.example('$0 --update --dry-run', 'Show what would be updated')
|
||||||
|
.example('$0 --update --strict', 'Update only incompatible versions within ranges')
|
||||||
.example('$0 --packages ./packages,./other-packages', 'Check multiple package directories')
|
.example('$0 --packages ./packages,./other-packages', 'Check multiple package directories')
|
||||||
.example('$0 --packages ./pkg1/package.json,./pkg2/package.json', 'Check specific package.json files')
|
.example('$0 --packages ./pkg1/package.json,./pkg2/package.json', 'Check specific package.json files')
|
||||||
.example('$0 --packages ./packages,./other/package.json', 'Mix of directories and files')
|
.example('$0 --packages ./packages,./other/package.json', 'Mix of directories and files')
|
||||||
@ -135,6 +142,7 @@ const cli = async () => {
|
|||||||
format: argv.format as any,
|
format: argv.format as any,
|
||||||
checkVersions: argv.checkVersions,
|
checkVersions: argv.checkVersions,
|
||||||
checkMissing: argv.checkMissing,
|
checkMissing: argv.checkMissing,
|
||||||
|
strict: argv.strict,
|
||||||
});
|
});
|
||||||
} catch (error:any) {
|
} catch (error:any) {
|
||||||
console.error(chalk.red('Error during execution:'));
|
console.error(chalk.red('Error during execution:'));
|
||||||
|
57
src/lib.ts
57
src/lib.ts
@ -16,6 +16,7 @@ interface RunOptions {
|
|||||||
format?: "text" | "json";
|
format?: "text" | "json";
|
||||||
checkVersions?: boolean;
|
checkVersions?: boolean;
|
||||||
checkMissing?: boolean;
|
checkMissing?: boolean;
|
||||||
|
strict?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VersionInfo {
|
interface VersionInfo {
|
||||||
@ -75,6 +76,7 @@ class DependencyChecker {
|
|||||||
private packageJsonFiles: string[];
|
private packageJsonFiles: string[];
|
||||||
private dependencyMap: Map<string, DependencyInfo>;
|
private dependencyMap: Map<string, DependencyInfo>;
|
||||||
private workspacePackages: Set<string>;
|
private workspacePackages: Set<string>;
|
||||||
|
private strictMode: boolean;
|
||||||
|
|
||||||
constructor(appPackageJsonPath: string, packagesInput: string) {
|
constructor(appPackageJsonPath: string, packagesInput: string) {
|
||||||
this.appPackageJsonPath = appPackageJsonPath;
|
this.appPackageJsonPath = appPackageJsonPath;
|
||||||
@ -82,6 +84,7 @@ class DependencyChecker {
|
|||||||
this.packageJsonFiles = [];
|
this.packageJsonFiles = [];
|
||||||
this.dependencyMap = new Map();
|
this.dependencyMap = new Map();
|
||||||
this.workspacePackages = new Set();
|
this.workspacePackages = new Set();
|
||||||
|
this.strictMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private findWorkspacePackages(): void {
|
private findWorkspacePackages(): void {
|
||||||
@ -147,6 +150,21 @@ class DependencyChecker {
|
|||||||
return this.workspacePackages.has(packageName);
|
return this.workspacePackages.has(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private hasVersionRange(version: string): boolean {
|
||||||
|
return /^[~^<>=]+/.test(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
private isVersionCompatible(rangeVersion: string, targetVersion: string): boolean {
|
||||||
|
try {
|
||||||
|
const cleanTargetVersion = this.getSemverVersion(targetVersion);
|
||||||
|
if (!cleanTargetVersion) return false;
|
||||||
|
|
||||||
|
return semver.satisfies(cleanTargetVersion, rangeVersion);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private shouldIncludeDependency(
|
private shouldIncludeDependency(
|
||||||
depName: string,
|
depName: string,
|
||||||
version: string,
|
version: string,
|
||||||
@ -590,15 +608,13 @@ class DependencyChecker {
|
|||||||
|
|
||||||
if (appDependencies[dep]) {
|
if (appDependencies[dep]) {
|
||||||
const appVersion = appDependencies[dep];
|
const appVersion = appDependencies[dep];
|
||||||
// Extract just the version numbers for comparison
|
|
||||||
const cleanCurrentVersion = version.replace(/^[~^<>=]+\s*/g, "");
|
// In strict mode, check if versions are compatible within range constraints
|
||||||
|
if (this.strictMode && this.hasVersionRange(version)) {
|
||||||
|
if (!this.isVersionCompatible(version, appVersion)) {
|
||||||
|
// Only update if the app version doesn't satisfy the range
|
||||||
const cleanAppVersion = appVersion.replace(/^[~^<>=]+\s*/g, "");
|
const cleanAppVersion = appVersion.replace(/^[~^<>=]+\s*/g, "");
|
||||||
|
|
||||||
if (cleanCurrentVersion !== cleanAppVersion) {
|
|
||||||
// Extract the version prefix (operators and spaces)
|
|
||||||
const versionPrefix = version.match(/^[~^<>=]+\s*/)?.[0] || '';
|
const versionPrefix = version.match(/^[~^<>=]+\s*/)?.[0] || '';
|
||||||
|
|
||||||
// Create new version string with original prefix but updated version number
|
|
||||||
const newVersion = versionPrefix + cleanAppVersion;
|
const newVersion = versionPrefix + cleanAppVersion;
|
||||||
|
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
@ -615,6 +631,30 @@ class DependencyChecker {
|
|||||||
|
|
||||||
hasUpdates = true;
|
hasUpdates = true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Original behavior for non-strict mode
|
||||||
|
const cleanCurrentVersion = version.replace(/^[~^<>=]+\s*/g, "");
|
||||||
|
const cleanAppVersion = appVersion.replace(/^[~^<>=]+\s*/g, "");
|
||||||
|
|
||||||
|
if (cleanCurrentVersion !== cleanAppVersion) {
|
||||||
|
const versionPrefix = version.match(/^[~^<>=]+\s*/)?.[0] || '';
|
||||||
|
const newVersion = versionPrefix + cleanAppVersion;
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
packageJson[section]![dep] = newVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
updates.push({
|
||||||
|
package: packageJson.name,
|
||||||
|
dependency: dep,
|
||||||
|
from: version,
|
||||||
|
to: newVersion,
|
||||||
|
type: section,
|
||||||
|
});
|
||||||
|
|
||||||
|
hasUpdates = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -768,8 +808,11 @@ class DependencyChecker {
|
|||||||
format = "text",
|
format = "text",
|
||||||
checkVersions = false,
|
checkVersions = false,
|
||||||
checkMissing = false,
|
checkMissing = false,
|
||||||
|
strict = false,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
|
this.strictMode = strict;
|
||||||
|
|
||||||
if (checkMissing) {
|
if (checkMissing) {
|
||||||
this.findPackageJsonFiles();
|
this.findPackageJsonFiles();
|
||||||
this.checkMissingDependencies();
|
this.checkMissingDependencies();
|
||||||
|
Loading…
Reference in New Issue
Block a user