From 514ad7ea3aec2b17c75c39675d32427d793b5a32 Mon Sep 17 00:00:00 2001 From: regevbr Date: Tue, 14 Apr 2020 22:22:30 +0300 Subject: [PATCH] bug: yarn 2 lock file parsing issues #56 --- lib/parsers/yarn-utils.ts | 20 +++++++++++---- test/lib/yarn-utils.test.ts | 49 +++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/lib/parsers/yarn-utils.ts b/lib/parsers/yarn-utils.ts index 8efe93a9..d6b6e474 100644 --- a/lib/parsers/yarn-utils.ts +++ b/lib/parsers/yarn-utils.ts @@ -2,13 +2,19 @@ import {YarnLockDep, YarnLockDeps} from './yarn-lock-parse-base'; import {parseResolution} from '@yarnpkg/parsers'; import {InvalidUserInputError} from '../errors'; +const PATCH_PLACEHOLDER = '@patch:'; + export type ParseResolution = typeof parseResolution; const lockFileKeyNormalizer = (resolutionParser: ParseResolution) => (key: string) => { - const normalizedKey = key + let normalizedKey = key .replace(/(#|::).*$/, '') .trim(); - const fileProtocol = normalizedKey.match(/^(.+)@(file:.+)$/); + const patchIndex = normalizedKey.indexOf(PATCH_PLACEHOLDER); + if (patchIndex > -1) { + normalizedKey = normalizedKey.substr(patchIndex + PATCH_PLACEHOLDER.length); + } + const fileProtocol = normalizedKey.match(/^(.+)@((file|link|portal):.+)$/); if (fileProtocol) { return `${fileProtocol[1]}@${fileProtocol[2]}`; } @@ -20,9 +26,13 @@ const lockFileKeyNormalizer = (resolutionParser: ParseResolution) => (key: strin if (httpsProtocol) { return key; } - const resolution = resolutionParser(normalizedKey).descriptor; - const name = resolution.fullName; - const fullVersion = resolution.description; + const resolution = resolutionParser(normalizedKey); + const descriptor = resolution.descriptor; + const name = descriptor.fullName; + if (resolution.from) { + return key; + } + const fullVersion = descriptor.description; if (!fullVersion) { throw new InvalidUserInputError(`Unsupported lockfile resolution ${key}`); } diff --git a/test/lib/yarn-utils.test.ts b/test/lib/yarn-utils.test.ts index 61a92516..ddd0acfb 100644 --- a/test/lib/yarn-utils.test.ts +++ b/test/lib/yarn-utils.test.ts @@ -19,12 +19,22 @@ test('Should work for semver resolution with npm protocol and scope', async (t) t.deepEqual(key, [ '@types/istanbul-reports@^1.1.1'], 'Resolution is normalized'); }); -test('Should work for fixed version', async (t) => { +test('Should work for tag resolution with npm protocol', async (t) => { + const key = normalizer('body-parser@npm:latest'); + t.deepEqual(key, [ 'body-parser@latest'], 'Resolution is normalized'); +}); + +test('Should work for tag resolution with npm protocol and scope', async (t) => { + const key = normalizer('@types/istanbul-reports@npm:latest'); + t.deepEqual(key, [ '@types/istanbul-reports@latest'], 'Resolution is normalized'); +}); + +test('Should work for semver without protocol', async (t) => { const key = normalizer('npm-packlist@1.1.6'); t.deepEqual(key, [ 'npm-packlist@1.1.6'], 'Resolution is normalized'); }); -test('Should work for fixed version and scope', async (t) => { +test('Should work for semver with scope and without protocol', async (t) => { const key = normalizer('@types/istanbul-reports@1.1.1'); t.deepEqual(key, [ '@types/istanbul-reports@1.1.1'], 'Resolution is normalized'); }); @@ -39,7 +49,42 @@ test('Should work for git+ssh', async (t) => { t.deepEqual(key, [ 'body-parser@git+ssh://git@github.com/expressjs/body-parser.git#1.9.0"'], 'Resolution is normalized'); }); +test('Should work for patch protocol', async (t) => { + const key = normalizer('fsevents@patch:fsevents@^1.2.7#builtin'); + t.deepEqual(key, [ 'fsevents@^1.2.7'], 'Resolution is normalized'); +}); + +test('Should work for short github protocol with tag', async (t) => { + const key = normalizer('body-parser@expressjs/body-parser#1.9.0'); + t.deepEqual(key, [ 'body-parser@expressjs/body-parser#1.9.0'], 'Resolution is normalized'); +}); + +test('Should work for shor github protocol without tag', async (t) => { + const key = normalizer('body-parser@expressjs/body-parser'); + t.deepEqual(key, [ 'body-parser@expressjs/body-parser'], 'Resolution is normalized'); +}); + +test('Should work for short github protocol with tag', async (t) => { + const key = normalizer('body-parser@github:expressjs/body-parser#1.9.0'); + t.deepEqual(key, [ 'body-parser@github:expressjs/body-parser#1.9.0'], 'Resolution is normalized'); +}); + +test('Should work for shor github protocol without tag', async (t) => { + const key = normalizer('body-parser@github:expressjs/body-parser'); + t.deepEqual(key, [ 'body-parser@github:expressjs/body-parser'], 'Resolution is normalized'); +}); + test('Should work for file protocol', async (t) => { const key = normalizer('shared@file:./some-file::locator=pkg-dev-deps-only%40workspace%3A.'); t.deepEqual(key, [ 'shared@file:./some-file'], 'Resolution is normalized'); }); + +test('Should work for link protocol', async (t) => { + const key = normalizer('body-parser@link:../test2::locator=external-tarball%40workspace%3A.'); + t.deepEqual(key, [ 'body-parser@link:../test2'], 'Resolution is normalized'); +}); + +test('Should work for portal protocol', async (t) => { + const key = normalizer('body-parser@portal:../test2::locator=external-tarball%40workspace%3A.'); + t.deepEqual(key, [ 'body-parser@portal:../test2'], 'Resolution is normalized'); +});