From ea0b324e6ac17eed27e602c2a950c4ff51b0aed9 Mon Sep 17 00:00:00 2001 From: Sebastian Kral Date: Fri, 17 Sep 2021 11:42:38 +0200 Subject: [PATCH] feat: Add rez versioning (#10930) --- lib/versioning/api.ts | 2 + lib/versioning/index.spec.ts | 2 - lib/versioning/rez/index.spec.ts | 442 +++++++++++++++++++++ lib/versioning/rez/index.ts | 277 ++++++++++--- lib/versioning/rez/pattern.ts | 89 +++++ lib/versioning/rez/readme.md | 18 + lib/versioning/rez/transform.ts | 113 ++++++ lib/versioning/versioning-metadata.spec.ts | 3 +- 8 files changed, 883 insertions(+), 63 deletions(-) create mode 100644 lib/versioning/rez/index.spec.ts create mode 100644 lib/versioning/rez/pattern.ts create mode 100644 lib/versioning/rez/readme.md create mode 100644 lib/versioning/rez/transform.ts diff --git a/lib/versioning/api.ts b/lib/versioning/api.ts index 3cc394bb71157e..e4979283355d57 100644 --- a/lib/versioning/api.ts +++ b/lib/versioning/api.ts @@ -14,6 +14,7 @@ import * as nuget from './nuget'; import * as pep440 from './pep440'; import * as poetry from './poetry'; import * as regex from './regex'; +import * as rez from './rez'; import * as ruby from './ruby'; import * as semver from './semver'; import * as swift from './swift'; @@ -39,6 +40,7 @@ api.set('nuget', nuget.api); api.set('pep440', pep440.api); api.set('poetry', poetry.api); api.set('regex', regex.api); +api.set('rez', rez.api); api.set('ruby', ruby.api); api.set('semver', semver.api); api.set('swift', swift.api); diff --git a/lib/versioning/index.spec.ts b/lib/versioning/index.spec.ts index aa23e0d78e35fa..92097568612a07 100644 --- a/lib/versioning/index.spec.ts +++ b/lib/versioning/index.spec.ts @@ -33,8 +33,6 @@ describe('versioning/index', () => { const vers = allVersioning.getVersionings(); const loadedVers = loadModules(__dirname); - // TODO: revert rez in #10930 - delete loadedVers.rez; expect(Array.from(vers.keys())).toEqual(Object.keys(loadedVers)); for (const name of vers.keys()) { diff --git a/lib/versioning/rez/index.spec.ts b/lib/versioning/rez/index.spec.ts new file mode 100644 index 00000000000000..f7860ddc313aca --- /dev/null +++ b/lib/versioning/rez/index.spec.ts @@ -0,0 +1,442 @@ +import semver from '../semver'; +import { api as versioning } from '.'; + +describe('versioning/rez/index', () => { + test.each` + version | equal | expected + ${'1'} | ${'1'} | ${true} + ${'1.0'} | ${'1'} | ${true} + ${'1.0.0'} | ${'1'} | ${true} + ${'1.9.0'} | ${'1.9'} | ${true} + ${'1'} | ${'2'} | ${false} + ${'1.9.1'} | ${'1.9'} | ${false} + ${'1.9-beta'} | ${'1.9'} | ${false} + `( + 'equals("$version", "$equal") === $expected', + ({ version, equal, expected }) => { + expect(versioning.equals(version, equal)).toBe(expected); + } + ); + + test.each` + version | expected + ${'1'} | ${1} + ${'1.9'} | ${1} + ${'1.9.0'} | ${1} + `('getMajor("$version") === $expected', ({ version, expected }) => { + expect(versioning.getMajor(version)).toEqual(expected); + }); + + test.each` + version | expected + ${'1'} | ${0} + ${'1.9'} | ${9} + ${'1.9.0'} | ${9} + `('getMinor("$version") === $expected', ({ version, expected }) => { + expect(versioning.getMinor(version)).toEqual(expected); + }); + + test.each` + version | expected + ${'1'} | ${0} + ${'1.9'} | ${0} + ${'1.9.0'} | ${0} + ${'1.9.4'} | ${4} + `('getPatch("$version") === $expected', ({ version, expected }) => { + expect(versioning.getPatch(version)).toEqual(expected); + }); + + test.each` + version | other | expected + ${'2'} | ${'1'} | ${true} + ${'2.0'} | ${'1'} | ${true} + ${'2.0.0'} | ${'1'} | ${true} + ${'1.10.0'} | ${'1.9'} | ${true} + ${'1.9'} | ${'1.9-beta'} | ${true} + ${'1'} | ${'1'} | ${false} + ${'1.0'} | ${'1'} | ${false} + ${'1.0.0'} | ${'1'} | ${false} + ${'1.9.0'} | ${'1.9'} | ${false} + `( + 'isGreaterThan("$version", "$other") === $expected', + ({ version, other, expected }) => { + expect(versioning.isGreaterThan(version, other)).toEqual(expected); + } + ); + + test.each` + version | expected + ${'1'} | ${true} + ${'1.9'} | ${true} + ${'1.9.0'} | ${true} + ${'1.9.4'} | ${true} + ${'1.9.4-beta'} | ${false} + `('isStable("$version") === $expected', ({ version, expected }) => { + expect(versioning.isStable(version)).toEqual(expected); + }); + + test.each` + input | expected + ${'1.2.3..1.2.4'} | ${true} + ${'1.2..1.3'} | ${true} + ${'1.2..2'} | ${true} + ${'1..3'} | ${true} + ${'17.04.0'} | ${false} + ${'1.2.3'} | ${true} + ${'v1.2.3'} | ${true} + ${'1.2.3-foo'} | ${true} + ${'1.2.3foo'} | ${false} + ${'1.2.3+'} | ${true} + ${'1.2.3+<2'} | ${true} + ${'1.2.3..1.2.4'} | ${true} + ${'<=1.2.3'} | ${true} + ${'<=2.0.0,>1.0.0'} | ${true} + ${'==1.2.3'} | ${true} + `('isValid("$input") === $expected', ({ input, expected }) => { + const res = !!versioning.isValid(input); + expect(res).toBe(expected); + }); + + test.each` + input | expected + ${'1.2.3'} | ${true} + `('isVersion("$input") === $expected', ({ input, expected }) => { + const res = !!versioning.isVersion(input); + expect(res).toBe(expected); + }); + + test.each` + input | expected + ${'1.2.3'} | ${true} + ${'1.2.3-alpha.1'} | ${true} + ${'==1.2.3'} | ${true} + ${'1.*'} | ${false} + `('isSingleVersion("$input") === $expected', ({ input, expected }) => { + const res = !!versioning.isSingleVersion(input); + expect(res).toBe(expected); + }); + + test.each` + versions | range | expected + ${['1.2.3', '1.2.4', '1.2.5']} | ${'1.2.3..1.2.4'} | ${'1.2.3'} + ${['0.4.0', '0.5.0', '4.2.0', '5.0.0']} | ${'4'} | ${'4.2.0'} + ${['0.4.0', '0.5.0', '4.2.0', '5.0.0']} | ${'4..5'} | ${'4.2.0'} + ${['0.4.0', '0.5.0', '4.2.0', '5.0.0']} | ${'4..5.0'} | ${'4.2.0'} + ${['0.4.0', '0.5.0', '4.2.0', '5.0.0']} | ${'4.2..5.0'} | ${'4.2.0'} + ${['0.4.0', '0.5.0', '4.2.0', '5.0.0']} | ${'4.2.0..5.0'} | ${'4.2.0'} + ${['0.4.0', '0.5.0', '4.2.0', '5.0.0']} | ${'4.2.0..5.0.0'} | ${'4.2.0'} + `( + 'minSatisfyingVersion($versions, "$range") === $expected', + ({ versions, range, expected }) => { + expect(versioning.minSatisfyingVersion(versions, range)).toBe(expected); + } + ); + + test.each` + versions | range | expected + ${['1.2.3', '1.2.4', '1.2.5']} | ${'1.2.3..1.2.4'} | ${'1.2.3'} + `( + 'getSatisfyingVersion($versions, "$range") === $expected', + ({ versions, range, expected }) => { + expect(versioning.getSatisfyingVersion(versions, range)).toBe(expected); + } + ); + + test.each` + version | range | expected + ${'1.2.3'} | ${'1.2.3..1.2.4'} | ${false} + ${'1.2.3'} | ${'1.2.4..1.2.5'} | ${true} + ${'0.9.0'} | ${'1.0.0..2.0.0'} | ${true} + ${'1.9.0'} | ${'1.0.0..2.0.0'} | ${false} + `( + 'isLessThanRange($version, "$range") === $expected', + ({ version, range, expected }) => { + expect(versioning.isLessThanRange(version, range)).toBe(expected); + } + ); + + test.each` + version | range | expected + ${'1.2.3'} | ${'1.2.3..1.2.4'} | ${true} + ${'1.2.4'} | ${'1.2.2..1.2.3'} | ${false} + ${'4.2.0'} | ${'4.2.0..5.0.0'} | ${true} + ${'4.2'} | ${'4.2.0..5.0.0'} | ${true} + ${'4.2'} | ${'4.2..5'} | ${true} + ${'4.2.0'} | ${'4.2..5'} | ${true} + ${'4.2.0'} | ${'4.2..5.0'} | ${true} + ${'4.2.0'} | ${'4.2..5.0.0'} | ${true} + ${'4.2.0'} | ${'2.0..3.0'} | ${false} + ${'4.2.2'} | ${'4.2.0..4.2.4'} | ${true} + ${'1.4'} | ${'1.4'} | ${true} + `( + 'matches($version, "$range") === $expected', + ({ version, range, expected }) => { + expect(versioning.matches(version, range)).toBe(expected); + } + ); + + test.each` + a | b + ${'1.1.1'} | ${'1.2.3'} + ${'1.2.3'} | ${'1.3.4'} + ${'2.0.1'} | ${'1.2.3'} + ${'1.2.3'} | ${'0.9.5'} + `( + 'rez.sortVersions("$a", "$b") === semver.sortVersions("$a", "$b")', + ({ a, b }) => { + const dockerSorted = versioning.sortVersions(a, b); + const semverSorted = semver.sortVersions(a, b); + expect(dockerSorted).toBe(semverSorted); + } + ); + + test.each` + currentValue | rangeStrategy | currentVersion | newVersion | expected + ${'==1.2.3'} | ${'replace'} | ${'1.2.3'} | ${'1.2.4'} | ${'==1.2.4'} + ${'1.2.3'} | ${'auto'} | ${'1.2.3'} | ${'1.2.4'} | ${'1.2.4'} + ${'1.2.3'} | ${'bump'} | ${'1.2.3'} | ${'1.2.4'} | ${'1.2.4'} + ${'1.2.3'} | ${'replace'} | ${'1.2.3'} | ${'1.2.4'} | ${'1.2.4'} + ${'1.2.3'} | ${'widen'} | ${'1.2.3'} | ${'1.2.4'} | ${'1.2.4'} + ${'7..8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7..9'} + ${'7.2..8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2..9'} + ${'7.2.3..8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3..9'} + ${'7..8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7..8.3'} + ${'7.2..8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2..8.3'} + ${'7.2.3..8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3..8.3'} + ${'7..8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7..8.3.0'} + ${'7.2..8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2..8.3.0'} + ${'7.2.3..8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3..8.3.0'} + ${'5..6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6'} + ${'5.2..6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6'} + ${'5.2.3..6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6'} + ${'5..6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5..6.3'} + ${'5.2..6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5..6.3'} + ${'5.2.3..6.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6.0'} + ${'5..6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6.0.0'} + ${'5.2..6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6.0.0'} + ${'5.2.3..6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5..6.0.0'} + ${'1..2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1..3'} + ${'1.2..2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2..3'} + ${'1.2..2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2..2.3'} + ${'1.2.3..2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2.3..2.3'} + ${'1.2.3..2.0.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2.3..2.3.0'} + ${'7+'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7+'} + ${'7.2+'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2+'} + ${'7.2.3+'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3+'} + ${'5+'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5+'} + ${'5.2+'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5+'} + ${'5.2.3+'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5+'} + ${'1+'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1+'} + ${'1.2+'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2+'} + ${'1.2.3+'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2.3+'} + ${'>=7'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7'} + ${'>=7.2'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2'} + ${'>=7.2.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3'} + ${'>=5'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5'} + ${'>=5.2'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5'} + ${'>=5.2.3'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5'} + ${'>=1'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1'} + ${'>=1.2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2'} + ${'>=1.2.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2.3'} + ${'>7'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7'} + ${'>7.2'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2'} + ${'>7.2.2'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.2'} + ${'>5'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5'} + ${'>5.2'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5.2'} + ${'>5.2.3'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5.2.3'} + ${'>1'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1'} + ${'>1.2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.2'} + ${'>1.2.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.2.3'} + ${'<=8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<=8.2.5'} + ${'<=7.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<=8.2.5'} + ${'<=7.2.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<=8.2.5'} + ${'<=6'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<=6.2.5'} + ${'<=5.3'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<=6.2.5'} + ${'<=5.2.3'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<=6.2.5'} + ${'<=2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<=2.2.5'} + ${'<=1.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<=2.2.5'} + ${'<=1.2.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<=2.2.5'} + ${'<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9'} + ${'<7.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9.0'} + ${'<7.2.4'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9.0.0'} + ${'<6'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<7'} + ${'<5.3'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<7.0'} + ${'<5.2.4'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<7.0.0'} + ${'<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3'} + ${'<1.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3.0'} + ${'<1.2.4'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3.0.0'} + ${'7+<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7+<9'} + ${'7.2+<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2+<9'} + ${'7.2.3+<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3+<9'} + ${'7+<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7+<8.3'} + ${'7.2+<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2+<8.3'} + ${'7.2.3+<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3+<8.3'} + ${'7+<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7+<8.3.0'} + ${'7.2+<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2+<8.3.0'} + ${'7.2.3+<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'7.2.3+<8.3.0'} + ${'5+<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6'} + ${'5.2+<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6'} + ${'5.2.3+<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6'} + ${'5+<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5+<6.3'} + ${'5.2+<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'6.2.5+<6.3'} + ${'5.2.3+<6.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6.0'} + ${'5+<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6.0.0'} + ${'5.2+<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6.0.0'} + ${'5.2.3+<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'5.2.5+<6.0.0'} + ${'1+<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1+<3'} + ${'1.2+<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2+<3'} + ${'1.2+<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2+<2.3'} + ${'1.2.3+<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2.3+<2.3'} + ${'1.2.3+<2.0.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'1.2.3+<2.3.0'} + ${'>=7,<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7,<9'} + ${'>=7.2,<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2,<9'} + ${'>=7.2.3,<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3,<9'} + ${'>=7,<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7,<8.3'} + ${'>=7.2,<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2,<8.3'} + ${'>=7.2.3,<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3,<8.3'} + ${'>=7,<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7,<8.3.0'} + ${'>=7.2,<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2,<8.3.0'} + ${'>=7.2.3,<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3,<8.3.0'} + ${'>=5,<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6'} + ${'>=5.2,<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6'} + ${'>=5.2.3,<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6'} + ${'>=5,<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5,<6.3'} + ${'>=5.2,<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5,<6.3'} + ${'>=5.2.3,<6.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6.0'} + ${'>=5,<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6.0.0'} + ${'>=5.2,<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6.0.0'} + ${'>=5.2.3,<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5,<6.0.0'} + ${'>=1,<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1,<3'} + ${'>=1.2,<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2,<3'} + ${'>=1.2,<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2,<2.3'} + ${'>=1.2.3,<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2.3,<2.3'} + ${'>=1.2.3,<2.0.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2.3,<2.3.0'} + ${'>=7<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7<9'} + ${'>=7.2<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2<9'} + ${'>=7.2.3<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3<9'} + ${'>=7<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7<8.3'} + ${'>=7.2<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2<8.3'} + ${'>=7.2.3<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3<8.3'} + ${'>=7<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7<8.3.0'} + ${'>=7.2<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2<8.3.0'} + ${'>=7.2.3<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>=7.2.3<8.3.0'} + ${'>=5<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6'} + ${'>=5.2<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6'} + ${'>=5.2.3<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6'} + ${'>=5<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5<6.3'} + ${'>=5.2<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>=6.2.5<6.3'} + ${'>=5.2.3<6.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6.0'} + ${'>=5<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6.0.0'} + ${'>=5.2<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6.0.0'} + ${'>=5.2.3<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>=5.2.5<6.0.0'} + ${'>=1<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1<3'} + ${'>=1.2<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2<3'} + ${'>=1.2<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2<2.3'} + ${'>=1.2.3<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2.3<2.3'} + ${'>=1.2.3<2.0.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>=1.2.3<2.3.0'} + ${'>6,<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>6,<9'} + ${'>7.1,<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.1,<9'} + ${'>7.2.0,<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.0,<9'} + ${'>6,<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>6,<8.3'} + ${'>7.1,<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.1,<8.3'} + ${'>7.2.0,<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.0,<8.3'} + ${'>6,<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>6,<8.3.0'} + ${'>7.1,<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.1,<8.3.0'} + ${'>7.2.0,<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.0,<8.3.0'} + ${'>4,<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>4,<6'} + ${'>5.1,<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.1,<6'} + ${'>5.2.0,<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.2.0,<6'} + ${'>5,<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5,<6.3'} + ${'>5.1,<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5.1,<6.3'} + ${'>5.2.0,<6.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.2.0,<6.0'} + ${'>5,<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5,<6.0.0'} + ${'>5.1,<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.1,<6.0.0'} + ${'>5.2.0,<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.2.0,<6.0.0'} + ${'>1,<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1,<3'} + ${'>1.1,<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.1,<3'} + ${'>1.1,<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.1,<2.3'} + ${'>1.2.0,<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.2.0,<2.3'} + ${'>1.2.0,<2.0.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.2.0,<2.3.0'} + ${'>6<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>6<9'} + ${'>7.1<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.1<9'} + ${'>7.2.0<8'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.0<9'} + ${'>6<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>6<8.3'} + ${'>7.1<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.1<8.3'} + ${'>7.2.0<8.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.0<8.3'} + ${'>6<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>6<8.3.0'} + ${'>7.1<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.1<8.3.0'} + ${'>7.2.0<8.0.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'>7.2.0<8.3.0'} + ${'>4<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>4<6'} + ${'>5.1<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.1<6'} + ${'>5.2.0<6'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.2.0<6'} + ${'>5<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5<6.3'} + ${'>5.1<6.0'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'>5.1<6.3'} + ${'>5.2.0<6.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.2.0<6.0'} + ${'>4<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>4<6.0.0'} + ${'>5.1<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.1<6.0.0'} + ${'>5.2.0<6.0.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'>5.2.0<6.0.0'} + ${'>1<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1<3'} + ${'>1.1<2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.1<3'} + ${'>1.1<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.1<2.3'} + ${'>1.2.0<2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.2.0<2.3'} + ${'>1.2.0<2.0.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'>1.2.0<2.3.0'} + ${'<8,>=7'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9,>=7'} + ${'<8,>=7.2'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9,>=7.2'} + ${'<8,>=7.2.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9,>=7.2.3'} + ${'<8.0,>=7'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3,>=7'} + ${'<8.0,>=7.2'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3,>=7.2'} + ${'<8.0,>=7.2.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3,>=7.2.3'} + ${'<8.0.0,>=7'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3.0,>=7'} + ${'<8.0.0,>=7.2'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3.0,>=7.2'} + ${'<8.0.0,>=7.2.3'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3.0,>=7.2.3'} + ${'<6,>=5'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6,>=5.2.5'} + ${'<6,>=5.2'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6,>=5.2.5'} + ${'<6,>=5.2.3'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6,>=5.2.5'} + ${'<6.0,>=5'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<6.3,>=6.2.5'} + ${'<6.0,>=5.2'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<6.3,>=6.2.5'} + ${'<6.0,>=5.2.3'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0,>=5.2.5'} + ${'<6.0.0,>=5'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0.0,>=5.2.5'} + ${'<6.0.0,>=5.2'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0.0,>=5.2.5'} + ${'<6.0.0,>=5.2.3'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0.0,>=5.2.5'} + ${'<2,>=1'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3,>=1'} + ${'<2,>=1.2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3,>=1.2'} + ${'<2.0,>=1.2'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<2.3,>=1.2'} + ${'<2.0,>=1.2.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<2.3,>=1.2.3'} + ${'<2.0.0,>=1.2.3'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<2.3.0,>=1.2.3'} + ${'<8,>6'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9,>6'} + ${'<8,>7.1'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9,>7.1'} + ${'<8,>7.2.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<9,>7.2.0'} + ${'<8.0,>6'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3,>6'} + ${'<8.0,>7.1'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3,>7.1'} + ${'<8.0,>7.2.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3,>7.2.0'} + ${'<8.0.0,>6'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3.0,>6'} + ${'<8.0.0,>7.1'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3.0,>7.1'} + ${'<8.0.0,>7.2.0'} | ${'replace'} | ${'7.2.3'} | ${'8.2.5'} | ${'<8.3.0,>7.2.0'} + ${'<6,>4'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6,>4'} + ${'<6,>5.1'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6,>5.1'} + ${'<6,>5.2.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6,>5.2.0'} + ${'<6.0,>5'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<6.3,>5'} + ${'<6.0,>5.1'} | ${'bump'} | ${'5.2.3'} | ${'6.2.5'} | ${'<6.3,>5.1'} + ${'<6.0,>5.2.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0,>5.2.0'} + ${'<6.0.0,>5'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0.0,>5'} + ${'<6.0.0,>5.1'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0.0,>5.1'} + ${'<6.0.0,>5.2.0'} | ${'bump'} | ${'5.2.3'} | ${'5.2.5'} | ${'<6.0.0,>5.2.0'} + ${'<2,>1'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3,>1'} + ${'<2,>1.1'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<3,>1.1'} + ${'<2.0,>1.1'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<2.3,>1.1'} + ${'<2.0,>1.2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<2.3,>1.2.0'} + ${'<2.0.0,>1.2.0'} | ${'widen'} | ${'1.2.3'} | ${'2.2.5'} | ${'<2.3.0,>1.2.0'} + ${'<=1.2.5, >1.2.0'} | ${'widen'} | ${'1.2.3'} | ${'1.2.4'} | ${null} + `( + 'getNewValue($currentValue, $rangeStrategy, $currentVersion, $newVersion, $expected) === $expected', + ({ currentValue, rangeStrategy, currentVersion, newVersion, expected }) => { + const res = versioning.getNewValue({ + currentValue, + rangeStrategy, + currentVersion, + newVersion, + }); + expect(res).toBe(expected); + } + ); +}); diff --git a/lib/versioning/rez/index.ts b/lib/versioning/rez/index.ts index 8114b4545321fb..6b848afcfbe645 100644 --- a/lib/versioning/rez/index.ts +++ b/lib/versioning/rez/index.ts @@ -1,59 +1,218 @@ -// istanbul ignore file: requires (#10930) - -// original rez regex written in python (#11634) -// version_range_regex = ( -// # Match a version number (e.g. 1.0.0) -// r" ^(?P{version_group})$" -// "|" -// # Or match an exact version number (e.g. ==1.0.0) -// " ^(?P" -// " ==" # Required == operator -// " (?P{version_group})?" -// " )$" -// "|" -// # Or match an inclusive bound (e.g. 1.0.0..2.0.0) -// " ^(?P" -// " (?P{version_group})?" -// " \.\." # Required .. operator -// " (?P{version_group})?" -// " )$" -// "|" -// # Or match a lower bound (e.g. 1.0.0+) -// " ^(?P" -// " (?P>|>=)?" # Bound is exclusive? -// " (?P{version_group})?" -// " (?(lower_bound_prefix)|\+)" # + only if bound is not exclusive -// " )$" -// "|" -// # Or match an upper bound (e.g. <=1.0.0) -// " ^(?P" -// " (?P<(?={version_group})|<=)?" # Bound is exclusive? -// " (?P{version_group})?" -// " )$" -// "|" -// # Or match a range in ascending order (e.g. 1.0.0+<2.0.0) -// " ^(?P" -// " (?P" -// " (?P>|>=)?" # Lower bound is exclusive? -// " (?P{version_group})?" -// " (?(range_lower_asc_prefix)|\+)?" # + only if lower bound is not exclusive -// " )(?P" -// " (?(range_lower_asc_version),?|)" # , only if lower bound is found -// " (?P<(?={version_group})|<=)" # <= only if followed by a version group -// " (?P{version_group})?" -// " )" -// " )$" -// "|" -// # Or match a range in descending order (e.g. <=2.0.0,1.0.0+) -// " ^(?P" -// " (?P" -// " (?P<|<=)?" # Upper bound is exclusive? -// " (?P{version_group})?" -// " (?(range_upper_desc_prefix)|\+)?" # + only if upper bound is not exclusive -// " )(?P" -// " (?(range_upper_desc_version),|)" # Comma is not optional because we don't want to recognize something like "<4>3" -// " (?P<(?={version_group})|>=?)" # >= or > only if followed by a version group -// " (?P{version_group})?" -// " )" -// " )$" -// ).format(version_group=version_group) +import { api as npm } from '../npm'; +import { api as pep440 } from '../pep440'; +import type { NewValueConfig, VersioningApi } from '../types'; +import { + ascendingRange, + descendingRange, + exactVersion, + inclusiveBound, + lowerBound, + upperBound, + versionGroup, +} from './pattern'; +import { + npm2rezplus, + padZeroes, + pep4402rezInclusiveBound, + rez2npm, + rez2pep440, +} from './transform'; + +export const id = 'rez'; +export const displayName = 'rez'; +export const urls = ['https://github.com/nerdvegas/rez']; +export const supportsRanges = true; +export const supportedRangeStrategies = ['bump', 'extend', 'pin', 'replace']; + +function equals(a: string, b: string): boolean { + try { + return npm.equals(padZeroes(a), padZeroes(b)); + } catch (err) /* istanbul ignore next */ { + return pep440.equals(a, b); + } +} + +function getMajor(version: string): number { + try { + return npm.getMajor(padZeroes(version)); + } catch (err) /* istanbul ignore next */ { + return pep440.getMajor(version); + } +} + +function getMinor(version: string): number { + try { + return npm.getMinor(padZeroes(version)); + } catch (err) /* istanbul ignore next */ { + return pep440.getMinor(version); + } +} + +function getPatch(version: string): number { + try { + return npm.getPatch(padZeroes(version)); + } catch (err) /* istanbul ignore next */ { + return pep440.getPatch(version); + } +} + +function isGreaterThan(a: string, b: string): boolean { + try { + return npm.isGreaterThan(padZeroes(a), padZeroes(b)); + } catch (err) /* istanbul ignore next */ { + return pep440.isGreaterThan(a, b); + } +} + +function isLessThanRange(version: string, range: string): boolean { + return ( + npm.isVersion(padZeroes(version)) && + npm.isLessThanRange(padZeroes(version), rez2npm(range)) + ); +} + +export function isValid(input: string): string | boolean { + return npm.isValid(rez2npm(input)); +} + +function isStable(version: string): boolean { + return npm.isStable(padZeroes(version)); +} + +function isVersion(input: string): string | boolean { + return npm.isVersion(padZeroes(rez2npm(input))); +} + +function matches(version: string, range: string): boolean { + return ( + npm.isVersion(padZeroes(version)) && + npm.matches(padZeroes(version), rez2npm(range)) + ); +} + +function getSatisfyingVersion(versions: string[], range: string): string { + return npm.getSatisfyingVersion(versions, rez2npm(range)); +} + +function minSatisfyingVersion(versions: string[], range: string): string { + return npm.minSatisfyingVersion(versions, rez2npm(range)); +} + +function isSingleVersion(constraint: string): string | boolean { + return ( + (constraint.trim().startsWith('==') && + isVersion(constraint.trim().substring(2).trim())) || + isVersion(constraint.trim()) + ); +} + +function sortVersions(a: string, b: string): number { + return npm.sortVersions(padZeroes(a), padZeroes(b)); +} + +function getNewValue({ + currentValue, + rangeStrategy, + currentVersion, + newVersion, +}: NewValueConfig): string { + const pep440Value = pep440.getNewValue({ + currentValue: rez2pep440(currentValue), + rangeStrategy, + currentVersion, + newVersion, + }); + if (exactVersion.test(currentValue)) { + return pep440Value; + } + if (inclusiveBound.test(currentValue)) { + return pep4402rezInclusiveBound(pep440Value); + } + if (lowerBound.test(currentValue)) { + if (currentValue.includes('+')) { + return npm2rezplus(pep440Value); + } + return pep440Value; + } + if (upperBound.test(currentValue)) { + return pep440Value; + } + if (ascendingRange.test(currentValue)) { + // Replace version numbers but keep rez format, otherwise we just end up trying + // to convert every single case separately. + const match = ascendingRange.exec(currentValue); + const lowerBoundAscCurrent = match.groups.range_lower_asc; + const upperBoundAscCurrent = match.groups.range_upper_asc; + const lowerAscVersionCurrent = match.groups.range_lower_asc_version; + const upperAscVersionCurrent = match.groups.range_upper_asc_version; + const [lowerBoundAscPep440, upperBoundAscPep440] = pep440Value.split(', '); + const lowerAscVersionNew = new RegExp(versionGroup).exec( + lowerBoundAscPep440 + )[0]; + const upperAscVersionNew = new RegExp(versionGroup).exec( + upperBoundAscPep440 + )[0]; + const lowerBoundAscNew = lowerBoundAscCurrent.replace( + lowerAscVersionCurrent, + lowerAscVersionNew + ); + const upperBoundAscNew = upperBoundAscCurrent.replace( + upperAscVersionCurrent, + upperAscVersionNew + ); + const separator = currentValue.includes(',') ? ',' : ''; + + return lowerBoundAscNew + separator + upperBoundAscNew; + } + if (descendingRange.test(currentValue)) { + // Replace version numbers but keep rez format, otherwise we just end up trying + // to convert every single case separately. + const match = descendingRange.exec(currentValue); + const upperBoundDescCurrent = match.groups.range_upper_desc; + const lowerBoundDescCurrent = match.groups.range_lower_desc; + const upperDescVersionCurrent = match.groups.range_upper_desc_version; + const lowerDescVersionCurrent = match.groups.range_lower_desc_version; + const [lowerBoundDescPep440, upperBoundDescPep440] = + pep440Value.split(', '); + + const upperDescVersionNew = new RegExp(versionGroup).exec( + upperBoundDescPep440 + )[0]; + const lowerDescVersionNew = new RegExp(versionGroup).exec( + lowerBoundDescPep440 + )[0]; + const upperBoundDescNew = upperBoundDescCurrent.replace( + upperDescVersionCurrent, + upperDescVersionNew + ); + const lowerBoundDescNew = lowerBoundDescCurrent.replace( + lowerDescVersionCurrent, + lowerDescVersionNew + ); + // Descending ranges are only supported with a comma. + const separator = ','; + + return upperBoundDescNew + separator + lowerBoundDescNew; + } + return null; +} + +export const api: VersioningApi = { + equals, + getMajor, + getMinor, + getPatch, + getNewValue, + getSatisfyingVersion, + isCompatible: isVersion, + isGreaterThan, + isLessThanRange, + isSingleVersion, + isStable, + isValid, + isVersion, + matches, + minSatisfyingVersion, + sortVersions, +}; +export default api; diff --git a/lib/versioning/rez/pattern.ts b/lib/versioning/rez/pattern.ts new file mode 100644 index 00000000000000..9132efa141fdee --- /dev/null +++ b/lib/versioning/rez/pattern.ts @@ -0,0 +1,89 @@ +// Regular Expressions have been copied from, some more work were necessary to make it work: +// original rez regex written in python (#11634) +// version_range_regex = ( +// # Match a version number (e.g. 1.0.0) +// r" ^(?P{version_group})$" +// "|" +// # Or match an exact version number (e.g. ==1.0.0) +// " ^(?P" +// " ==" # Required == operator +// " (?P{version_group})?" +// " )$" +// "|" +// # Or match an inclusive bound (e.g. 1.0.0..2.0.0) +// " ^(?P" +// " (?P{version_group})?" +// " \.\." # Required .. operator +// " (?P{version_group})?" +// " )$" +// "|" +// # Or match a lower bound (e.g. 1.0.0+) +// " ^(?P" +// " (?P>|>=)?" # Bound is exclusive? +// " (?P{version_group})?" +// " (?(lower_bound_prefix)|\+)" # + only if bound is not exclusive +// " )$" +// "|" +// # Or match an upper bound (e.g. <=1.0.0) +// " ^(?P" +// " (?P<(?={version_group})|<=)?" # Bound is exclusive? +// " (?P{version_group})?" +// " )$" +// "|" +// # Or match a range in ascending order (e.g. 1.0.0+<2.0.0) +// " ^(?P" +// " (?P" +// " (?P>|>=)?" # Lower bound is exclusive? +// " (?P{version_group})?" +// " (?(range_lower_asc_prefix)|\+)?" # + only if lower bound is not exclusive +// " )(?P" +// " (?(range_lower_asc_version),?|)" # , only if lower bound is found +// " (?P<(?={version_group})|<=)" # <= only if followed by a version group +// " (?P{version_group})?" +// " )" +// " )$" +// "|" +// # Or match a range in descending order (e.g. <=2.0.0,1.0.0+) +// " ^(?P" +// " (?P" +// " (?P<|<=)?" # Upper bound is exclusive? +// " (?P{version_group})?" +// " (?(range_upper_desc_prefix)|\+)?" # + only if upper bound is not exclusive +// " )(?P" +// " (?(range_upper_desc_version),|)" # Comma is not optional because we don't want to recognize something like "<4>3" +// " (?P<(?={version_group})|>=?)" # >= or > only if followed by a version group +// " (?P{version_group})?" +// " )" +// " )$" +// ).format(version_group=version_group) +// - Replace {version_group} -> ${versionGroup} +// - Replace (?P<...>) -> (?<...>) +// - Replace ?(...) -> \k<...> +// - Replace single \ -> double \ +export const versionGroup = '([0-9a-zA-Z_]+(?:[.-][0-9a-zA-Z_]+)*)'; +export const matchVersion = new RegExp( + `^(?${versionGroup})$` +); /* Match a version number (e.g. 1.0.0) */ +export const exactVersion = new RegExp( + `^(?==(?${versionGroup})?)$` +); /* Match an exact version number (e.g. ==1.0.0) */ +// inclusiveBound is called inclusive but behaviour in rez is this: +// package-1..3 will match versions 1.2.3, 2.3.4, but not 3.0.0 or above +export const inclusiveBound = new RegExp( + `^(?(?${versionGroup})?\\.\\.(?${versionGroup})?)$` +); /* Match an inclusive bound (e.g. 1.0.0..2.0.0) */ +// Add ? after |\\+) in order to match >=1.15 +export const lowerBound = new RegExp( + `^(?(?>|>=)?(?${versionGroup})?(\\k|\\+)?)$` +); /* Match a lower bound (e.g. 1.0.0+) */ +export const upperBound = new RegExp( + `^(?(?<(?=${versionGroup})|<=)?(?${versionGroup})?)$` +); /* Match an upper bound (e.g. <=1.0.0) */ +// Add ,? to match >=7,<9 (otherwise it just matches >=7<9) +export const ascendingRange = new RegExp( + `^(?(?(?>|>=)?(?${versionGroup})?(\\k|\\+)?),?(?(\\k,?|)(?<(?=${versionGroup})|<=)(?${versionGroup})?))$` +); /* Match a range in ascending order (e.g. 1.0.0+<2.0.0) */ +// Add , to match <9,>=7 (otherwise it just matches <9>=7) +export const descendingRange = new RegExp( + `^(?(?(?<|<=)?(?${versionGroup})?(\\k|\\+)?),(?(\\k,|)(?<(?=${versionGroup})|>=?)(?${versionGroup})?))$` +); /* Match a range in descending order (e.g. <=2.0.0,1.0.0+) */ diff --git a/lib/versioning/rez/readme.md b/lib/versioning/rez/readme.md new file mode 100644 index 00000000000000..3041ef1a9e80d8 --- /dev/null +++ b/lib/versioning/rez/readme.md @@ -0,0 +1,18 @@ +rez versioning was developed to support the [rez Package Manager](https://github.com/nerdvegas/rez). +It's based on Semantic Versioning but includes its own concept of ranges. + +**Use of dots** + +A range is expressed with dots `1.2..2` means `>=1.2.x <2.0.0`. + +**No exact versions unless using two equals ==** + +In rez, `1.2.3` doesn't mean "exactly 1.2.3", it actually means `>= 1.2.3 <1.2.4`. +If you want to use an exact version use two equal characters, like this: `==1.2.3`. + +**Use of pipes** + +rez uses pipes as an OR operator, `2.7..3|4` means `>=2.7 <3 OR 4.x.x`. + +This has not been implemented yet. +The current iteration of rez versioning does not support pipes yet. diff --git a/lib/versioning/rez/transform.ts b/lib/versioning/rez/transform.ts new file mode 100644 index 00000000000000..b5685560821795 --- /dev/null +++ b/lib/versioning/rez/transform.ts @@ -0,0 +1,113 @@ +import { + ascendingRange, + descendingRange, + exactVersion, + inclusiveBound, + lowerBound, + matchVersion, + upperBound, +} from './pattern'; + +function getVersionParts(input: string): [string, string] { + const versionParts = input.split('-'); + if (versionParts.length === 1) { + return [input, '']; + } + + return [versionParts[0], '-' + versionParts[1]]; +} + +export function padZeroes(input: string): string { + if (/[~^*]/.test(input)) { + // ignore ranges + return input; + } + + const [output, stability] = getVersionParts(input); + + const sections = output.split('.'); + while (sections.length < 3) { + sections.push('0'); + } + return sections.join('.') + stability; +} + +function plus2npm(input: string): string { + if (input.includes('+')) { + return '>=' + input.replace('+', ' '); + } + return input; +} + +export function rez2npm(input: string): string { + if (matchVersion.test(input)) { + return input; + } + if (exactVersion.test(input)) { + return input.replace('==', '='); + } + if (inclusiveBound.test(input)) { + return '>=' + input.replace(/\.\./g, ' <'); + } + if (lowerBound.test(input)) { + return plus2npm(input); + } + if (upperBound.test(input)) { + return input; + } + if (ascendingRange.test(input)) { + const match = ascendingRange.exec(input); + const lowerBoundAsc = match.groups.range_lower_asc; + const upperBoundAsc = match.groups.range_upper_asc; + return plus2npm(lowerBoundAsc) + ' ' + plus2npm(upperBoundAsc); + } + if (descendingRange.test(input)) { + const match = descendingRange.exec(input); + const upperBoundDesc = match.groups.range_upper_desc; + const lowerBoundDesc = match.groups.range_lower_desc; + return plus2npm(lowerBoundDesc) + ' ' + plus2npm(upperBoundDesc); + } + return input; +} + +export function rez2pep440(input: string): string { + if (matchVersion.test(input)) { + return input; + } + if (exactVersion.test(input)) { + return input; + } + if (inclusiveBound.test(input)) { + return '>=' + input.replace(/\.\./g, ', <'); + } + if (lowerBound.test(input)) { + return plus2npm(input); + } + if (upperBound.test(input)) { + return input; + } + if (ascendingRange.test(input)) { + const match = ascendingRange.exec(input); + const lowerBoundAsc = match.groups.range_lower_asc; + const upperBoundAsc = match.groups.range_upper_asc; + return plus2npm(lowerBoundAsc) + ', ' + plus2npm(upperBoundAsc); + } + if (descendingRange.test(input)) { + const match = descendingRange.exec(input); + const upperBoundDesc = match.groups.range_upper_desc; + const lowerBoundDesc = match.groups.range_lower_desc; + return plus2npm(lowerBoundDesc) + ', ' + plus2npm(upperBoundDesc); + } + return input; +} + +export function pep4402rezInclusiveBound(input: string): string { + return input + .split(',') + .map((v) => v.trim().replace(/[<>=]/g, '')) + .join('..'); +} + +export function npm2rezplus(input: string): string { + return input.trim().replace('>=', '') + '+'; +} diff --git a/lib/versioning/versioning-metadata.spec.ts b/lib/versioning/versioning-metadata.spec.ts index 7275d4d394b51f..371d9abadf7467 100644 --- a/lib/versioning/versioning-metadata.spec.ts +++ b/lib/versioning/versioning-metadata.spec.ts @@ -26,8 +26,7 @@ describe('versioning/versioning-metadata', () => { (item) => !item.includes('.') && !item.startsWith('_') ); - // TODO: revert rez in #10930 - for (const versioning of allVersioning.filter((v) => v !== 'rez')) { + for (const versioning of allVersioning) { const versioningObj = require(`./${versioning}`); expect(versioningObj.id).toEqual(versioning); expect(versioningObj.displayName).toBeDefined();