Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: replacement for pep440 versioning #17882

Merged
117 changes: 117 additions & 0 deletions lib/modules/versioning/pep440/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,123 @@ describe('modules/versioning/pep440/index', () => {
}
);

test.each`
currentValue | rangeStrategy | currentVersion | newVersion | expected
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'1.0.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'1.0.0'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.0.3'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.0.3'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.0.3'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=1.2.0'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=1.2.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.2.0'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.2.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=1.2.0'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.2.0'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.0.3'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.0.3'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.0.3'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.2.*'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.2.*'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.2.*'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.0.*'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.0.*'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'==1.0.*'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2.2.3'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2.2.3'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2.3'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2.3'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2.3'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1.2'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<1'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<2.0.0'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<2.0.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'<2.0.0'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>0.9.8'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>0.9.8'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>0.9.8'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>2.0.0'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>2.0.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>2.0.0'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=2.0.0'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=2.0.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=2.0.0'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0, !=1.1.1'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0, !=1.1.1'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0, !=1.1.1'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0,!=1.1.1'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0,!=1.1.1'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0,!=1.1.1'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${' '} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${' '} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${' '} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'invalid'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'invalid'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'invalid'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'===1.0.3'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'===1.0.3'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'===1.0.3'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'!=1.2.3'} | ${'bump'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'!=1.2.3'} | ${'replace'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'!=1.2.3'} | ${'pin'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'~=1.1.0,!=1.1.1'} | ${'unsupported'} | ${'1.0.0'} | ${'1.2.3'} | ${'1.2.3'}
${'>=19.12.2,<20.13.9'} | ${'replace'} | ${'19.12.2'} | ${'21.3.1'} | ${'21.3.1'}
${'>=19.12.2,<19.13.9'} | ${'replace'} | ${'19.12.2'} | ${'20.3.1'} | ${'20.3.1'}
${'>=19.12.2,<19.13.0'} | ${'replace'} | ${'19.12.2'} | ${'20.3.1'} | ${'20.3.1'}
${'>=19.12.2,<19.13.0'} | ${'replace'} | ${'19.12.2'} | ${'20.3.0'} | ${'20.3.0'}
${'>=19.12.2,<19.13.0'} | ${'replace'} | ${'19.12.2'} | ${'19.13.1'} | ${'19.13.1'}
${'>=19.12.2,<19.13.0'} | ${'replace'} | ${'19.12.2'} | ${'19.13.0'} | ${'19.13.0'}
${'>=19.12.2,<19.13.0'} | ${'auto'} | ${'19.12.2'} | ${'19.13.0'} | ${'19.13.0'}
${'>=19.12.2,<20.13.9'} | ${'widen'} | ${'19.12.2'} | ${'21.3.1'} | ${'21.3.1'}
${'>=19.12.2,<19.13.9'} | ${'widen'} | ${'19.12.2'} | ${'20.3.1'} | ${'20.3.1'}
${'>=19.12.2,<19.13.0'} | ${'widen'} | ${'19.12.2'} | ${'20.3.1'} | ${'20.3.1'}
${'>=19.12.2,<19.13.0'} | ${'widen'} | ${'19.12.2'} | ${'20.3.0'} | ${'20.3.0'}
${'>=19.12.2,<19.13.0'} | ${'widen'} | ${'19.12.2'} | ${'19.13.1'} | ${'19.13.1'}
${'>=19.12.2,<19.13.0'} | ${'widen'} | ${'19.12.2'} | ${'19.13.0'} | ${'19.13.0'}
${'~=7.2'} | ${'replace'} | ${'7.2.0'} | ${'8.0.1'} | ${'8.0.1'}
${'~=7.2'} | ${'replace'} | ${'7.2.0'} | ${'8'} | ${'8'}
${'~=7.2.0'} | ${'replace'} | ${'7.2.0'} | ${'8.2'} | ${'8.2'}
${'~=7.2'} | ${'widen'} | ${'7.2.0'} | ${'8.0.1'} | ${'8.0.1'}
${'~=7.2'} | ${'widen'} | ${'7.2.0'} | ${'8'} | ${'8'}
${'~=7.2.0'} | ${'widen'} | ${'7.2.0'} | ${'8.2'} | ${'8.2'}
${'==3.2.*,>=3.2.2'} | ${'replace'} | ${'3.2.2'} | ${'4.1.1'} | ${'4.1.1'}
${'==3.2.*,>=3.2.2'} | ${'replace'} | ${'3.2.2'} | ${'4.0.0'} | ${'4.0.0'}
${'>=1.0.0,<1.1.0'} | ${'replace'} | ${'1.0.0'} | ${'1.2.0'} | ${'1.2.0'}
${'<1.3.0'} | ${'bump'} | ${'1.3.0'} | ${'0.9.2'} | ${'0.9.2'}
${'<1.3.0'} | ${'bump'} | ${'0.9.0'} | ${'0.9.2'} | ${'0.9.2'}
${'<=1.3.0'} | ${'bump'} | ${'0.9.0'} | ${'0.9.2'} | ${'0.9.2'}
${'<=1.3.0'} | ${'bump'} | ${'1.3.0'} | ${'0.9.2'} | ${'0.9.2'}
${'<1.3.0'} | ${'bump'} | ${'1.3.0'} | ${'1.6.0'} | ${'1.6.0'}
${'<1.3.0'} | ${'bump'} | ${'0.9.0'} | ${'1.6.0'} | ${'1.6.0'}
${'<=1.3.0'} | ${'bump'} | ${'0.9.0'} | ${'1.6.0'} | ${'1.6.0'}
${'<=1.3.0'} | ${'bump'} | ${'1.3.0'} | ${'1.6.0'} | ${'1.6.0'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'==1.2.3'} | ${'==1.2.3'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'>=1.2.3'} | ${'>=1.2.3'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'<=1.2.3'} | ${'<=1.2.3'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'~=1.2.3'} | ${'~=1.2.3'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'!=1.2.3'} | ${'!=1.2.3'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'>1.2.3'} | ${'>1.2.3'}
${'1.0.0'} | ${'bump'} | ${'1.0.0'} | ${'<1.2.3'} | ${'<1.2.3'}
`(
'getNewValue("$currentValue", "$rangeStrategy", "$currentVersion", "$newVersion") === "$expected"',
({ currentValue, rangeStrategy, currentVersion, newVersion, expected }) => {
const isReplacement = true;
const res = pep440.getNewValue({
currentValue,
rangeStrategy,
currentVersion,
newVersion,
isReplacement,
});
expect(res).toEqual(expected);
}
);

test.each`
version | range | expected
${'0.9.9.9'} | ${'>= 1.0.0, < 2.0.0'} | ${true}
Expand Down
5 changes: 3 additions & 2 deletions lib/modules/versioning/pep440/range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,16 @@ export function getNewValue({
rangeStrategy,
currentVersion,
newVersion,
isReplacement,
}: NewValueConfig): string | null {
let ranges: Range[];
let updatedRange: (string | null)[];
if (rangeStrategy === 'pin') {
if (rangeStrategy === 'pin' && !isReplacement) {
return '==' + newVersion;
}

// no symbol: accept only that specific version specified
if (currentValue === currentVersion) {
if (currentValue === currentVersion || isReplacement) {
return newVersion;
}

Expand Down
1 change: 1 addition & 0 deletions lib/modules/versioning/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface NewValueConfig {
rangeStrategy: RangeStrategy;
currentVersion?: string;
newVersion: string;
isReplacement?: boolean;
}
export interface VersioningApi {
// validation
Expand Down
7 changes: 4 additions & 3 deletions lib/workers/repository/process/lookup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,16 @@ export async function lookupUpdates(
res.updates.push(rollback);
}
let rangeStrategy = getRangeStrategy(config);
if (dependency.replacementName && dependency.replacementVersion) {
if (config.replacementName && config.replacementVersion) {
res.updates.push({
updateType: 'replacement',
newName: dependency.replacementName,
newName: config.replacementName,
newValue: versioning.getNewValue({
// TODO #7154
currentValue: currentValue!,
newVersion: dependency.replacementVersion,
newVersion: config.replacementVersion,
rangeStrategy: rangeStrategy!,
isReplacement: true,
})!,
});
}
Expand Down
2 changes: 2 additions & 0 deletions lib/workers/repository/process/lookup/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export interface LookupUpdateConfig
depName: string;
minimumConfidence?: string;
extractedConstraints?: Record<string, string>;
replacementVersion?: string;
replacementName?: string;
}

export interface UpdateResult {
Expand Down