From 7a483666e64a046be9984bf4146ac8566b3f5920 Mon Sep 17 00:00:00 2001 From: Jamie Mason Date: Sun, 23 Aug 2020 13:04:09 +0100 Subject: [PATCH] fix(core): ignore link: versions rather than throw Closes #38 --- src/commands/fix-mismatches.ts | 14 ++++---- src/commands/lib/get-highest-version.spec.ts | 30 ++++++++++++++++ src/commands/lib/get-highest-version.ts | 36 +++++++++++--------- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/commands/fix-mismatches.ts b/src/commands/fix-mismatches.ts index f34a94e7..43cac5c0 100644 --- a/src/commands/fix-mismatches.ts +++ b/src/commands/fix-mismatches.ts @@ -18,12 +18,14 @@ export const fixMismatches = (dependencyTypes: DependencyType[], filter: RegExp, mismatches.forEach((installedPackage) => { const versions = installedPackage.installations.map((installation) => installation.version); const newest = getHighestVersion(versions); - installedPackage.installations.forEach(({ type, name, source }) => { - const dependencies = source.contents[type]; - if (dependencies) { - dependencies[name] = newest; - } - }); + if (newest !== null) { + installedPackage.installations.forEach(({ type, name, source }) => { + const dependencies = source.contents[type]; + if (dependencies) { + dependencies[name] = newest; + } + }); + } }); }; diff --git a/src/commands/lib/get-highest-version.spec.ts b/src/commands/lib/get-highest-version.spec.ts index 18cc0ebe..a42f4a0f 100644 --- a/src/commands/lib/get-highest-version.spec.ts +++ b/src/commands/lib/get-highest-version.spec.ts @@ -9,6 +9,34 @@ const shuffle = (array: string[]): string[] => { }; describe('getHighestVersion', () => { + it('ignores non-semver versions', () => { + const a: string[] = []; + const b = shuffle([...a, 'http://asdf.com/asdf.tar.gz']); + const c = shuffle([...b, 'file:../foo/bar']); + const d = shuffle([...c, 'latest']); + const e = shuffle([...d, 'git+https://isaacs@github.com/npm/cli.git']); + const f = shuffle([...e, 'expressjs/express']); + const g = shuffle([...f, 'mochajs/mocha#4727d357ea']); + const h = shuffle([...g, 'user/repo#feature/branch']); + const i = shuffle([...h, 'link:../foo/bar']); + const j = shuffle([...i, 'git+ssh://git@github.com:npm/cli.git#v1.0.27']); + const k = shuffle([...j, 'git+ssh://git@github.com:npm/cli#semver:^5.0']); + const l = shuffle([...k, 'git://github.com/npm/cli.git#v1.0.27']); + expect(getHighestVersion(a)).toBeNull(); + expect(getHighestVersion(b)).toBeNull(); + expect(getHighestVersion(c)).toBeNull(); + expect(getHighestVersion(d)).toBeNull(); + expect(getHighestVersion(e)).toBeNull(); + expect(getHighestVersion(f)).toBeNull(); + expect(getHighestVersion(g)).toBeNull(); + expect(getHighestVersion(h)).toBeNull(); + expect(getHighestVersion(i)).toBeNull(); + expect(getHighestVersion(i)).toBeNull(); + expect(getHighestVersion(j)).toBeNull(); + expect(getHighestVersion(k)).toBeNull(); + expect(getHighestVersion(l)).toBeNull(); + }); + it('returns the newest version from an array of versions', () => { const a = ['<1.0.0']; const b = shuffle([...a, '<=1.0.0']); @@ -29,6 +57,7 @@ describe('getHighestVersion', () => { const q = shuffle([...p, 'expressjs/express']); const r = shuffle([...q, 'mochajs/mocha#4727d357ea']); const s = shuffle([...r, 'user/repo#feature/branch']); + const t = shuffle([...s, 'link:../foo/bar']); // valid semver expect(getHighestVersion(a)).toEqual('<1.0.0'); expect(getHighestVersion(b)).toEqual('<=1.0.0'); @@ -50,5 +79,6 @@ describe('getHighestVersion', () => { expect(getHighestVersion(q)).toEqual('*'); expect(getHighestVersion(r)).toEqual('*'); expect(getHighestVersion(s)).toEqual('*'); + expect(getHighestVersion(t)).toEqual('*'); }); }); diff --git a/src/commands/lib/get-highest-version.ts b/src/commands/lib/get-highest-version.ts index d2ea7624..a333cd36 100644 --- a/src/commands/lib/get-highest-version.ts +++ b/src/commands/lib/get-highest-version.ts @@ -9,6 +9,7 @@ import { RANGE_MINOR, RANGE_PATCH, } from '../../constants'; +import { isSemver } from './is-semver'; const getRange = (version: string): string => version.slice(0, version.search(/[0-9]/)); @@ -27,23 +28,24 @@ const getRangeScore = (version: string | null): number => { return 0; }; -export const getHighestVersion = (versions: string[]): string => { - let rawHighest: string | null = null; - for (const raw of versions) { - if (raw === '*') return raw; +export const getHighestVersion = (versions: string[]): string | null => + versions.reduce((rawHighest, raw) => { const version = valid(coerce(raw)); - if (version === null) continue; const highest = valid(coerce(rawHighest)); - if ( - highest === null || - gt(version, highest) || - (eq(version, highest) && getRangeScore(raw) > getRangeScore(rawHighest)) - ) { - rawHighest = raw; + if (raw === '*' || rawHighest === '*') { + return '*'; } - } - if (rawHighest === null) { - throw new Error(`Failed to find highest version of ${versions.join(', ')}`); - } - return rawHighest; -}; + if (!isSemver(raw) || version === null) { + return rawHighest; + } + if (highest === null) { + return raw; + } + if (gt(version, highest)) { + return raw; + } + if (eq(version, highest) && getRangeScore(raw) > getRangeScore(rawHighest)) { + return raw; + } + return rawHighest; + }, null);