Skip to content

Commit

Permalink
feat(npm): optimize remediation to detect already updated branches (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
rarkins committed Feb 8, 2022
1 parent 98ed29c commit 9a43d32
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 7 deletions.
26 changes: 25 additions & 1 deletion lib/manager/npm/update/locked-dependency/index.spec.ts
Expand Up @@ -120,13 +120,37 @@ describe('manager/npm/update/locked-dependency/index', () => {
const packageLock = JSON.parse(res.files['package-lock.json']);
expect(packageLock.dependencies.express.version).toBe('4.1.0');
});
it('returns if already remediated', async () => {
it('returns already-updated if already remediated exactly', async () => {
config.depName = 'mime';
config.currentVersion = '1.2.10';
config.newVersion = '1.2.11';
const res = await updateLockedDependency(config);
expect(res.status).toBe('already-updated');
});
it('returns already-updated if already remediated higher', async () => {
config.depName = 'mime';
config.currentVersion = '1.2.9';
config.newVersion = '1.2.10';
config.allowHigherOrRemoved = true;
const res = await updateLockedDependency(config);
expect(res.status).toBe('already-updated');
});
it('returns already-updated if not found', async () => {
config.depName = 'notfound';
config.currentVersion = '1.2.9';
config.newVersion = '1.2.10';
config.allowHigherOrRemoved = true;
const res = await updateLockedDependency(config);
expect(res.status).toBe('already-updated');
});
it('returns update-failed if other, lower version found', async () => {
config.depName = 'mime';
config.currentVersion = '1.2.5';
config.newVersion = '1.2.15';
config.allowHigherOrRemoved = true;
const res = await updateLockedDependency(config);
expect(res.status).toBe('update-failed');
});
it('remediates mime', async () => {
config.depName = 'mime';
config.currentVersion = '1.2.11';
Expand Down
Expand Up @@ -36,6 +36,11 @@ describe('manager/npm/update/locked-dependency/package-lock/get-locked', () => {
},
]);
});
it('finds any version', () => {
expect(getLockedDependencies(packageLockJson, 'send', null)).toHaveLength(
2
);
});
it('finds bundled dependency', () => {
expect(
getLockedDependencies(bundledPackageLockJson, 'ansi-regex', '3.0.0')
Expand Down
Expand Up @@ -5,7 +5,7 @@ import type { PackageLockDependency, PackageLockOrEntry } from './types';
export function getLockedDependencies(
entry: PackageLockOrEntry,
depName: string,
currentVersion: string,
currentVersion: string | null,
bundled = false
): PackageLockDependency[] {
let res: PackageLockDependency[] = [];
Expand All @@ -15,7 +15,7 @@ export function getLockedDependencies(
return [];
}
const dep = dependencies[depName];
if (dep?.version === currentVersion) {
if (dep && (currentVersion === null || dep?.version === currentVersion)) {
if (bundled || entry.bundled) {
dep.bundled = true;
}
Expand Down
41 changes: 37 additions & 4 deletions lib/manager/npm/update/locked-dependency/package-lock/index.ts
Expand Up @@ -22,6 +22,7 @@ export async function updateLockedDependency(
lockFile,
lockFileContent,
allowParentUpdates = true,
allowHigherOrRemoved = false,
} = config;
logger.debug(
`npm.updateLockedDependency: ${depName}@${currentVersion} -> ${newVersion} [${lockFile}]`
Expand Down Expand Up @@ -66,10 +67,42 @@ export async function updateLockedDependency(
);
status = 'already-updated';
} else {
logger.debug(
`${depName}@${currentVersion} not found in ${lockFile} - cannot update`
);
status = 'update-failed';
if (allowHigherOrRemoved) {
// it's acceptable if the package is no longer present
const anyVersionLocked = getLockedDependencies(
packageLockJson,
depName,
null
);
if (anyVersionLocked.length) {
if (
anyVersionLocked.every((dep) =>
semver.isGreaterThan(dep.version, newVersion)
)
) {
logger.debug(
`${depName} found in ${lockFile} with higher version - looks like it's already updated`
);
status = 'already-updated';
} else {
logger.debug(
{ anyVersionLocked },
`Found alternative versions of qs`
);
status = 'update-failed';
}
} else {
logger.debug(
`${depName} not found in ${lockFile} - looks like it's already removed`
);
status = 'already-updated';
}
} else {
logger.debug(
`${depName}@${currentVersion} not found in ${lockFile} - cannot update`
);
status = 'update-failed';
}
}
// Don't return {} if we're a parent update or else the whole update will fail
// istanbul ignore if: too hard to replicate
Expand Down
1 change: 1 addition & 0 deletions lib/manager/types.ts
Expand Up @@ -229,6 +229,7 @@ export interface UpdateLockedConfig {
currentVersion?: string;
newVersion?: string;
allowParentUpdates?: boolean;
allowHigherOrRemoved?: boolean;
}

export interface UpdateLockedResult {
Expand Down
1 change: 1 addition & 0 deletions lib/workers/branch/get-updated.ts
Expand Up @@ -75,6 +75,7 @@ export async function getUpdatedPackageFiles(
packageFileContent,
lockFileContent,
allowParentUpdates: true,
allowHigherOrRemoved: true,
});
if (reuseExistingBranch && status !== 'already-updated') {
logger.debug(
Expand Down

0 comments on commit 9a43d32

Please sign in to comment.