From b184d1ea9c4f8b24a358920855a8fb1a980ebb7e Mon Sep 17 00:00:00 2001 From: ylemkimon <mail@ylem.kim> Date: Fri, 13 Nov 2020 18:11:08 +0900 Subject: [PATCH] refactor(npm): lockfile extraction code (#7703) --- .../extract/__snapshots__/npm.spec.ts.snap | 16 +++++++------ lib/manager/npm/extract/common.ts | 6 +++++ .../npm/extract/locked-versions.spec.ts | 10 ++++---- lib/manager/npm/extract/locked-versions.ts | 15 ++++-------- lib/manager/npm/extract/npm.spec.ts | 6 ++--- lib/manager/npm/extract/npm.ts | 14 +++++------ lib/manager/npm/extract/yarn.spec.ts | 6 ++--- lib/manager/npm/extract/yarn.ts | 23 ++++++++----------- 8 files changed, 47 insertions(+), 49 deletions(-) diff --git a/lib/manager/npm/extract/__snapshots__/npm.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/npm.spec.ts.snap index 3858128514..e8e7f21cc4 100644 --- a/lib/manager/npm/extract/__snapshots__/npm.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/npm.spec.ts.snap @@ -2,12 +2,14 @@ exports[`manager/npm/extract/npm .getNpmLock() extracts 1`] = ` Object { - "ansi-styles": "3.2.1", - "chalk": "2.4.1", - "color-convert": "1.9.1", - "color-name": "1.1.3", - "escape-string-regexp": "1.0.5", - "has-flag": "3.0.0", - "supports-color": "5.4.0", + "lockedVersions": Object { + "ansi-styles": "3.2.1", + "chalk": "2.4.1", + "color-convert": "1.9.1", + "color-name": "1.1.3", + "escape-string-regexp": "1.0.5", + "has-flag": "3.0.0", + "supports-color": "5.4.0", + }, } `; diff --git a/lib/manager/npm/extract/common.ts b/lib/manager/npm/extract/common.ts index ed2b7a959e..c463f997e5 100644 --- a/lib/manager/npm/extract/common.ts +++ b/lib/manager/npm/extract/common.ts @@ -13,3 +13,9 @@ export type LockFileEntry = Record< string, { version: string; integrity?: boolean } >; + +export interface LockFile { + lockedVersions: Record<string, string>; + lockfileVersion?: number; // cache version for Yarn + isYarn1?: boolean; +} diff --git a/lib/manager/npm/extract/locked-versions.spec.ts b/lib/manager/npm/extract/locked-versions.spec.ts index 90348d08b1..897dfd18aa 100644 --- a/lib/manager/npm/extract/locked-versions.spec.ts +++ b/lib/manager/npm/extract/locked-versions.spec.ts @@ -15,7 +15,7 @@ describe('manager/npm/extract/locked-versions', () => { async (yarnVersion) => { yarn.getYarnLock.mockReturnValue({ isYarn1: yarnVersion === '1.22.0', - cacheVersion: yarnVersion === '2.2.0' ? 6 : NaN, + lockfileVersion: yarnVersion === '2.2.0' ? 6 : undefined, lockedVersions: { 'a@1.0.0': '1.0.0', 'b@2.0.0': '2.0.0', @@ -46,9 +46,11 @@ describe('manager/npm/extract/locked-versions', () => { it('uses package-lock.json', async () => { npm.getNpmLock.mockReturnValue({ - a: '1.0.0', - b: '2.0.0', - c: '3.0.0', + lockedVersions: { + a: '1.0.0', + b: '2.0.0', + c: '3.0.0', + }, }); const packageFiles = [ { diff --git a/lib/manager/npm/extract/locked-versions.ts b/lib/manager/npm/extract/locked-versions.ts index a54dcb7de3..593968bc06 100644 --- a/lib/manager/npm/extract/locked-versions.ts +++ b/lib/manager/npm/extract/locked-versions.ts @@ -1,13 +1,14 @@ import { valid } from 'semver'; import { logger } from '../../../logger'; import { PackageFile } from '../../common'; +import { LockFile } from './common'; import { getNpmLock } from './npm'; import { getYarnLock } from './yarn'; export async function getLockedVersions( packageFiles: PackageFile[] ): Promise<void> { - const lockFileCache: Record<string, YarnLockCache> = {}; + const lockFileCache: Record<string, LockFile> = {}; logger.debug('Finding locked versions'); for (const packageFile of packageFiles) { const { yarnLock, npmLock, pnpmShrinkwrap } = packageFile; @@ -17,9 +18,9 @@ export async function getLockedVersions( logger.trace('Retrieving/parsing ' + yarnLock); lockFileCache[yarnLock] = await getYarnLock(yarnLock); } - const { cacheVersion, isYarn1 } = lockFileCache[yarnLock]; + const { lockfileVersion, isYarn1 } = lockFileCache[yarnLock]; if (!isYarn1) { - if (cacheVersion >= 6) { + if (lockfileVersion >= 6) { // https://github.com/yarnpkg/berry/commit/f753790380cbda5b55d028ea84b199445129f9ba packageFile.constraints.yarn = '>= 2.2.0'; } else { @@ -36,7 +37,7 @@ export async function getLockedVersions( logger.debug('Found ' + npmLock + ' for ' + packageFile.packageFile); if (!lockFileCache[npmLock]) { logger.trace('Retrieving/parsing ' + npmLock); - lockFileCache[npmLock] = { lockedVersions: await getNpmLock(npmLock) }; + lockFileCache[npmLock] = await getNpmLock(npmLock); } for (const dep of packageFile.deps) { dep.lockedVersion = valid( @@ -48,9 +49,3 @@ export async function getLockedVersions( } } } - -interface YarnLockCache { - lockedVersions: Record<string, string>; - cacheVersion?: number; - isYarn1?: boolean; -} diff --git a/lib/manager/npm/extract/npm.spec.ts b/lib/manager/npm/extract/npm.spec.ts index 3156240410..077259fcde 100644 --- a/lib/manager/npm/extract/npm.spec.ts +++ b/lib/manager/npm/extract/npm.spec.ts @@ -9,7 +9,7 @@ describe('manager/npm/extract/npm', () => { it('returns empty if failed to parse', async () => { fs.readLocalFile.mockResolvedValueOnce('abcd'); const res = await getNpmLock('package.json'); - expect(Object.keys(res)).toHaveLength(0); + expect(Object.keys(res.lockedVersions)).toHaveLength(0); }); it('extracts', async () => { const plocktest1Lock = readFileSync( @@ -18,12 +18,12 @@ describe('manager/npm/extract/npm', () => { fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock as never); const res = await getNpmLock('package.json'); expect(res).toMatchSnapshot(); - expect(Object.keys(res)).toHaveLength(7); + expect(Object.keys(res.lockedVersions)).toHaveLength(7); }); it('returns empty if no deps', async () => { fs.readLocalFile.mockResolvedValueOnce('{}'); const res = await getNpmLock('package.json'); - expect(Object.keys(res)).toHaveLength(0); + expect(Object.keys(res.lockedVersions)).toHaveLength(0); }); }); }); diff --git a/lib/manager/npm/extract/npm.ts b/lib/manager/npm/extract/npm.ts index bfabceffa2..6982352412 100644 --- a/lib/manager/npm/extract/npm.ts +++ b/lib/manager/npm/extract/npm.ts @@ -1,23 +1,21 @@ import { logger } from '../../../logger'; import { readLocalFile } from '../../../util/fs'; -import { LockFileEntry } from './common'; +import { LockFile, LockFileEntry } from './common'; -export async function getNpmLock( - filePath: string -): Promise<Record<string, string>> { +export async function getNpmLock(filePath: string): Promise<LockFile> { const lockRaw = await readLocalFile(filePath, 'utf8'); try { const lockParsed = JSON.parse(lockRaw); - const lockFile: Record<string, string> = {}; + const lockedVersions: Record<string, string> = {}; for (const [entry, val] of Object.entries( (lockParsed.dependencies || {}) as LockFileEntry )) { logger.trace({ entry, version: val.version }); - lockFile[entry] = val.version; + lockedVersions[entry] = val.version; } - return lockFile; + return { lockedVersions }; } catch (err) { logger.debug({ filePath, err }, 'Warning: Exception parsing npm lock file'); - return {}; + return { lockedVersions: {} }; } } diff --git a/lib/manager/npm/extract/yarn.spec.ts b/lib/manager/npm/extract/yarn.spec.ts index 18cff3c671..a106e7ecd4 100644 --- a/lib/manager/npm/extract/yarn.spec.ts +++ b/lib/manager/npm/extract/yarn.spec.ts @@ -21,7 +21,7 @@ describe('manager/npm/extract/yarn', () => { fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getYarnLock('package.json'); expect(res.isYarn1).toBe(true); - expect(res.cacheVersion).toBe(NaN); + expect(res.lockfileVersion).toBeUndefined(); expect(res.lockedVersions).toMatchSnapshot(); expect(Object.keys(res.lockedVersions)).toHaveLength(7); }); @@ -34,7 +34,7 @@ describe('manager/npm/extract/yarn', () => { fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getYarnLock('package.json'); expect(res.isYarn1).toBe(false); - expect(res.cacheVersion).toBe(NaN); + expect(res.lockfileVersion).toBe(NaN); expect(res.lockedVersions).toMatchSnapshot(); expect(Object.keys(res.lockedVersions)).toHaveLength(8); }); @@ -47,7 +47,7 @@ describe('manager/npm/extract/yarn', () => { fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getYarnLock('package.json'); expect(res.isYarn1).toBe(false); - expect(res.cacheVersion).toBe(6); + expect(res.lockfileVersion).toBe(6); expect(res.lockedVersions).toMatchSnapshot(); expect(Object.keys(res.lockedVersions)).toHaveLength(10); }); diff --git a/lib/manager/npm/extract/yarn.ts b/lib/manager/npm/extract/yarn.ts index 731f17dcd0..fa7d17b9bf 100644 --- a/lib/manager/npm/extract/yarn.ts +++ b/lib/manager/npm/extract/yarn.ts @@ -2,24 +2,19 @@ import { structUtils } from '@yarnpkg/core'; import { parseSyml } from '@yarnpkg/parsers'; import { logger } from '../../../logger'; import { readLocalFile } from '../../../util/fs'; +import { LockFile } from './common'; -export async function getYarnLock( - filePath: string -): Promise<{ - isYarn1: boolean; - cacheVersion: number; - lockedVersions: Record<string, string>; -}> { +export async function getYarnLock(filePath: string): Promise<LockFile> { const yarnLockRaw = await readLocalFile(filePath, 'utf8'); try { const parsed = parseSyml(yarnLockRaw); - const lockFile: Record<string, string> = {}; - let cacheVersion = NaN; + const lockedVersions: Record<string, string> = {}; + let lockfileVersion: number; for (const [key, val] of Object.entries(parsed)) { if (key === '__metadata') { // yarn 2 - cacheVersion = parseInt(val.cacheKey, 10); + lockfileVersion = parseInt(val.cacheKey, 10); } else { for (const entry of key.split(', ')) { const { scope, name, range } = structUtils.parseDescriptor(entry); @@ -27,17 +22,17 @@ export async function getYarnLock( const { selector } = structUtils.parseRange(range); logger.trace({ entry, version: val.version }); - lockFile[packageName + '@' + selector] = parsed[key].version; + lockedVersions[packageName + '@' + selector] = parsed[key].version; } } } return { isYarn1: !('__metadata' in parsed), - cacheVersion, - lockedVersions: lockFile, + lockfileVersion, + lockedVersions, }; } catch (err) { logger.debug({ filePath, err }, 'Warning: Exception parsing yarn.lock'); - return { isYarn1: true, cacheVersion: NaN, lockedVersions: {} }; + return { isYarn1: true, lockedVersions: {} }; } } -- GitLab