From 3ff8649e9a75f1a39251e6c65c4d84ee07a8821b Mon Sep 17 00:00:00 2001 From: renovate-testing <77205328+renovate-testing@users.noreply.github.com> Date: Sun, 21 Mar 2021 02:19:59 +0300 Subject: [PATCH] fix(npm): Fix replace strategy edge-case for carets (#9106) --- lib/versioning/npm/index.spec.ts | 10 ++++++ lib/versioning/npm/range.ts | 52 +++++++++++++++++++++++------ lib/versioning/poetry/index.spec.ts | 4 +-- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/lib/versioning/npm/index.spec.ts b/lib/versioning/npm/index.spec.ts index 510f0652a8767e..09b1d752137978 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 f3bfbea053b02e..46cfcfcdcc14bb 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 4779aa30415655..2b2ee1aa4a52c9 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(