diff --git a/lib/versioning/npm/index.spec.ts b/lib/versioning/npm/index.spec.ts index 510f0652a8767ec4ce2f2f207f6acaf5953b5dc6..09b1d752137978581b2ce3d61f14886cb9a82638 100644 --- a/lib/versioning/npm/index.spec.ts +++ b/lib/versioning/npm/index.spec.ts @@ -84,6 +84,16 @@ describe('semver.getNewValue()', () => { ['^1.2.3', '4.0.0', '^4.0.0'], ['^1.2.3', '4.5.6', '^4.0.0'], ['^1.0.0', '4.5.6', '^4.0.0'], + + ['^0.2.3', '0.2.4', '^0.2.3'], + ['^2.3.0', '2.4.0', '^2.3.0'], + ['^2.3.4', '2.4.5', '^2.3.4'], + ['^0.0.1', '0.0.2', '^0.0.2'], + ['^1.0.1', '2.0.2', '^2.0.0'], + ['^1.2.3', '1.2.3', '^1.2.3'], + ['^1.2.3', '1.2.2', '^1.2.2'], + + ['^0.9.21', '0.9.22', '^0.9.21'], // #4762 ].forEach(([currentValue, newVersion, expectedValue]) => { expect( semver.getNewValue({ diff --git a/lib/versioning/npm/range.ts b/lib/versioning/npm/range.ts index f3bfbea053b02e03c1206f5261b759866164c383..46cfcfcdcc14bb7fe76b440dbb992886b0692497 100644 --- a/lib/versioning/npm/range.ts +++ b/lib/versioning/npm/range.ts @@ -11,6 +11,47 @@ import { parseRange } from 'semver-utils'; import { logger } from '../../logger'; import type { NewValueConfig } from '../types'; +function replaceCaretValue(oldValue: string, newValue: string): string { + const toVersionMajor = major(newValue); + const toVersionMinor = minor(newValue); + const toVersionPatch = patch(newValue); + + const currentMajor = major(oldValue); + const currentMinor = minor(oldValue); + const currentPatch = patch(oldValue); + + const oldTuple = [currentMajor, currentMinor, currentPatch]; + const newTuple = [toVersionMajor, toVersionMinor, toVersionPatch]; + const resultTuple = []; + + let leadingZero = true; + let needReplace = false; + for (let idx = 0; idx < 3; idx += 1) { + const oldVal = oldTuple[idx]; + const newVal = newTuple[idx]; + + let leadingDigit = false; + if (oldVal !== 0 || newVal !== 0) { + if (leadingZero) { + leadingZero = false; + leadingDigit = true; + } + } + + if (leadingDigit && newVal > oldVal) { + needReplace = true; + } + + if (!needReplace && newVal < oldVal) { + return newValue; + } + + resultTuple.push(leadingDigit ? newVal : 0); + } + + return needReplace ? resultTuple.join('.') : oldValue; +} + export function getNewValue({ currentValue, rangeStrategy, @@ -150,16 +191,7 @@ export function getNewValue({ if (suffix.length || !currentVersion) { return `^${toVersionMajor}.${toVersionMinor}.${toVersionPatch}${suffix}`; } - if (toVersionMajor === major(currentVersion)) { - if (toVersionMajor === 0) { - if (toVersionMinor === 0) { - return `^${newVersion}`; - } - return `^${toVersionMajor}.${toVersionMinor}.0`; - } - return `^${newVersion}`; - } - return `^${toVersionMajor}.0.0`; + return `^${replaceCaretValue(currentVersion, newVersion)}`; } if (element.operator === '=') { return `=${newVersion}`; diff --git a/lib/versioning/poetry/index.spec.ts b/lib/versioning/poetry/index.spec.ts index 4779aa3041565564132460d886790658f947ac0d..2b2ee1aa4a52c99d66e40a2ac313a898f8619158 100644 --- a/lib/versioning/poetry/index.spec.ts +++ b/lib/versioning/poetry/index.spec.ts @@ -420,9 +420,9 @@ describe(getName(__filename), () => { currentValue: '^1.0.0', rangeStrategy: 'replace', currentVersion: '1.0.0', - newVersion: '1.0.7', + newVersion: '1.2.3', }) - ).toEqual('^1.0.7'); + ).toEqual('^1.0.0'); }); it('bumps short tilde', () => { expect(