Skip to content

Commit

Permalink
feat: support sequentially applying upgrades for Poetry
Browse files Browse the repository at this point in the history
Support optionally upgrading 1 package at a time, this
is much slower but can provide better success in upgrading
vulnerable package versions
  • Loading branch information
lili2311 committed Sep 14, 2021
1 parent 325f999 commit f423a71
Show file tree
Hide file tree
Showing 3 changed files with 616 additions and 13 deletions.
Expand Up @@ -35,11 +35,15 @@ interface PyProjectToml {
};
}

function chooseFixStrategy(options: FixOptions) {
return options.sequentialFix ? fixSequentially : fixAll;
}

export async function updateDependencies(
entity: EntityToFix,
options: FixOptions,
): Promise<PluginFixResponse> {
const handlerResult = await fixAll(entity, options);
const handlerResult = await chooseFixStrategy(options)(entity, options);
return handlerResult;
}

Expand Down Expand Up @@ -171,6 +175,64 @@ async function fixAll(
return handlerResult;
}

async function fixSequentially(
entity: EntityToFix,
options: FixOptions,
): Promise<PluginFixResponse> {
const handlerResult: PluginFixResponse = {
succeeded: [],
failed: [],
skipped: [],
};
const { upgrades, devUpgrades } = await generateUpgrades(entity);
// TODO: for better support we need to:
// 1. parse the manifest and extract original requirements, version spec etc
// 2. swap out only the version and retain original spec
// 3. re-lock the lockfile
const changes: FixChangesSummary[] = [];

try {
// update prod dependencies first
if (upgrades.length) {
for (const upgrade of upgrades) {
changes.push(...(await poetryAdd(entity, options, [upgrade])));
}
}

// update dev dependencies second
if (devUpgrades.length) {
for (const upgrade of devUpgrades) {
const installDev = true;
changes.push(
...(await poetryAdd(entity, options, [upgrade], installDev)),
);
}
}

if (!changes.length || !changes.some((c) => isSuccessfulChange(c))) {
debug('Manifest has not changed as no changes got applied!');
// throw the first error tip since 100% failed, they all failed with the same
// error
const { reason, tip } = changes[0] as FixChangesError;
throw new NoFixesCouldBeAppliedError(reason, tip);
}
handlerResult.succeeded.push({
original: entity,
changes,
});
} catch (error) {
debug(
`Failed to fix ${entity.scanResult.identity.targetFile}.\nERROR: ${error}`,
);
handlerResult.failed.push({
original: entity,
tip: error.tip,
error,
});
}
return handlerResult;
}

async function poetryAdd(
entity: EntityToFix,
options: FixOptions,
Expand Down
1 change: 1 addition & 0 deletions packages/snyk-fix/src/types.ts
Expand Up @@ -239,6 +239,7 @@ export interface FixOptions {
dryRun?: boolean;
quiet?: boolean;
stripAnsi?: boolean;
sequentialFix?: boolean;
}

export interface FixedMeta {
Expand Down

0 comments on commit f423a71

Please sign in to comment.