From 771978d7fb77d2e524c6f73ccefd25ccee9473e3 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Thu, 24 Mar 2022 23:50:08 +0800 Subject: [PATCH 01/25] feat: add git-branch-lockfile config to generate lockfile in each branch --- packages/config/src/Config.ts | 1 + packages/config/src/index.ts | 7 +++++ packages/core/src/getPeerDependencyIssues.ts | 1 + .../core/src/install/extendInstallOptions.ts | 2 ++ packages/core/src/install/index.ts | 2 +- packages/core/src/link/index.ts | 2 +- packages/core/src/link/options.ts | 2 ++ packages/get-context/src/index.ts | 4 +++ packages/get-context/src/readLockfiles.ts | 4 ++- packages/headless/src/index.ts | 6 +++- .../lockfile-file/src/existsWantedLockfile.ts | 13 +++++++-- packages/lockfile-file/src/gitChecks.ts | 6 ++++ packages/lockfile-file/src/lockfileName.ts | 21 ++++++++++++++ packages/lockfile-file/src/read.ts | 29 ++++++++++++++++--- packages/lockfile-file/src/write.ts | 9 ++++-- .../storeStatus/extendStoreStatusOptions.ts | 2 ++ 16 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 packages/lockfile-file/src/gitChecks.ts create mode 100644 packages/lockfile-file/src/lockfileName.ts diff --git a/packages/config/src/Config.ts b/packages/config/src/Config.ts index 9805bc5e7d9..3b1be3739d1 100644 --- a/packages/config/src/Config.ts +++ b/packages/config/src/Config.ts @@ -130,6 +130,7 @@ export interface Config { modulesDir?: string sharedWorkspaceLockfile?: boolean useLockfile: boolean + useGitBranchLockfile: boolean globalPnpmfile?: string npmPath?: string gitChecks?: boolean diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 23215bbc1d1..5c96c321cb1 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -51,6 +51,7 @@ export const types = Object.assign({ 'global-dir': String, 'global-path': String, 'global-pnpmfile': String, + 'git-branch-lockfile': Boolean, hoist: Boolean, 'hoist-pattern': Array, 'ignore-pnpmfile': Boolean, @@ -173,6 +174,7 @@ export default async ( 'fetch-retry-mintimeout': 10000, 'fetch-timeout': 60000, globalconfig: npmDefaults.globalconfig, + 'git-branch-lockfile': false, hoist: true, 'hoist-pattern': ['*'], 'ignore-workspace-root-check': false, @@ -249,6 +251,10 @@ export default async ( if (typeof pnpmConfig['packageLock'] === 'boolean') return pnpmConfig['packageLock'] return false })() + pnpmConfig.useGitBranchLockfile = (() => { + if (typeof pnpmConfig['gitBranchLockfile'] === 'boolean') return pnpmConfig['gitBranchLockfile'] + return false + })() pnpmConfig.pnpmHomeDir = getDataDir(process) if (cliOptions['global']) { @@ -302,6 +308,7 @@ export default async ( } delete pnpmConfig.lockfileDir } + pnpmConfig.useGitBranchLockfile = false if (opts.cliOptions['virtual-store-dir']) { throw new PnpmError('CONFIG_CONFLICT_VIRTUAL_STORE_DIR_WITH_GLOBAL', 'Configuration conflict. "virtual-store-dir" may not be used with "global"') diff --git a/packages/core/src/getPeerDependencyIssues.ts b/packages/core/src/getPeerDependencyIssues.ts index 2099ff43a33..b5bb3cbea99 100644 --- a/packages/core/src/getPeerDependencyIssues.ts +++ b/packages/core/src/getPeerDependencyIssues.ts @@ -16,6 +16,7 @@ export type ListMissingPeersOptions = Partial | 'preferWorkspacePackages' | 'saveWorkspaceProtocol' | 'storeController' +| 'useGitBranchLockfile' | 'workspacePackages' > & Pick diff --git a/packages/core/src/install/extendInstallOptions.ts b/packages/core/src/install/extendInstallOptions.ts index 9c1e5d6bb9f..4aae849c52c 100644 --- a/packages/core/src/install/extendInstallOptions.ts +++ b/packages/core/src/install/extendInstallOptions.ts @@ -23,6 +23,7 @@ export interface StrictInstallOptions { extraBinPaths: string[] hoistingLimits?: HoistingLimits useLockfile: boolean + useGitBranchLockfile: boolean linkWorkspacePackagesDepth: number lockfileOnly: boolean fixLockfile: boolean @@ -162,6 +163,7 @@ const defaults = async (opts: InstallOptions) => { process.getuid() !== 0, update: false, useLockfile: true, + useGitBranchLockfile: false, userAgent: `${packageManager.name}/${packageManager.version} npm/? node/${process.version} ${process.platform} ${process.arch}`, verifyStoreIntegrity: true, workspacePackages: {}, diff --git a/packages/core/src/install/index.ts b/packages/core/src/install/index.ts index 44f372d2a91..ef6014c9a77 100644 --- a/packages/core/src/install/index.ts +++ b/packages/core/src/install/index.ts @@ -769,7 +769,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => { } const depsStateCache: DepsStateCache = {} - const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile } + const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile, useGitBranchLockfile: opts.useGitBranchLockfile } if (!opts.lockfileOnly && opts.enableModulesDir) { const result = await linkPackages( projects, diff --git a/packages/core/src/link/index.ts b/packages/core/src/link/index.ts index af57b1b1264..088bc8b05f0 100644 --- a/packages/core/src/link/index.ts +++ b/packages/core/src/link/index.ts @@ -157,7 +157,7 @@ export default async function link ( } else { newPkg = opts.manifest } - const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile } + const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile, useGitBranchLockfile: opts.useGitBranchLockfile } if (opts.useLockfile) { await writeLockfiles({ currentLockfile: updatedCurrentLockfile, diff --git a/packages/core/src/link/options.ts b/packages/core/src/link/options.ts index 624f827fd39..84d5fcb164b 100644 --- a/packages/core/src/link/options.ts +++ b/packages/core/src/link/options.ts @@ -29,6 +29,8 @@ interface StrictLinkOptions { publicHoistPattern: string[] | undefined forcePublicHoistPattern: boolean + + useGitBranchLockfile: boolean } export type LinkOptions = diff --git a/packages/get-context/src/index.ts b/packages/get-context/src/index.ts index a277974bda0..e9f513eb1fd 100644 --- a/packages/get-context/src/index.ts +++ b/packages/get-context/src/index.ts @@ -82,6 +82,7 @@ export interface GetContextOptions { registries: Registries storeDir: string useLockfile: boolean + useGitBranchLockfile?: boolean virtualStoreDir?: string hoistPattern?: string[] | undefined @@ -176,6 +177,7 @@ export default async function getContext ( projects: importersContext.projects, registry: opts.registries.default, useLockfile: opts.useLockfile, + useGitBranchLockfile: opts.useGitBranchLockfile, virtualStoreDir, }), } @@ -376,6 +378,7 @@ export async function getContextForSingleImporter ( registries: Registries storeDir: string useLockfile: boolean + useGitBranchLockfile?: boolean virtualStoreDir?: string hoistPattern?: string[] | undefined @@ -479,6 +482,7 @@ export async function getContextForSingleImporter ( projects: [{ id: importerId, rootDir: opts.dir }], registry: opts.registries.default, useLockfile: opts.useLockfile, + useGitBranchLockfile: opts.useGitBranchLockfile, virtualStoreDir, }), } diff --git a/packages/get-context/src/readLockfiles.ts b/packages/get-context/src/readLockfiles.ts index 6ce12cfba03..19f022d50dc 100644 --- a/packages/get-context/src/readLockfiles.ts +++ b/packages/get-context/src/readLockfiles.ts @@ -34,6 +34,7 @@ export default async function ( lockfileDir: string registry: string useLockfile: boolean + useGitBranchLockfile?: boolean virtualStoreDir: string } ): Promise<{ @@ -49,6 +50,7 @@ export default async function ( const lockfileOpts = { ignoreIncompatible: opts.force || isCI, wantedVersion: LOCKFILE_VERSION, + useGitBranchLockfile: opts.useGitBranchLockfile, } const fileReads = [] as Array> let lockfileHadConflicts: boolean = false @@ -73,7 +75,7 @@ export default async function ( fileReads.push(readWantedLockfile(opts.lockfileDir, lockfileOpts)) } } else { - if (await existsWantedLockfile(opts.lockfileDir)) { + if (await existsWantedLockfile(opts.lockfileDir, lockfileOpts)) { logger.warn({ message: `A ${WANTED_LOCKFILE} file exists. The current configuration prohibits to read or write a lockfile`, prefix: opts.lockfileDir, diff --git a/packages/headless/src/index.ts b/packages/headless/src/index.ts index d11e87fdf79..4d6d1390f94 100644 --- a/packages/headless/src/index.ts +++ b/packages/headless/src/index.ts @@ -137,6 +137,7 @@ export interface HeadlessOptions { skipped: Set enableModulesDir?: boolean nodeLinker?: 'isolated' | 'hoisted' | 'pnp' + useGitBranchLockfile?: boolean } export default async (opts: HeadlessOptions) => { @@ -146,7 +147,10 @@ export default async (opts: HeadlessOptions) => { } const lockfileDir = opts.lockfileDir - const wantedLockfile = opts.wantedLockfile ?? await readWantedLockfile(lockfileDir, { ignoreIncompatible: false }) + const wantedLockfile = opts.wantedLockfile ?? await readWantedLockfile(lockfileDir, { + ignoreIncompatible: false, + useGitBranchLockfile: opts.useGitBranchLockfile, + }) if (wantedLockfile == null) { throw new Error(`Headless installation requires a ${WANTED_LOCKFILE} file`) diff --git a/packages/lockfile-file/src/existsWantedLockfile.ts b/packages/lockfile-file/src/existsWantedLockfile.ts index c7625fc7d68..7b5b3f1233d 100644 --- a/packages/lockfile-file/src/existsWantedLockfile.ts +++ b/packages/lockfile-file/src/existsWantedLockfile.ts @@ -1,9 +1,16 @@ import fs from 'fs' import path from 'path' -import { WANTED_LOCKFILE } from '@pnpm/constants' +import { getWantedLockfileName } from './lockfileName' -export default async (pkgPath: string) => new Promise((resolve, reject) => { - fs.access(path.join(pkgPath, WANTED_LOCKFILE), (err) => { +interface ExistsWantedLockfileOptions { + useGitBranchLockfile?: boolean +} + +export default async (pkgPath: string, opts: ExistsWantedLockfileOptions = { + useGitBranchLockfile: false, +}) => new Promise((resolve, reject) => { + const wantedLockfile: string = getWantedLockfileName(opts) + fs.access(path.join(pkgPath, wantedLockfile), (err) => { if (err == null) { resolve(true) return diff --git a/packages/lockfile-file/src/gitChecks.ts b/packages/lockfile-file/src/gitChecks.ts new file mode 100644 index 00000000000..d23c24dd89d --- /dev/null +++ b/packages/lockfile-file/src/gitChecks.ts @@ -0,0 +1,6 @@ +import { spawnSync } from 'child_process' + +export function getCurrentBranchName () { + const { stdout } = spawnSync('git', ['symbolic-ref', '--short', 'HEAD'], { encoding: 'utf8' }) + return String(stdout).trim() +} \ No newline at end of file diff --git a/packages/lockfile-file/src/lockfileName.ts b/packages/lockfile-file/src/lockfileName.ts new file mode 100644 index 00000000000..3583e8de957 --- /dev/null +++ b/packages/lockfile-file/src/lockfileName.ts @@ -0,0 +1,21 @@ +import { WANTED_LOCKFILE } from '@pnpm/constants' +import { getCurrentBranchName } from './gitChecks' + +interface GetWantedLockfileNameOptions { + useGitBranchLockfile?: boolean +} + +export function getWantedLockfileName (opts: GetWantedLockfileNameOptions = { useGitBranchLockfile: false }) { + if (opts.useGitBranchLockfile) { + const currentBranchName = getCurrentBranchName() + if (currentBranchName) { + return WANTED_LOCKFILE.replace('.yaml', `.${stringifyBranchName(currentBranchName)}.yaml`) + } + } + return WANTED_LOCKFILE +} + +// branch name may contains slashes, which is not allowed in filenames +function stringifyBranchName (branchName: string = '') { + return branchName.replace(/[^a-zA-Z0-9-_.]/g, '!') +} \ No newline at end of file diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index 24466903efd..958e98ce0ac 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -15,6 +15,7 @@ import { LockfileBreakingChangeError } from './errors' import { autofixMergeConflicts, isDiff } from './gitMergeFile' import logger from './logger' import { LockfileFile } from './write' +import { getWantedLockfileName } from './lockfileName' export async function readCurrentLockfile ( virtualStoreDir: string, @@ -32,13 +33,24 @@ export async function readWantedLockfileAndAutofixConflicts ( opts: { wantedVersion?: number ignoreIncompatible: boolean + useGitBranchLockfile?: boolean } ): Promise<{ lockfile: Lockfile | null hadConflicts: boolean }> { - const lockfilePath = path.join(pkgPath, WANTED_LOCKFILE) - return _read(lockfilePath, pkgPath, { ...opts, autofixMergeConflicts: true }) + let result: { lockfile: Lockfile | null, hadConflicts: boolean} = { + lockfile: null, + hadConflicts: false, + } + if (opts.useGitBranchLockfile) { + const lockfilePath = path.join(pkgPath, getWantedLockfileName(opts)) + result = await _read(lockfilePath, pkgPath, { ...opts, autofixMergeConflicts: true }) + } + if (!result.lockfile) { + result = await _read(WANTED_LOCKFILE, pkgPath, { ...opts, autofixMergeConflicts: true }) + } + return result } export async function readWantedLockfile ( @@ -46,10 +58,18 @@ export async function readWantedLockfile ( opts: { wantedVersion?: number ignoreIncompatible: boolean + useGitBranchLockfile?: boolean } ): Promise { - const lockfilePath = path.join(pkgPath, WANTED_LOCKFILE) - return (await _read(lockfilePath, pkgPath, opts)).lockfile + let lockfile: Lockfile | null = null + if (opts.useGitBranchLockfile) { + const lockfilePath = path.join(pkgPath, getWantedLockfileName(opts)) + lockfile = (await _read(lockfilePath, pkgPath, opts)).lockfile + } + if (!lockfile) { + lockfile = (await _read(WANTED_LOCKFILE, pkgPath, opts)).lockfile + } + return lockfile } async function _read ( @@ -59,6 +79,7 @@ async function _read ( autofixMergeConflicts?: boolean wantedVersion?: number ignoreIncompatible: boolean + useGitBranchLockfile?: boolean } ): Promise<{ lockfile: Lockfile | null diff --git a/packages/lockfile-file/src/write.ts b/packages/lockfile-file/src/write.ts index ec7b662c60a..cdb0c948105 100644 --- a/packages/lockfile-file/src/write.ts +++ b/packages/lockfile-file/src/write.ts @@ -10,6 +10,7 @@ import isEmpty from 'ramda/src/isEmpty' import writeFileAtomicCB from 'write-file-atomic' import logger from './logger' import { sortLockfileKeys } from './sortLockfileKeys' +import { getWantedLockfileName } from './lockfileName' async function writeFileAtomic (filename: string, data: string) { return new Promise((resolve, reject) => writeFileAtomicCB(filename, data, {}, (err?: Error) => (err != null) ? reject(err) : resolve())) @@ -28,9 +29,11 @@ export async function writeWantedLockfile ( wantedLockfile: Lockfile, opts?: { forceSharedFormat?: boolean + useGitBranchLockfile?: boolean } ) { - return writeLockfile(WANTED_LOCKFILE, pkgPath, wantedLockfile, opts) + const wantedLockfileName: string = getWantedLockfileName(opts) + return writeLockfile(wantedLockfileName, pkgPath, wantedLockfile, opts) } export async function writeCurrentLockfile ( @@ -142,9 +145,11 @@ export default async function writeLockfiles ( wantedLockfileDir: string currentLockfile: Lockfile currentLockfileDir: string + useGitBranchLockfile?: boolean } ) { - const wantedLockfilePath = path.join(opts.wantedLockfileDir, WANTED_LOCKFILE) + const wantedLockfileName: string = getWantedLockfileName(opts) + const wantedLockfilePath = path.join(opts.wantedLockfileDir, wantedLockfileName) const currentLockfilePath = path.join(opts.currentLockfileDir, 'lock.yaml') // empty lockfile is not saved diff --git a/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts b/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts index cfe02e78574..4d9fe7a3175 100644 --- a/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts +++ b/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts @@ -11,6 +11,7 @@ export interface StrictStoreStatusOptions { forceSharedLockfile: boolean nodeLinker: 'isolated' | 'hoisted' | 'pnp' useLockfile: boolean + useGitBranchLockfile: boolean registries: Registries shamefullyHoist: boolean @@ -38,6 +39,7 @@ const defaults = async (opts: StoreStatusOptions) => { shamefullyHoist: false, storeDir: opts.storeDir, useLockfile: true, + useGitBranchLockfile: false, } as StrictStoreStatusOptions } From 781addd9a3ee7503de22492944bc717890f6d15d Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Fri, 25 Mar 2022 00:46:46 +0800 Subject: [PATCH 02/25] feat: add --clean-git-branch-lockfiles arg to pnpm install --- packages/config/src/Config.ts | 1 + packages/config/src/index.ts | 3 ++- packages/core/src/install/extendInstallOptions.ts | 2 ++ packages/core/src/install/index.ts | 5 +++++ .../lockfile-file/src/cleanGitBranchLockfile.ts | 13 +++++++++++++ packages/lockfile-file/src/index.ts | 2 ++ .../plugin-commands-installation/src/install.ts | 5 +++++ 7 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 packages/lockfile-file/src/cleanGitBranchLockfile.ts diff --git a/packages/config/src/Config.ts b/packages/config/src/Config.ts index 3b1be3739d1..6818ac878f6 100644 --- a/packages/config/src/Config.ts +++ b/packages/config/src/Config.ts @@ -15,6 +15,7 @@ export interface Config { allowNew: boolean autoInstallPeers?: boolean bail: boolean + cleanGitBranchLockfiles?: boolean color: 'always' | 'auto' | 'never' cliOptions: Record, // eslint-disable-line useBetaCli: boolean diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 5c96c321cb1..8ddae82e7bc 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -35,6 +35,7 @@ export const types = Object.assign({ bail: Boolean, 'cache-dir': String, 'child-concurrency': Number, + 'clean-git-branch-lockfiles': Boolean, color: ['always', 'auto', 'never'], 'config-dir': String, dev: [null, true], @@ -252,7 +253,7 @@ export default async ( return false })() pnpmConfig.useGitBranchLockfile = (() => { - if (typeof pnpmConfig['gitBranchLockfile'] === 'boolean') return pnpmConfig['gitBranchLockfile'] + if (!pnpmConfig.cleanGitBranchLockfiles && typeof pnpmConfig['gitBranchLockfile'] === 'boolean') return pnpmConfig['gitBranchLockfile'] return false })() pnpmConfig.pnpmHomeDir = getDataDir(process) diff --git a/packages/core/src/install/extendInstallOptions.ts b/packages/core/src/install/extendInstallOptions.ts index 4aae849c52c..f2ea52c8704 100644 --- a/packages/core/src/install/extendInstallOptions.ts +++ b/packages/core/src/install/extendInstallOptions.ts @@ -24,6 +24,7 @@ export interface StrictInstallOptions { hoistingLimits?: HoistingLimits useLockfile: boolean useGitBranchLockfile: boolean + cleanGitBranchLockfiles: boolean linkWorkspacePackagesDepth: number lockfileOnly: boolean fixLockfile: boolean @@ -164,6 +165,7 @@ const defaults = async (opts: InstallOptions) => { update: false, useLockfile: true, useGitBranchLockfile: false, + cleanGitBranchLockfiles: false, userAgent: `${packageManager.name}/${packageManager.version} npm/? node/${process.version} ${process.platform} ${process.arch}`, verifyStoreIntegrity: true, workspacePackages: {}, diff --git a/packages/core/src/install/index.ts b/packages/core/src/install/index.ts index ef6014c9a77..522e1cf480f 100644 --- a/packages/core/src/install/index.ts +++ b/packages/core/src/install/index.ts @@ -25,6 +25,7 @@ import { writeCurrentLockfile, writeLockfiles, writeWantedLockfile, + cleanGitBranchLockfiles, } from '@pnpm/lockfile-file' import { writePnpFile } from '@pnpm/lockfile-to-pnp' import { extendProjectsWithTargetDirs } from '@pnpm/lockfile-utils' @@ -195,6 +196,10 @@ export async function mutateModules ( streamParser.removeListener('data', reporter) } + if (opts.cleanGitBranchLockfiles) { + await cleanGitBranchLockfiles(ctx.lockfileDir) + } + return result async function _install (): Promise { diff --git a/packages/lockfile-file/src/cleanGitBranchLockfile.ts b/packages/lockfile-file/src/cleanGitBranchLockfile.ts new file mode 100644 index 00000000000..303ed52151f --- /dev/null +++ b/packages/lockfile-file/src/cleanGitBranchLockfile.ts @@ -0,0 +1,13 @@ +import { promises as fs } from 'fs' +import path from 'path' + +export async function cleanGitBranchLockfiles (pkgPath: string) { + const files = await fs.readdir(pkgPath) + const gitBranchLockfiles: string[] = files.filter(file => file.match(/pnpm-lock.(?:.*).yaml/)) + await Promise.all( + gitBranchLockfiles.map(async file => { + const filepath: string = path.join(pkgPath, file) + await fs.rm(filepath) + }) + ) +} \ No newline at end of file diff --git a/packages/lockfile-file/src/index.ts b/packages/lockfile-file/src/index.ts index 0587041af04..26bf3be624d 100644 --- a/packages/lockfile-file/src/index.ts +++ b/packages/lockfile-file/src/index.ts @@ -15,3 +15,5 @@ export { writeCurrentLockfile, writeWantedLockfile, } + +export { cleanGitBranchLockfiles } from './cleanGitBranchLockfile' \ No newline at end of file diff --git a/packages/plugin-commands-installation/src/install.ts b/packages/plugin-commands-installation/src/install.ts index f5ca42de8f5..847c9d7936e 100644 --- a/packages/plugin-commands-installation/src/install.ts +++ b/packages/plugin-commands-installation/src/install.ts @@ -12,6 +12,7 @@ export function rcOptionsTypes () { return pick([ 'cache-dir', 'child-concurrency', + 'clean-git-branch-lockfiles', 'dev', 'engine-strict', 'fetch-retries', @@ -139,6 +140,10 @@ For options that may be used with `-r`, see "pnpm help recursive"', description: 'Fix broken lockfile entries automatically', name: '--fix-lockfile', }, + { + description: 'Clean lockfiles were generated on git branch', + name: '--clean-git-branch-lockfiles', + }, { description: 'The directory in which dependencies will be installed (instead of node_modules)', name: '--modules-dir ', From 37133482a75cb4df46f638a3196f587592b17d7a Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Fri, 25 Mar 2022 01:40:44 +0800 Subject: [PATCH 03/25] chore: test lockfile name --- packages/lockfile-file/src/lockfileName.ts | 2 +- packages/lockfile-file/src/read.ts | 5 ++- .../lockfile-file/test/lockfileName.test.ts | 32 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 packages/lockfile-file/test/lockfileName.test.ts diff --git a/packages/lockfile-file/src/lockfileName.ts b/packages/lockfile-file/src/lockfileName.ts index 3583e8de957..c0fba3540ac 100644 --- a/packages/lockfile-file/src/lockfileName.ts +++ b/packages/lockfile-file/src/lockfileName.ts @@ -1,7 +1,7 @@ import { WANTED_LOCKFILE } from '@pnpm/constants' import { getCurrentBranchName } from './gitChecks' -interface GetWantedLockfileNameOptions { +export interface GetWantedLockfileNameOptions { useGitBranchLockfile?: boolean } diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index 958e98ce0ac..a1255c10bda 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -48,7 +48,7 @@ export async function readWantedLockfileAndAutofixConflicts ( result = await _read(lockfilePath, pkgPath, { ...opts, autofixMergeConflicts: true }) } if (!result.lockfile) { - result = await _read(WANTED_LOCKFILE, pkgPath, { ...opts, autofixMergeConflicts: true }) + result = await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, { ...opts, autofixMergeConflicts: true }) } return result } @@ -67,7 +67,7 @@ export async function readWantedLockfile ( lockfile = (await _read(lockfilePath, pkgPath, opts)).lockfile } if (!lockfile) { - lockfile = (await _read(WANTED_LOCKFILE, pkgPath, opts)).lockfile + lockfile = (await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, opts)).lockfile } return lockfile } @@ -79,7 +79,6 @@ async function _read ( autofixMergeConflicts?: boolean wantedVersion?: number ignoreIncompatible: boolean - useGitBranchLockfile?: boolean } ): Promise<{ lockfile: Lockfile | null diff --git a/packages/lockfile-file/test/lockfileName.test.ts b/packages/lockfile-file/test/lockfileName.test.ts new file mode 100644 index 00000000000..41889d66d91 --- /dev/null +++ b/packages/lockfile-file/test/lockfileName.test.ts @@ -0,0 +1,32 @@ +/* eslint-disable import/first */ +const getCurrentBranchName = jest.fn() +jest.mock('@pnpm/lockfile-file/lib/gitChecks', () => { + const original = jest.requireActual('@pnpm/lockfile-file/lib/gitChecks') + return { + ...original, + getCurrentBranchName, + } +}) + +import { WANTED_LOCKFILE } from '@pnpm/constants' +import { getWantedLockfileName } from '@pnpm/lockfile-file/lib/lockfileName' + +describe('lockfileName', () => { + afterEach(() => { + getCurrentBranchName.mockReset() + }) + + test('returns default lockfile name if useGitBranchLockfile is off', () => { + expect(getWantedLockfileName()).toBe(WANTED_LOCKFILE) + }) + + test('returns git branch lockfile name', () => { + getCurrentBranchName.mockReturnValue('main') + expect(getWantedLockfileName({ useGitBranchLockfile: true })).toBe('pnpm-lock.main.yaml') + }) + + test('returns git branch lockfile name when git branch contains clashes', () => { + getCurrentBranchName.mockReturnValue('a/b/c') + expect(getWantedLockfileName({ useGitBranchLockfile: true })).toBe('pnpm-lock.a!b!c.yaml') + }) +}) From 5ea34d3fe7b04acaed842e7f4ba863c74b72bce8 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Fri, 25 Mar 2022 14:25:38 +0800 Subject: [PATCH 04/25] chore: add more tests for git branch lockfile --- .../test/install/gitBranchLockfile.test.ts | 118 ++++++++++++++++++ .../test/fixtures/6/pnpm-lock.branch.yaml | 4 + .../test/fixtures/6/pnpm-lock.yaml | 4 + .../lockfile-file/test/lockfileName.test.ts | 11 +- packages/lockfile-file/test/read.test.ts | 27 ++++ .../lockfile-file/test/utils/mockGitChecks.ts | 15 +++ packages/lockfile-file/test/write.test.ts | 37 ++++++ privatePackages/assert-project/src/index.ts | 6 +- 8 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 packages/core/test/install/gitBranchLockfile.test.ts create mode 100644 packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml create mode 100644 packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml create mode 100644 packages/lockfile-file/test/utils/mockGitChecks.ts diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts new file mode 100644 index 00000000000..414974c0611 --- /dev/null +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -0,0 +1,118 @@ +import fs from 'fs' +import path from 'path' +import { getCurrentBranchName } from '@pnpm/lockfile-file/test/utils/mockGitChecks' +import { prepareEmpty, preparePackages } from '@pnpm/prepare' +import { install, mutateModules } from '@pnpm/core' +import { testDefaults } from '../utils' +import { WANTED_LOCKFILE } from '@pnpm/constants' +import { ProjectManifest } from '@pnpm/types' +import writeYamlFile from 'write-yaml-file' + +test('install with git-branch-lockfile = true', async () => { + const project = prepareEmpty() + + const branchName: string = 'main-branch' + getCurrentBranchName.mockReturnValue(branchName) + + const opts = await testDefaults({ + useGitBranchLockfile: true, + }) + + await install({ + dependencies: { + 'is-positive': '^3.0.0', + }, + }, opts) + + const lockfileDir: string = project.dir() + expect(fs.existsSync(path.join(lockfileDir, `pnpm-lock.${branchName}.yaml`))).toBe(true) + expect(fs.existsSync(path.join(lockfileDir, WANTED_LOCKFILE))).toBe(false) +}) + +test('install a workspace with git-branch-lockfile = true', async () => { + const rootManifest: ProjectManifest = { + name: 'root', + } + const project1Manifest: ProjectManifest = { + name: 'project-1', + dependencies: { 'is-positive': '1.0.0' }, + } + const project2Manifest: ProjectManifest = { + name: 'project-2', + dependencies: { 'is-positive': '1.0.0' }, + } + const { root } = preparePackages([ + { + location: '.', + package: rootManifest, + }, + { + location: 'project-1', + package: project1Manifest, + }, + { + location: 'project-2', + package: project2Manifest, + }, + ]) + + const branchName: string = 'main-branch' + getCurrentBranchName.mockReturnValue(branchName) + + const opts = await testDefaults({ + useGitBranchLockfile: true, + }) + + await mutateModules([ + { + buildIndex: 0, + manifest: rootManifest, + mutation: 'install', + rootDir: process.cwd(), + }, + { + buildIndex: 0, + manifest: project1Manifest, + mutation: 'install', + rootDir: path.resolve('project-1'), + }, + { + buildIndex: 0, + manifest: project2Manifest, + mutation: 'install', + rootDir: path.resolve('project-2'), + }, + ], opts) + + const lockfileDir: string = root.dir() + expect(fs.existsSync(path.join(lockfileDir, `pnpm-lock.${branchName}.yaml`))).toBe(true) + expect(fs.existsSync(path.join(lockfileDir, WANTED_LOCKFILE))).toBe(false) +}) + +test('install with --clean-git-branch-lockfiles', async () => { + prepareEmpty() + + const branchName: string = 'main-branch' + getCurrentBranchName.mockReturnValue(branchName) + + const otherLockfilePath: string = path.resolve('pnpm-lock.other.yaml') + const mainLockfilePath: string = path.resolve(WANTED_LOCKFILE) + await writeYamlFile(otherLockfilePath, { + whatever: 'whatever', + }) + + expect(fs.existsSync(otherLockfilePath)).toBe(true) + expect(fs.existsSync(mainLockfilePath)).toBe(false) + + const opts = await testDefaults({ + cleanGitBranchLockfiles: true, + }) + await install({ + dependencies: { + 'is-positive': '^3.0.0', + }, + }, opts) + + expect(fs.existsSync(otherLockfilePath)).toBe(false) + expect(fs.existsSync(mainLockfilePath)).toBe(true) +}) \ No newline at end of file diff --git a/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml b/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml new file mode 100644 index 00000000000..0674b1d2f80 --- /dev/null +++ b/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml @@ -0,0 +1,4 @@ +lockfileVersion: 5.3 + +specifiers: + foo: '2' diff --git a/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml b/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml new file mode 100644 index 00000000000..58873f9a5b2 --- /dev/null +++ b/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml @@ -0,0 +1,4 @@ +lockfileVersion: 5.3 + +specifiers: + foo: '1' diff --git a/packages/lockfile-file/test/lockfileName.test.ts b/packages/lockfile-file/test/lockfileName.test.ts index 41889d66d91..ebb4464af2e 100644 --- a/packages/lockfile-file/test/lockfileName.test.ts +++ b/packages/lockfile-file/test/lockfileName.test.ts @@ -1,13 +1,4 @@ -/* eslint-disable import/first */ -const getCurrentBranchName = jest.fn() -jest.mock('@pnpm/lockfile-file/lib/gitChecks', () => { - const original = jest.requireActual('@pnpm/lockfile-file/lib/gitChecks') - return { - ...original, - getCurrentBranchName, - } -}) - +import { getCurrentBranchName } from './utils/mockGitChecks' import { WANTED_LOCKFILE } from '@pnpm/constants' import { getWantedLockfileName } from '@pnpm/lockfile-file/lib/lockfileName' diff --git a/packages/lockfile-file/test/read.test.ts b/packages/lockfile-file/test/read.test.ts index 228e762e1a3..0d86d747954 100644 --- a/packages/lockfile-file/test/read.test.ts +++ b/packages/lockfile-file/test/read.test.ts @@ -1,4 +1,5 @@ import path from 'path' +import { getCurrentBranchName } from './utils/mockGitChecks' import { existsWantedLockfile, readCurrentLockfile, @@ -190,3 +191,29 @@ test('existsWantedLockfile()', async () => { }) expect(await existsWantedLockfile(projectPath)).toBe(true) }) + +test('readWantedLockfile() when useGitBranchLockfile', async () => { + getCurrentBranchName.mockReturnValue('branch') + const lockfile = await readWantedLockfile(path.join('fixtures', '6'), { + ignoreIncompatible: false, + }) + expect(lockfile?.importers).toEqual({ + '.': { + specifiers: { + foo: '1', + }, + }, + }) + + const gitBranchLockfile = await readWantedLockfile(path.join('fixtures', '6'), { + ignoreIncompatible: false, + useGitBranchLockfile: true, + }) + expect(gitBranchLockfile?.importers).toEqual({ + '.': { + specifiers: { + foo: '2', + }, + }, + }) +}) \ No newline at end of file diff --git a/packages/lockfile-file/test/utils/mockGitChecks.ts b/packages/lockfile-file/test/utils/mockGitChecks.ts new file mode 100644 index 00000000000..d4572c36837 --- /dev/null +++ b/packages/lockfile-file/test/utils/mockGitChecks.ts @@ -0,0 +1,15 @@ +/** + * Mock git checks + */ +const getCurrentBranchName = jest.fn() +jest.mock('@pnpm/lockfile-file/lib/gitChecks', () => { + const original = jest.requireActual('@pnpm/lockfile-file/lib/gitChecks') + return { + ...original, + getCurrentBranchName, + } +}) + +export { + getCurrentBranchName, +} \ No newline at end of file diff --git a/packages/lockfile-file/test/write.test.ts b/packages/lockfile-file/test/write.test.ts index 4b256fec55b..9427bc2cf61 100644 --- a/packages/lockfile-file/test/write.test.ts +++ b/packages/lockfile-file/test/write.test.ts @@ -1,5 +1,6 @@ import fs from 'fs' import path from 'path' +import { getCurrentBranchName } from './utils/mockGitChecks' import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants' import { readCurrentLockfile, @@ -191,3 +192,39 @@ test('writeLockfiles() does not fail if the lockfile has undefined properties', wantedLockfileDir: projectPath, }) }) + +test('writeLockfiles() when useGitBranchLockfile', async () => { + const branchName: string = 'branch' + getCurrentBranchName.mockReturnValue(branchName) + const projectPath = tempy.directory() + const wantedLockfile = { + importers: { + '.': { + dependencies: { + foo: '1.0.0', + }, + specifiers: { + foo: '^1.0.0', + }, + }, + }, + lockfileVersion: LOCKFILE_VERSION, + packages: { + '/foo/1.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=', + }, + }, + }, + } + + await writeLockfiles({ + currentLockfile: wantedLockfile, + currentLockfileDir: projectPath, + wantedLockfile, + wantedLockfileDir: projectPath, + useGitBranchLockfile: true, + }) + expect(fs.existsSync(path.join(projectPath, WANTED_LOCKFILE))).toBeFalsy() + expect(fs.existsSync(path.join(projectPath, `pnpm-lock.${branchName}.yaml`))).toBeTruthy() +}) \ No newline at end of file diff --git a/privatePackages/assert-project/src/index.ts b/privatePackages/assert-project/src/index.ts index 92e0b8ada0f..1958b4442ca 100644 --- a/privatePackages/assert-project/src/index.ts +++ b/privatePackages/assert-project/src/index.ts @@ -39,7 +39,7 @@ export interface Project { * * https://github.com/microsoft/TypeScript/pull/32695 might help with this. */ - readLockfile: () => Promise> + readLockfile: (lockfileName?: string) => Promise> writePackageJson: (pkgJson: object) => Promise } @@ -143,9 +143,9 @@ export default (projectPath: string, encodedRegistryName?: string): Project => { } }, readModulesManifest: async () => readModules(modules), - async readLockfile () { + async readLockfile (lockfileName: string = WANTED_LOCKFILE) { try { - return await readYamlFile(path.join(projectPath, WANTED_LOCKFILE)) // eslint-disable-line + return await readYamlFile(path.join(projectPath, lockfileName)) // eslint-disable-line } catch (err: any) { // eslint-disable-line if (err.code === 'ENOENT') return null! throw err From bb014fa2c43e6d6c7b50857690bfe7ba04062ac4 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 26 Mar 2022 16:09:14 +0800 Subject: [PATCH 05/25] chore: syntax tweak accoding to code review --- packages/lockfile-file/src/read.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index a1255c10bda..e286da063c6 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -46,11 +46,11 @@ export async function readWantedLockfileAndAutofixConflicts ( if (opts.useGitBranchLockfile) { const lockfilePath = path.join(pkgPath, getWantedLockfileName(opts)) result = await _read(lockfilePath, pkgPath, { ...opts, autofixMergeConflicts: true }) + if (result.lockfile) { + return result + } } - if (!result.lockfile) { - result = await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, { ...opts, autofixMergeConflicts: true }) - } - return result + return await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, { ...opts, autofixMergeConflicts: true }) } export async function readWantedLockfile ( @@ -65,11 +65,11 @@ export async function readWantedLockfile ( if (opts.useGitBranchLockfile) { const lockfilePath = path.join(pkgPath, getWantedLockfileName(opts)) lockfile = (await _read(lockfilePath, pkgPath, opts)).lockfile + if (lockfile) { + return lockfile + } } - if (!lockfile) { - lockfile = (await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, opts)).lockfile - } - return lockfile + return (await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, opts)).lockfile } async function _read ( From bfb8a6772d28bb34e58b3addd095e76db8a9f50e Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 26 Mar 2022 15:40:24 +0800 Subject: [PATCH 06/25] refactor: extract git checks to a package @pnpm/git-utils --- .../test/install/gitBranchLockfile.test.ts | 8 ++-- packages/git-utils/README.md | 32 +++++++++++++ packages/git-utils/example.js | 8 ++++ packages/git-utils/jest.config.js | 1 + packages/git-utils/package.json | 45 +++++++++++++++++++ .../gitChecks.ts => git-utils/src/index.ts} | 0 packages/git-utils/test/utils/mock.ts | 28 ++++++++++++ packages/git-utils/tsconfig.json | 13 ++++++ packages/git-utils/tsconfig.lint.json | 8 ++++ packages/lockfile-file/package.json | 1 + .../lockfile-file/src/existsWantedLockfile.ts | 28 ++++++------ packages/lockfile-file/src/gitChecks.ts | 6 --- packages/lockfile-file/src/lockfileName.ts | 13 +++--- packages/lockfile-file/src/read.ts | 6 +-- packages/lockfile-file/src/write.ts | 4 +- .../lockfile-file/test/lockfileName.test.ts | 25 ++++++----- packages/lockfile-file/test/read.test.ts | 4 +- .../lockfile-file/test/utils/mockGitChecks.ts | 15 ------- packages/lockfile-file/test/write.test.ts | 4 +- packages/lockfile-file/tsconfig.json | 3 ++ .../plugin-commands-publishing/package.json | 1 + .../plugin-commands-publishing/src/publish.ts | 2 +- .../plugin-commands-publishing/tsconfig.json | 3 ++ packages/pnpm/package.json | 1 + packages/pnpm/tsconfig.json | 2 +- pnpm-lock.yaml | 45 ++++++++++++------- 26 files changed, 226 insertions(+), 80 deletions(-) create mode 100644 packages/git-utils/README.md create mode 100644 packages/git-utils/example.js create mode 100644 packages/git-utils/jest.config.js create mode 100644 packages/git-utils/package.json rename packages/{plugin-commands-publishing/src/gitChecks.ts => git-utils/src/index.ts} (100%) create mode 100644 packages/git-utils/test/utils/mock.ts create mode 100644 packages/git-utils/tsconfig.json create mode 100644 packages/git-utils/tsconfig.lint.json delete mode 100644 packages/lockfile-file/src/gitChecks.ts delete mode 100644 packages/lockfile-file/test/utils/mockGitChecks.ts diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts index 414974c0611..ac9de982e8e 100644 --- a/packages/core/test/install/gitBranchLockfile.test.ts +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -1,6 +1,6 @@ import fs from 'fs' import path from 'path' -import { getCurrentBranchName } from '@pnpm/lockfile-file/test/utils/mockGitChecks' +import { getCurrentBranch } from '@pnpm/git-utils/test/index' import { prepareEmpty, preparePackages } from '@pnpm/prepare' import { install, mutateModules } from '@pnpm/core' import { testDefaults } from '../utils' @@ -12,7 +12,7 @@ test('install with git-branch-lockfile = true', async () => { const project = prepareEmpty() const branchName: string = 'main-branch' - getCurrentBranchName.mockReturnValue(branchName) + getCurrentBranch.mockReturnValue(branchName) const opts = await testDefaults({ useGitBranchLockfile: true, @@ -57,7 +57,7 @@ test('install a workspace with git-branch-lockfile = true', async () => { ]) const branchName: string = 'main-branch' - getCurrentBranchName.mockReturnValue(branchName) + getCurrentBranch.mockReturnValue(branchName) const opts = await testDefaults({ useGitBranchLockfile: true, @@ -93,7 +93,7 @@ test('install with --clean-git-branch-lockfiles', async () => { prepareEmpty() const branchName: string = 'main-branch' - getCurrentBranchName.mockReturnValue(branchName) + getCurrentBranch.mockReturnValue(branchName) const otherLockfilePath: string = path.resolve('pnpm-lock.other.yaml') const mainLockfilePath: string = path.resolve(WANTED_LOCKFILE) diff --git a/packages/git-utils/README.md b/packages/git-utils/README.md new file mode 100644 index 00000000000..7ccb1016902 --- /dev/null +++ b/packages/git-utils/README.md @@ -0,0 +1,32 @@ +# @pnpm/git-utils + +> Utilities for git + + +[![npm version](https://img.shields.io/npm/v/@pnpm/git-utils.svg)](https://www.npmjs.com/package/@pnpm/git-utils) + + +## Installation + +``` +pnpm add @pnpm/git-utils +``` + +## Usage + + +```js +'use strict' +const { getCurrentBranchName } = require('@pnpm-utils').default + +main() +async function main() { + const branchName = await getCurrentBranch(); + console.log(branchName) +} +``` + + +# License + +MIT \ No newline at end of file diff --git a/packages/git-utils/example.js b/packages/git-utils/example.js new file mode 100644 index 00000000000..9b5ad529457 --- /dev/null +++ b/packages/git-utils/example.js @@ -0,0 +1,8 @@ +'use strict' +const { getCurrentBranch } = require('@pnpm-utils').default + +main() +async function main() { + const branchName = await getCurrentBranch(); + console.log(branchName) +} diff --git a/packages/git-utils/jest.config.js b/packages/git-utils/jest.config.js new file mode 100644 index 00000000000..f697d831691 --- /dev/null +++ b/packages/git-utils/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js') diff --git a/packages/git-utils/package.json b/packages/git-utils/package.json new file mode 100644 index 00000000000..235f3099484 --- /dev/null +++ b/packages/git-utils/package.json @@ -0,0 +1,45 @@ +{ + "name": "@pnpm/git-utils", + "version": "0.0.0", + "description": "Utilities for git", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib", + "!*.map" + ], + "engines": { + "node": ">=14.19" + }, + "scripts": { + "lint": "eslint src/**/*.ts test/**/*.ts", + "_test": "jest", + "test": "pnpm run compile && pnpm run _test", + "prepublishOnly": "pnpm run compile", + "fix": "tslint -c tslint.json src/**/*.ts test/**/*.ts --fix", + "compile-only": "tsc --build", + "compile": "tsc --build && pnpm run lint --fix" + }, + "repository": "https://github.com/pnpm/pnpm/blob/main/packages/git-utils", + "keywords": [ + "pnpm7", + "pnpm", + "git", + "npm" + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/pnpm/pnpm/issues" + }, + "homepage": "https://github.com/pnpm/pnpm/blob/main/packages/git-utils#readme", + "dependencies": { + "execa": "npm:safe-execa@^0.1.1" + }, + "devDependencies": { + "@pnpm/git-utils": "workspace:0.0.0" + }, + "funding": "https://opencollective.com/pnpm", + "exports": { + ".": "./lib/index.js" + } +} diff --git a/packages/plugin-commands-publishing/src/gitChecks.ts b/packages/git-utils/src/index.ts similarity index 100% rename from packages/plugin-commands-publishing/src/gitChecks.ts rename to packages/git-utils/src/index.ts diff --git a/packages/git-utils/test/utils/mock.ts b/packages/git-utils/test/utils/mock.ts new file mode 100644 index 00000000000..96a07880d6d --- /dev/null +++ b/packages/git-utils/test/utils/mock.ts @@ -0,0 +1,28 @@ +/** + * Mock git utils + */ + +const originalAPI = jest.requireActual('@pnpm/git-utils') + +const isGitRepo = jest.fn().mockImplementationOnce(originalAPI.isGitRepo) +const getCurrentBranch = jest.fn().mockImplementation(originalAPI.getCurrentBranch) +const isWorkingTreeClean = jest.fn().mockImplementationOnce(originalAPI.isWorkingTreeClean) +const isRemoteHistoryClean = jest.fn().mockImplementation(originalAPI.isRemoteHistoryClean) + +jest.mock('@pnpm/git-utils', () => { + return { + ...originalAPI, + isGitRepo, + getCurrentBranch, + isWorkingTreeClean, + isRemoteHistoryClean, + } +}) + +export { + isGitRepo, + getCurrentBranch, + isWorkingTreeClean, + isRemoteHistoryClean, + originalAPI, +} \ No newline at end of file diff --git a/packages/git-utils/tsconfig.json b/packages/git-utils/tsconfig.json new file mode 100644 index 00000000000..f798b65d3a5 --- /dev/null +++ b/packages/git-utils/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "@pnpm/tsconfig", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "include": [ + "src/**/*.ts", + "../../typings/**/*.d.ts" + ], + "references": [ + ] +} diff --git a/packages/git-utils/tsconfig.lint.json b/packages/git-utils/tsconfig.lint.json new file mode 100644 index 00000000000..0dc5add6b7b --- /dev/null +++ b/packages/git-utils/tsconfig.lint.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "src/**/*.ts", + "test/**/*.ts", + "../../typings/**/*.d.ts" + ] +} diff --git a/packages/lockfile-file/package.json b/packages/lockfile-file/package.json index 7bdfac817a2..cfc83b6f709 100644 --- a/packages/lockfile-file/package.json +++ b/packages/lockfile-file/package.json @@ -48,6 +48,7 @@ "dependencies": { "@pnpm/constants": "workspace:6.0.0", "@pnpm/error": "workspace:3.0.0", + "@pnpm/git-utils": "workspace:0.0.0", "@pnpm/lockfile-types": "workspace:4.0.0", "@pnpm/merge-lockfile-changes": "workspace:3.0.0", "@pnpm/types": "workspace:8.0.0", diff --git a/packages/lockfile-file/src/existsWantedLockfile.ts b/packages/lockfile-file/src/existsWantedLockfile.ts index 7b5b3f1233d..613eb15c0fd 100644 --- a/packages/lockfile-file/src/existsWantedLockfile.ts +++ b/packages/lockfile-file/src/existsWantedLockfile.ts @@ -8,17 +8,19 @@ interface ExistsWantedLockfileOptions { export default async (pkgPath: string, opts: ExistsWantedLockfileOptions = { useGitBranchLockfile: false, -}) => new Promise((resolve, reject) => { - const wantedLockfile: string = getWantedLockfileName(opts) - fs.access(path.join(pkgPath, wantedLockfile), (err) => { - if (err == null) { - resolve(true) - return - } - if (err.code === 'ENOENT') { - resolve(false) - return - } - reject(err) +}) => { + const wantedLockfile: string = await getWantedLockfileName(opts) + return new Promise((resolve, reject) => { + fs.access(path.join(pkgPath, wantedLockfile), (err) => { + if (err == null) { + resolve(true) + return + } + if (err.code === 'ENOENT') { + resolve(false) + return + } + reject(err) + }) }) -}) +} diff --git a/packages/lockfile-file/src/gitChecks.ts b/packages/lockfile-file/src/gitChecks.ts deleted file mode 100644 index d23c24dd89d..00000000000 --- a/packages/lockfile-file/src/gitChecks.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { spawnSync } from 'child_process' - -export function getCurrentBranchName () { - const { stdout } = spawnSync('git', ['symbolic-ref', '--short', 'HEAD'], { encoding: 'utf8' }) - return String(stdout).trim() -} \ No newline at end of file diff --git a/packages/lockfile-file/src/lockfileName.ts b/packages/lockfile-file/src/lockfileName.ts index c0fba3540ac..cde7ec32d88 100644 --- a/packages/lockfile-file/src/lockfileName.ts +++ b/packages/lockfile-file/src/lockfileName.ts @@ -1,13 +1,13 @@ import { WANTED_LOCKFILE } from '@pnpm/constants' -import { getCurrentBranchName } from './gitChecks' +import { getCurrentBranch } from '@pnpm/git-utils' export interface GetWantedLockfileNameOptions { useGitBranchLockfile?: boolean } -export function getWantedLockfileName (opts: GetWantedLockfileNameOptions = { useGitBranchLockfile: false }) { +export async function getWantedLockfileName (opts: GetWantedLockfileNameOptions = { useGitBranchLockfile: false }) { if (opts.useGitBranchLockfile) { - const currentBranchName = getCurrentBranchName() + const currentBranchName = await getCurrentBranch() if (currentBranchName) { return WANTED_LOCKFILE.replace('.yaml', `.${stringifyBranchName(currentBranchName)}.yaml`) } @@ -15,7 +15,10 @@ export function getWantedLockfileName (opts: GetWantedLockfileNameOptions = { us return WANTED_LOCKFILE } -// branch name may contains slashes, which is not allowed in filenames +/** + * 1. Git branch name may contains slashes, which is not allowed in filenames + * 2. Filesystem may be case-insensitive, so we need to convert branch name to lowercase + */ function stringifyBranchName (branchName: string = '') { - return branchName.replace(/[^a-zA-Z0-9-_.]/g, '!') + return branchName.replace(/[^a-zA-Z0-9-_.]/g, '!').toLowerCase() } \ No newline at end of file diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index e286da063c6..8a6e3e36e76 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -44,13 +44,13 @@ export async function readWantedLockfileAndAutofixConflicts ( hadConflicts: false, } if (opts.useGitBranchLockfile) { - const lockfilePath = path.join(pkgPath, getWantedLockfileName(opts)) + const lockfilePath = path.join(pkgPath, await getWantedLockfileName(opts)) result = await _read(lockfilePath, pkgPath, { ...opts, autofixMergeConflicts: true }) if (result.lockfile) { return result } } - return await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, { ...opts, autofixMergeConflicts: true }) + return _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, { ...opts, autofixMergeConflicts: true }) } export async function readWantedLockfile ( @@ -63,7 +63,7 @@ export async function readWantedLockfile ( ): Promise { let lockfile: Lockfile | null = null if (opts.useGitBranchLockfile) { - const lockfilePath = path.join(pkgPath, getWantedLockfileName(opts)) + const lockfilePath = path.join(pkgPath, await getWantedLockfileName(opts)) lockfile = (await _read(lockfilePath, pkgPath, opts)).lockfile if (lockfile) { return lockfile diff --git a/packages/lockfile-file/src/write.ts b/packages/lockfile-file/src/write.ts index cdb0c948105..40a9926a016 100644 --- a/packages/lockfile-file/src/write.ts +++ b/packages/lockfile-file/src/write.ts @@ -32,7 +32,7 @@ export async function writeWantedLockfile ( useGitBranchLockfile?: boolean } ) { - const wantedLockfileName: string = getWantedLockfileName(opts) + const wantedLockfileName: string = await getWantedLockfileName(opts) return writeLockfile(wantedLockfileName, pkgPath, wantedLockfile, opts) } @@ -148,7 +148,7 @@ export default async function writeLockfiles ( useGitBranchLockfile?: boolean } ) { - const wantedLockfileName: string = getWantedLockfileName(opts) + const wantedLockfileName: string = await getWantedLockfileName(opts) const wantedLockfilePath = path.join(opts.wantedLockfileDir, wantedLockfileName) const currentLockfilePath = path.join(opts.currentLockfileDir, 'lock.yaml') diff --git a/packages/lockfile-file/test/lockfileName.test.ts b/packages/lockfile-file/test/lockfileName.test.ts index ebb4464af2e..51f7a448569 100644 --- a/packages/lockfile-file/test/lockfileName.test.ts +++ b/packages/lockfile-file/test/lockfileName.test.ts @@ -1,23 +1,28 @@ -import { getCurrentBranchName } from './utils/mockGitChecks' +import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { WANTED_LOCKFILE } from '@pnpm/constants' import { getWantedLockfileName } from '@pnpm/lockfile-file/lib/lockfileName' describe('lockfileName', () => { afterEach(() => { - getCurrentBranchName.mockReset() + getCurrentBranch.mockReset() }) - test('returns default lockfile name if useGitBranchLockfile is off', () => { - expect(getWantedLockfileName()).toBe(WANTED_LOCKFILE) + test('returns default lockfile name if useGitBranchLockfile is off', async () => { + await expect(getWantedLockfileName()).resolves.toBe(WANTED_LOCKFILE) }) - test('returns git branch lockfile name', () => { - getCurrentBranchName.mockReturnValue('main') - expect(getWantedLockfileName({ useGitBranchLockfile: true })).toBe('pnpm-lock.main.yaml') + test('returns git branch lockfile name', async () => { + getCurrentBranch.mockReturnValue('main') + await expect(getWantedLockfileName({ useGitBranchLockfile: true })).resolves.toBe('pnpm-lock.main.yaml') }) - test('returns git branch lockfile name when git branch contains clashes', () => { - getCurrentBranchName.mockReturnValue('a/b/c') - expect(getWantedLockfileName({ useGitBranchLockfile: true })).toBe('pnpm-lock.a!b!c.yaml') + test('returns git branch lockfile name when git branch contains clashes', async () => { + getCurrentBranch.mockReturnValue('a/b/c') + await expect(getWantedLockfileName({ useGitBranchLockfile: true })).resolves.toBe('pnpm-lock.a!b!c.yaml') + }) + + test('returns git branch lockfile name when git branch contains uppercase', async () => { + getCurrentBranch.mockReturnValue('aBc') + await expect(getWantedLockfileName({ useGitBranchLockfile: true })).resolves.toBe('pnpm-lock.abc.yaml') }) }) diff --git a/packages/lockfile-file/test/read.test.ts b/packages/lockfile-file/test/read.test.ts index 0d86d747954..4f728423b27 100644 --- a/packages/lockfile-file/test/read.test.ts +++ b/packages/lockfile-file/test/read.test.ts @@ -1,5 +1,5 @@ import path from 'path' -import { getCurrentBranchName } from './utils/mockGitChecks' +import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { existsWantedLockfile, readCurrentLockfile, @@ -193,7 +193,7 @@ test('existsWantedLockfile()', async () => { }) test('readWantedLockfile() when useGitBranchLockfile', async () => { - getCurrentBranchName.mockReturnValue('branch') + getCurrentBranch.mockReturnValue('branch') const lockfile = await readWantedLockfile(path.join('fixtures', '6'), { ignoreIncompatible: false, }) diff --git a/packages/lockfile-file/test/utils/mockGitChecks.ts b/packages/lockfile-file/test/utils/mockGitChecks.ts deleted file mode 100644 index d4572c36837..00000000000 --- a/packages/lockfile-file/test/utils/mockGitChecks.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Mock git checks - */ -const getCurrentBranchName = jest.fn() -jest.mock('@pnpm/lockfile-file/lib/gitChecks', () => { - const original = jest.requireActual('@pnpm/lockfile-file/lib/gitChecks') - return { - ...original, - getCurrentBranchName, - } -}) - -export { - getCurrentBranchName, -} \ No newline at end of file diff --git a/packages/lockfile-file/test/write.test.ts b/packages/lockfile-file/test/write.test.ts index 9427bc2cf61..727652f7d77 100644 --- a/packages/lockfile-file/test/write.test.ts +++ b/packages/lockfile-file/test/write.test.ts @@ -1,6 +1,6 @@ import fs from 'fs' import path from 'path' -import { getCurrentBranchName } from './utils/mockGitChecks' +import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants' import { readCurrentLockfile, @@ -195,7 +195,7 @@ test('writeLockfiles() does not fail if the lockfile has undefined properties', test('writeLockfiles() when useGitBranchLockfile', async () => { const branchName: string = 'branch' - getCurrentBranchName.mockReturnValue(branchName) + getCurrentBranch.mockReturnValue(branchName) const projectPath = tempy.directory() const wantedLockfile = { importers: { diff --git a/packages/lockfile-file/tsconfig.json b/packages/lockfile-file/tsconfig.json index 54d74c76715..2099aac3f79 100644 --- a/packages/lockfile-file/tsconfig.json +++ b/packages/lockfile-file/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../error" }, + { + "path": "../git-utils" + }, { "path": "../lockfile-types" }, diff --git a/packages/plugin-commands-publishing/package.json b/packages/plugin-commands-publishing/package.json index f9109cec7b2..ae7fd904fd1 100644 --- a/packages/plugin-commands-publishing/package.json +++ b/packages/plugin-commands-publishing/package.json @@ -64,6 +64,7 @@ "@pnpm/config": "workspace:14.0.0", "@pnpm/error": "workspace:3.0.0", "@pnpm/exportable-manifest": "workspace:3.0.0", + "@pnpm/git-utils": "workspace:0.0.0", "@pnpm/lifecycle": "workspace:13.0.0", "@pnpm/package-bins": "workspace:6.0.0", "@pnpm/pick-registry-for-package": "workspace:3.0.0", diff --git a/packages/plugin-commands-publishing/src/publish.ts b/packages/plugin-commands-publishing/src/publish.ts index 282a438472d..338d0d9fb1f 100644 --- a/packages/plugin-commands-publishing/src/publish.ts +++ b/packages/plugin-commands-publishing/src/publish.ts @@ -6,6 +6,7 @@ import PnpmError from '@pnpm/error' import runLifecycleHooks, { RunLifecycleHookOptions } from '@pnpm/lifecycle' import runNpm from '@pnpm/run-npm' import { ProjectManifest } from '@pnpm/types' +import { getCurrentBranch, isGitRepo, isRemoteHistoryClean, isWorkingTreeClean } from '@pnpm/git-utils' import { prompt } from 'enquirer' import rimraf from '@zkochan/rimraf' import pick from 'ramda/src/pick' @@ -13,7 +14,6 @@ import realpathMissing from 'realpath-missing' import renderHelp from 'render-help' import * as pack from './pack' import recursivePublish, { PublishRecursiveOpts } from './recursivePublish' -import { getCurrentBranch, isGitRepo, isRemoteHistoryClean, isWorkingTreeClean } from './gitChecks' export function rcOptionsTypes () { return pick([ diff --git a/packages/plugin-commands-publishing/tsconfig.json b/packages/plugin-commands-publishing/tsconfig.json index cba3c3334e2..c061f19b6cd 100644 --- a/packages/plugin-commands-publishing/tsconfig.json +++ b/packages/plugin-commands-publishing/tsconfig.json @@ -30,6 +30,9 @@ { "path": "../filter-workspace-packages" }, + { + "path": "../git-utils" + }, { "path": "../lifecycle" }, diff --git a/packages/pnpm/package.json b/packages/pnpm/package.json index 6909be81e4a..e52a1154c86 100644 --- a/packages/pnpm/package.json +++ b/packages/pnpm/package.json @@ -158,6 +158,7 @@ "test": "pnpm run compile && pnpm run _test", "prepublishOnly": "pnpm compile && npm cache clear --force && publish-packed --prune --npm-client=pnpm --dest=dist", "postpublish": "publish-packed", + "_compile": "tsc --build", "compile": "tsc --build && pnpm run lint --fix && rimraf dist bin/nodes && pnpm run bundle && shx cp -r node-gyp-bin dist/node-gyp-bin && shx cp -r node_modules/@pnpm/tabtab/lib/scripts dist/scripts && shx cp -r node_modules/ps-list/vendor dist/vendor && shx cp pnpmrc dist/pnpmrc" }, "publishConfig": { diff --git a/packages/pnpm/tsconfig.json b/packages/pnpm/tsconfig.json index da152edddcf..5f6efd2034a 100644 --- a/packages/pnpm/tsconfig.json +++ b/packages/pnpm/tsconfig.json @@ -4,7 +4,7 @@ "composite": false, "declaration": false, "outDir": "lib", - "sourceMap": false, + "sourceMap": true, "rootDir": "src" }, "include": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69bd2e1befd..d210d1d78f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1033,6 +1033,15 @@ importers: '@types/semver': 7.3.9 is-windows: 1.0.2 + packages/git-utils: + specifiers: + '@pnpm/git-utils': workspace:0.0.0 + execa: npm:safe-execa@^0.1.1 + dependencies: + execa: /safe-execa/0.1.1 + devDependencies: + '@pnpm/git-utils': 'link:' + packages/graceful-fs: specifiers: '@pnpm/graceful-fs': workspace:2.0.0 @@ -1332,6 +1341,7 @@ importers: specifiers: '@pnpm/constants': workspace:6.0.0 '@pnpm/error': workspace:3.0.0 + '@pnpm/git-utils': workspace:0.0.0 '@pnpm/lockfile-file': workspace:5.0.0 '@pnpm/lockfile-types': workspace:4.0.0 '@pnpm/logger': ^4.0.0 @@ -1357,6 +1367,7 @@ importers: dependencies: '@pnpm/constants': link:../constants '@pnpm/error': link:../error + '@pnpm/git-utils': link:../git-utils '@pnpm/lockfile-types': link:../lockfile-types '@pnpm/merge-lockfile-changes': link:../merge-lockfile-changes '@pnpm/types': link:../types @@ -2392,6 +2403,7 @@ importers: '@pnpm/error': workspace:3.0.0 '@pnpm/exportable-manifest': workspace:3.0.0 '@pnpm/filter-workspace-packages': workspace:5.0.0 + '@pnpm/git-utils': workspace:0.0.0 '@pnpm/lifecycle': workspace:13.0.0 '@pnpm/logger': ^4.0.0 '@pnpm/package-bins': workspace:6.0.0 @@ -2437,6 +2449,7 @@ importers: '@pnpm/config': link:../config '@pnpm/error': link:../error '@pnpm/exportable-manifest': link:../exportable-manifest + '@pnpm/git-utils': link:../git-utils '@pnpm/lifecycle': link:../lifecycle '@pnpm/package-bins': link:../package-bins '@pnpm/pick-registry-for-package': link:../pick-registry-for-package @@ -5605,7 +5618,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 - eslint: '*' + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || * typescript: '*' peerDependenciesMeta: typescript: @@ -5631,7 +5644,7 @@ packages: resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: - eslint: '*' + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 || * typescript: '*' peerDependenciesMeta: typescript: @@ -5651,7 +5664,7 @@ packages: resolution: {integrity: sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - eslint: '*' + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || * typescript: '*' peerDependenciesMeta: typescript: @@ -5758,7 +5771,7 @@ packages: resolution: {integrity: sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - eslint: '*' + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || * dependencies: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 5.17.0 @@ -5987,7 +6000,7 @@ packages: lru-cache: 6.0.0 /@zkochan/istanbul-reports/3.0.2: - resolution: {integrity: sha512-GeZZ9YNlvveT1CrMqe64s9+5hNF5p9Gj6J+PRQU3OnBS/9c2y5kSFavUZ9YAuoAgxFW8tKGKWIxJK4I6HBSigg==} + resolution: {integrity: sha1-WkGKLJfewBd0WgUWuLSaie8jGys=} engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 @@ -6312,7 +6325,7 @@ packages: sprintf-js: 1.0.3 /argparse/2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: {integrity: sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=} /arr-diff/4.0.0: resolution: {integrity: sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=} @@ -8231,7 +8244,7 @@ packages: resolution: {integrity: sha512-FeiMHljEJ346Y0I/HpAymNKdrgKEpHpcg/D93FvPHWfCzbT4QyUJba/0FwntZeGLXfUiWDSeKmdJD597d9wwiw==} peerDependencies: '@typescript-eslint/eslint-plugin': ^4.0.1 || ^5.6.0 - eslint: '*' + eslint: ^7.12.1 || * eslint-plugin-import: ^2.22.1 eslint-plugin-node: ^11.1.0 eslint-plugin-promise: ^4.2.1 || ^5.0.0 @@ -8252,7 +8265,7 @@ packages: /eslint-config-standard/16.0.3_930f3be8c6a4d79109eacdcf5d7c3aa5: resolution: {integrity: sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==} peerDependencies: - eslint: '*' + eslint: ^7.12.1 || * eslint-plugin-import: ^2.22.1 eslint-plugin-node: ^11.1.0 eslint-plugin-promise: ^4.2.1 || ^5.0.0 @@ -8281,7 +8294,7 @@ packages: resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: - eslint: '*' + eslint: '>=4.19.1 || *' dependencies: eslint: 8.12.0 eslint-utils: 2.1.0 @@ -8292,7 +8305,7 @@ packages: resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} engines: {node: '>=4'} peerDependencies: - eslint: '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || * dependencies: array-includes: 3.1.4 array.prototype.flat: 1.2.5 @@ -8314,7 +8327,7 @@ packages: resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: - eslint: '*' + eslint: '>=5.16.0 || *' dependencies: eslint: 8.12.0 eslint-plugin-es: 3.0.1_eslint@8.12.0 @@ -8329,7 +8342,7 @@ packages: resolution: {integrity: sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: - eslint: '*' + eslint: ^7.0.0 || * dependencies: eslint: 8.12.0 dev: false @@ -8360,7 +8373,7 @@ packages: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: - eslint: '*' + eslint: '>=5 || * || *' dependencies: eslint: 8.12.0 eslint-visitor-keys: 2.1.0 @@ -8996,7 +9009,7 @@ packages: resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + resolution: {integrity: sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -9010,7 +9023,7 @@ packages: resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} /fuse-native/2.2.6: - resolution: {integrity: sha512-Y5wXd7vUsWWWIIHbjluv7jKZgPZaSVA5YWaW3I5fXIJfcGWL6IRUgoBUveQAq+D8cG9cCiGNahv9CeToccCXrw==} + resolution: {integrity: sha1-UXIk3hFY2az6tGXjW0Stnp0wjFY=} hasBin: true requiresBuild: true dependencies: @@ -9435,7 +9448,7 @@ packages: dev: true /html-escaper/2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + resolution: {integrity: sha1-39YAJ9o2o238viNiYsAKWCJoFFM=} dev: true /http-cache-semantics/4.1.0: From 01bc5f9d3a9a95ea41f3f097ce0d4eb50ec9609d Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 26 Mar 2022 16:52:58 +0800 Subject: [PATCH 07/25] test: git-utils --- packages/git-utils/package.json | 3 ++- packages/git-utils/test/index.test.ts | 39 +++++++++++++++++++++++++++ pnpm-lock.yaml | 12 +++++---- 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 packages/git-utils/test/index.test.ts diff --git a/packages/git-utils/package.json b/packages/git-utils/package.json index 235f3099484..a6156071489 100644 --- a/packages/git-utils/package.json +++ b/packages/git-utils/package.json @@ -36,7 +36,8 @@ "execa": "npm:safe-execa@^0.1.1" }, "devDependencies": { - "@pnpm/git-utils": "workspace:0.0.0" + "@pnpm/git-utils": "workspace:0.0.0", + "tempy": "^1.0.0" }, "funding": "https://opencollective.com/pnpm", "exports": { diff --git a/packages/git-utils/test/index.test.ts b/packages/git-utils/test/index.test.ts new file mode 100644 index 00000000000..dba8c3b52ef --- /dev/null +++ b/packages/git-utils/test/index.test.ts @@ -0,0 +1,39 @@ +import tempy from 'tempy' +import execa from 'execa' +import { promises as fs } from 'fs' +import path from 'path' +import { getCurrentBranch, isGitRepo, isWorkingTreeClean } from '@pnpm/git-utils' + +test('isGitRepo', async () => { + const tempDir = tempy.directory() + process.chdir(tempDir) + + await expect(isGitRepo()).resolves.toBe(false) + + await execa('git', ['init']) + + await expect(isGitRepo()).resolves.toBe(true) +}) + +test('getCurrentBranch', async () => { + const tempDir = tempy.directory() + process.chdir(tempDir) + + await execa('git', ['init']) + await execa('git', ['checkout', '-b', 'foo']) + + await expect(getCurrentBranch()).resolves.toBe('foo') +}) + +test('isWorkingTreeClean', async () => { + const tempDir = tempy.directory() + process.chdir(tempDir) + + await execa('git', ['init']) + + await expect(isWorkingTreeClean()).resolves.toBe(true) + + await fs.writeFile(path.join(tempDir, 'foo'), 'foo') + + await expect(isWorkingTreeClean()).resolves.toBe(false) +}) \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d210d1d78f6..86230006a3c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1037,10 +1037,12 @@ importers: specifiers: '@pnpm/git-utils': workspace:0.0.0 execa: npm:safe-execa@^0.1.1 + tempy: ^1.0.0 dependencies: execa: /safe-execa/0.1.1 devDependencies: '@pnpm/git-utils': 'link:' + tempy: 1.0.1 packages/graceful-fs: specifiers: @@ -6376,7 +6378,7 @@ packages: dev: true /array-union/2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + resolution: {integrity: sha1-t5hCCtvrHego2ErNii4j0+/oXo0=} engines: {node: '>=8'} /array-uniq/1.0.3: @@ -6653,7 +6655,7 @@ packages: wrap-ansi: 7.0.0 /brace-expansion/1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: {integrity: sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 @@ -9915,7 +9917,7 @@ packages: dev: true /is-path-cwd/2.2.0: - resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + resolution: {integrity: sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s=} engines: {node: '>=6'} /is-path-inside/3.0.3: @@ -11314,7 +11316,7 @@ packages: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} /merge2/1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + resolution: {integrity: sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=} engines: {node: '>= 8'} /methods/1.1.2: @@ -12309,7 +12311,7 @@ packages: dev: true /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + resolution: {integrity: sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=} engines: {node: '>=8'} /peek-stream/1.1.3: From ad8091d36c3e815c77f1ec0489d59fce89fd2885 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 26 Mar 2022 19:02:09 +0800 Subject: [PATCH 08/25] test: @pnpm/core test --- packages/core/package.json | 1 + packages/core/test/install/gitBranchLockfile.test.ts | 2 +- packages/core/tsconfig.json | 3 +++ pnpm-lock.yaml | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 4f707b1760a..d3ffc018722 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -22,6 +22,7 @@ "@pnpm/error": "workspace:3.0.0", "@pnpm/filter-lockfile": "workspace:6.0.0", "@pnpm/get-context": "workspace:6.0.0", + "@pnpm/git-utils": "workspace:0.0.0", "@pnpm/headless": "workspace:18.0.0", "@pnpm/hoist": "workspace:6.0.0", "@pnpm/lifecycle": "workspace:13.0.0", diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts index ac9de982e8e..3fb7880704c 100644 --- a/packages/core/test/install/gitBranchLockfile.test.ts +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -1,6 +1,6 @@ import fs from 'fs' import path from 'path' -import { getCurrentBranch } from '@pnpm/git-utils/test/index' +import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { prepareEmpty, preparePackages } from '@pnpm/prepare' import { install, mutateModules } from '@pnpm/core' import { testDefaults } from '../utils' diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index fbf40b54154..e0854a70158 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -51,6 +51,9 @@ { "path": "../get-context" }, + { + "path": "../git-utils" + }, { "path": "../headless" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86230006a3c..7506bc3628b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -399,6 +399,7 @@ importers: '@pnpm/error': workspace:3.0.0 '@pnpm/filter-lockfile': workspace:6.0.0 '@pnpm/get-context': workspace:6.0.0 + '@pnpm/git-utils': workspace:0.0.0 '@pnpm/graph-sequencer': 1.0.0 '@pnpm/headless': workspace:18.0.0 '@pnpm/hoist': workspace:6.0.0 @@ -475,6 +476,7 @@ importers: '@pnpm/error': link:../error '@pnpm/filter-lockfile': link:../filter-lockfile '@pnpm/get-context': link:../get-context + '@pnpm/git-utils': link:../git-utils '@pnpm/graph-sequencer': 1.0.0 '@pnpm/headless': link:../headless '@pnpm/hoist': link:../hoist From 7363a2d6ec4b83385324d433b2db627c3ac3b274 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 26 Mar 2022 21:37:43 +0800 Subject: [PATCH 09/25] refactor: clean-git-branch-lockfiles -> merge-git-branch-lockfiles --- packages/config/src/Config.ts | 2 +- packages/config/src/index.ts | 4 +- .../core/src/install/extendInstallOptions.ts | 4 +- packages/core/src/install/index.ts | 7 +- packages/core/src/link/index.ts | 2 +- packages/core/src/link/options.ts | 1 + .../test/install/gitBranchLockfile.test.ts | 5 +- packages/get-context/src/index.ts | 4 + packages/get-context/src/readLockfiles.ts | 2 + packages/headless/src/index.ts | 2 + .../src/cleanGitBranchLockfile.ts | 13 --- .../lockfile-file/src/existsWantedLockfile.ts | 2 + .../lockfile-file/src/gitBranchLockfile.ts | 18 ++++ packages/lockfile-file/src/index.ts | 2 - packages/lockfile-file/src/lockfileName.ts | 5 +- packages/lockfile-file/src/read.ts | 88 ++++++++++++++++--- packages/lockfile-file/src/write.ts | 18 +++- .../test/fixtures/6/otherFile.md | 0 .../test/fixtures/6/pnpm-lock.branch.yaml | 7 +- .../test/fixtures/6/pnpm-lock.yaml | 6 +- .../test/gitBranchLockfile.test.ts | 10 +++ packages/lockfile-file/test/read.test.ts | 46 +++++++++- .../src/install.ts | 6 +- .../storeStatus/extendStoreStatusOptions.ts | 2 - 24 files changed, 202 insertions(+), 54 deletions(-) delete mode 100644 packages/lockfile-file/src/cleanGitBranchLockfile.ts create mode 100644 packages/lockfile-file/src/gitBranchLockfile.ts create mode 100644 packages/lockfile-file/test/fixtures/6/otherFile.md create mode 100644 packages/lockfile-file/test/gitBranchLockfile.test.ts diff --git a/packages/config/src/Config.ts b/packages/config/src/Config.ts index 6818ac878f6..653424ea5a9 100644 --- a/packages/config/src/Config.ts +++ b/packages/config/src/Config.ts @@ -15,7 +15,6 @@ export interface Config { allowNew: boolean autoInstallPeers?: boolean bail: boolean - cleanGitBranchLockfiles?: boolean color: 'always' | 'auto' | 'never' cliOptions: Record, // eslint-disable-line useBetaCli: boolean @@ -132,6 +131,7 @@ export interface Config { sharedWorkspaceLockfile?: boolean useLockfile: boolean useGitBranchLockfile: boolean + mergeGitBranchLockfiles?: boolean globalPnpmfile?: string npmPath?: string gitChecks?: boolean diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 8ddae82e7bc..c5e179e5947 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -35,7 +35,7 @@ export const types = Object.assign({ bail: Boolean, 'cache-dir': String, 'child-concurrency': Number, - 'clean-git-branch-lockfiles': Boolean, + 'merge-git-branch-lockfiles': Boolean, color: ['always', 'auto', 'never'], 'config-dir': String, dev: [null, true], @@ -253,7 +253,7 @@ export default async ( return false })() pnpmConfig.useGitBranchLockfile = (() => { - if (!pnpmConfig.cleanGitBranchLockfiles && typeof pnpmConfig['gitBranchLockfile'] === 'boolean') return pnpmConfig['gitBranchLockfile'] + if (typeof pnpmConfig['gitBranchLockfile'] === 'boolean') return pnpmConfig['gitBranchLockfile'] return false })() pnpmConfig.pnpmHomeDir = getDataDir(process) diff --git a/packages/core/src/install/extendInstallOptions.ts b/packages/core/src/install/extendInstallOptions.ts index f2ea52c8704..a6148cf77fc 100644 --- a/packages/core/src/install/extendInstallOptions.ts +++ b/packages/core/src/install/extendInstallOptions.ts @@ -24,7 +24,7 @@ export interface StrictInstallOptions { hoistingLimits?: HoistingLimits useLockfile: boolean useGitBranchLockfile: boolean - cleanGitBranchLockfiles: boolean + mergeGitBranchLockfiles: boolean linkWorkspacePackagesDepth: number lockfileOnly: boolean fixLockfile: boolean @@ -165,7 +165,7 @@ const defaults = async (opts: InstallOptions) => { update: false, useLockfile: true, useGitBranchLockfile: false, - cleanGitBranchLockfiles: false, + mergeGitBranchLockfiles: false, userAgent: `${packageManager.name}/${packageManager.version} npm/? node/${process.version} ${process.platform} ${process.arch}`, verifyStoreIntegrity: true, workspacePackages: {}, diff --git a/packages/core/src/install/index.ts b/packages/core/src/install/index.ts index 522e1cf480f..f3a3e6f600a 100644 --- a/packages/core/src/install/index.ts +++ b/packages/core/src/install/index.ts @@ -25,7 +25,6 @@ import { writeCurrentLockfile, writeLockfiles, writeWantedLockfile, - cleanGitBranchLockfiles, } from '@pnpm/lockfile-file' import { writePnpFile } from '@pnpm/lockfile-to-pnp' import { extendProjectsWithTargetDirs } from '@pnpm/lockfile-utils' @@ -196,10 +195,6 @@ export async function mutateModules ( streamParser.removeListener('data', reporter) } - if (opts.cleanGitBranchLockfiles) { - await cleanGitBranchLockfiles(ctx.lockfileDir) - } - return result async function _install (): Promise { @@ -774,7 +769,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => { } const depsStateCache: DepsStateCache = {} - const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile, useGitBranchLockfile: opts.useGitBranchLockfile } + const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile, useGitBranchLockfile: opts.useGitBranchLockfile, mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles } if (!opts.lockfileOnly && opts.enableModulesDir) { const result = await linkPackages( projects, diff --git a/packages/core/src/link/index.ts b/packages/core/src/link/index.ts index 088bc8b05f0..291f855a6ed 100644 --- a/packages/core/src/link/index.ts +++ b/packages/core/src/link/index.ts @@ -157,7 +157,7 @@ export default async function link ( } else { newPkg = opts.manifest } - const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile, useGitBranchLockfile: opts.useGitBranchLockfile } + const lockfileOpts = { forceSharedFormat: opts.forceSharedLockfile, useGitBranchLockfile: opts.useGitBranchLockfile, mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles } if (opts.useLockfile) { await writeLockfiles({ currentLockfile: updatedCurrentLockfile, diff --git a/packages/core/src/link/options.ts b/packages/core/src/link/options.ts index 84d5fcb164b..201aed0939c 100644 --- a/packages/core/src/link/options.ts +++ b/packages/core/src/link/options.ts @@ -31,6 +31,7 @@ interface StrictLinkOptions { forcePublicHoistPattern: boolean useGitBranchLockfile: boolean + mergeGitBranchLockfiles: boolean } export type LinkOptions = diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts index 3fb7880704c..486bef09e81 100644 --- a/packages/core/test/install/gitBranchLockfile.test.ts +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -89,7 +89,7 @@ test('install a workspace with git-branch-lockfile = true', async () => { expect(fs.existsSync(path.join(lockfileDir, WANTED_LOCKFILE))).toBe(false) }) -test('install with --clean-git-branch-lockfiles', async () => { +test('install with --merge-git-branch-lockfiles', async () => { prepareEmpty() const branchName: string = 'main-branch' @@ -105,7 +105,8 @@ test('install with --clean-git-branch-lockfiles', async () => { expect(fs.existsSync(mainLockfilePath)).toBe(false) const opts = await testDefaults({ - cleanGitBranchLockfiles: true, + useGitBranchLockfile: true, + mergeGitBranchLockfiles: true, }) await install({ dependencies: { diff --git a/packages/get-context/src/index.ts b/packages/get-context/src/index.ts index e9f513eb1fd..fbe8dec3906 100644 --- a/packages/get-context/src/index.ts +++ b/packages/get-context/src/index.ts @@ -83,6 +83,7 @@ export interface GetContextOptions { storeDir: string useLockfile: boolean useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean virtualStoreDir?: string hoistPattern?: string[] | undefined @@ -178,6 +179,7 @@ export default async function getContext ( registry: opts.registries.default, useLockfile: opts.useLockfile, useGitBranchLockfile: opts.useGitBranchLockfile, + mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles, virtualStoreDir, }), } @@ -379,6 +381,7 @@ export async function getContextForSingleImporter ( storeDir: string useLockfile: boolean useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean virtualStoreDir?: string hoistPattern?: string[] | undefined @@ -483,6 +486,7 @@ export async function getContextForSingleImporter ( registry: opts.registries.default, useLockfile: opts.useLockfile, useGitBranchLockfile: opts.useGitBranchLockfile, + mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles, virtualStoreDir, }), } diff --git a/packages/get-context/src/readLockfiles.ts b/packages/get-context/src/readLockfiles.ts index 19f022d50dc..f108e138eca 100644 --- a/packages/get-context/src/readLockfiles.ts +++ b/packages/get-context/src/readLockfiles.ts @@ -35,6 +35,7 @@ export default async function ( registry: string useLockfile: boolean useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean virtualStoreDir: string } ): Promise<{ @@ -51,6 +52,7 @@ export default async function ( ignoreIncompatible: opts.force || isCI, wantedVersion: LOCKFILE_VERSION, useGitBranchLockfile: opts.useGitBranchLockfile, + mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles, } const fileReads = [] as Array> let lockfileHadConflicts: boolean = false diff --git a/packages/headless/src/index.ts b/packages/headless/src/index.ts index 4d6d1390f94..7bb12029ec0 100644 --- a/packages/headless/src/index.ts +++ b/packages/headless/src/index.ts @@ -138,6 +138,7 @@ export interface HeadlessOptions { enableModulesDir?: boolean nodeLinker?: 'isolated' | 'hoisted' | 'pnp' useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } export default async (opts: HeadlessOptions) => { @@ -150,6 +151,7 @@ export default async (opts: HeadlessOptions) => { const wantedLockfile = opts.wantedLockfile ?? await readWantedLockfile(lockfileDir, { ignoreIncompatible: false, useGitBranchLockfile: opts.useGitBranchLockfile, + mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles, }) if (wantedLockfile == null) { diff --git a/packages/lockfile-file/src/cleanGitBranchLockfile.ts b/packages/lockfile-file/src/cleanGitBranchLockfile.ts deleted file mode 100644 index 303ed52151f..00000000000 --- a/packages/lockfile-file/src/cleanGitBranchLockfile.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { promises as fs } from 'fs' -import path from 'path' - -export async function cleanGitBranchLockfiles (pkgPath: string) { - const files = await fs.readdir(pkgPath) - const gitBranchLockfiles: string[] = files.filter(file => file.match(/pnpm-lock.(?:.*).yaml/)) - await Promise.all( - gitBranchLockfiles.map(async file => { - const filepath: string = path.join(pkgPath, file) - await fs.rm(filepath) - }) - ) -} \ No newline at end of file diff --git a/packages/lockfile-file/src/existsWantedLockfile.ts b/packages/lockfile-file/src/existsWantedLockfile.ts index 613eb15c0fd..8757b6cfe0f 100644 --- a/packages/lockfile-file/src/existsWantedLockfile.ts +++ b/packages/lockfile-file/src/existsWantedLockfile.ts @@ -4,10 +4,12 @@ import { getWantedLockfileName } from './lockfileName' interface ExistsWantedLockfileOptions { useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } export default async (pkgPath: string, opts: ExistsWantedLockfileOptions = { useGitBranchLockfile: false, + mergeGitBranchLockfiles: false, }) => { const wantedLockfile: string = await getWantedLockfileName(opts) return new Promise((resolve, reject) => { diff --git a/packages/lockfile-file/src/gitBranchLockfile.ts b/packages/lockfile-file/src/gitBranchLockfile.ts new file mode 100644 index 00000000000..b6f8acb8044 --- /dev/null +++ b/packages/lockfile-file/src/gitBranchLockfile.ts @@ -0,0 +1,18 @@ +import { promises as fs } from 'fs' +import path from 'path' + +export async function getGitBranchLockfileNames (lockfileDir: string) { + const files = await fs.readdir(lockfileDir) + const gitBranchLockfileNames: string[] = files.filter(file => file.match(/pnpm-lock.(?:.*).yaml/)) + return gitBranchLockfileNames +} + +export async function cleanGitBranchLockfiles (lockfileDir: string) { + const gitBranchLockfiles: string[] = await getGitBranchLockfileNames(lockfileDir) + await Promise.all( + gitBranchLockfiles.map(async file => { + const filepath: string = path.join(lockfileDir, file) + await fs.rm(filepath) + }) + ) +} diff --git a/packages/lockfile-file/src/index.ts b/packages/lockfile-file/src/index.ts index 26bf3be624d..0587041af04 100644 --- a/packages/lockfile-file/src/index.ts +++ b/packages/lockfile-file/src/index.ts @@ -15,5 +15,3 @@ export { writeCurrentLockfile, writeWantedLockfile, } - -export { cleanGitBranchLockfiles } from './cleanGitBranchLockfile' \ No newline at end of file diff --git a/packages/lockfile-file/src/lockfileName.ts b/packages/lockfile-file/src/lockfileName.ts index cde7ec32d88..0d8f7691a6c 100644 --- a/packages/lockfile-file/src/lockfileName.ts +++ b/packages/lockfile-file/src/lockfileName.ts @@ -3,10 +3,11 @@ import { getCurrentBranch } from '@pnpm/git-utils' export interface GetWantedLockfileNameOptions { useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } -export async function getWantedLockfileName (opts: GetWantedLockfileNameOptions = { useGitBranchLockfile: false }) { - if (opts.useGitBranchLockfile) { +export async function getWantedLockfileName (opts: GetWantedLockfileNameOptions = { useGitBranchLockfile: false, mergeGitBranchLockfiles: false }) { + if (opts.useGitBranchLockfile && !opts.mergeGitBranchLockfiles) { const currentBranchName = await getCurrentBranch() if (currentBranchName) { return WANTED_LOCKFILE.replace('.yaml', `.${stringifyBranchName(currentBranchName)}.yaml`) diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index 8a6e3e36e76..340933397a9 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -16,6 +16,7 @@ import { autofixMergeConflicts, isDiff } from './gitMergeFile' import logger from './logger' import { LockfileFile } from './write' import { getWantedLockfileName } from './lockfileName' +import { getGitBranchLockfileNames } from './gitBranchLockfile' export async function readCurrentLockfile ( virtualStoreDir: string, @@ -34,23 +35,30 @@ export async function readWantedLockfileAndAutofixConflicts ( wantedVersion?: number ignoreIncompatible: boolean useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } ): Promise<{ lockfile: Lockfile | null hadConflicts: boolean }> { - let result: { lockfile: Lockfile | null, hadConflicts: boolean} = { - lockfile: null, - hadConflicts: false, - } + const lockfileNames: string[] = [WANTED_LOCKFILE] if (opts.useGitBranchLockfile) { - const lockfilePath = path.join(pkgPath, await getWantedLockfileName(opts)) - result = await _read(lockfilePath, pkgPath, { ...opts, autofixMergeConflicts: true }) + const gitBranchLockfileName: string = await getWantedLockfileName(opts) + if (gitBranchLockfileName !== WANTED_LOCKFILE) { + lockfileNames.unshift(gitBranchLockfileName) + } + } + let result: { lockfile: Lockfile | null, hadConflicts: boolean } = { lockfile: null, hadConflicts: false } + for (const lockfileName of lockfileNames) { + result = await _read(path.join(pkgPath, lockfileName), pkgPath, { ...opts, autofixMergeConflicts: true }) if (result.lockfile) { - return result + if (opts.mergeGitBranchLockfiles) { + result.lockfile = await _mergeGitBranchLockfiles(result.lockfile, pkgPath, pkgPath, opts) + } + break } } - return _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, { ...opts, autofixMergeConflicts: true }) + return result } export async function readWantedLockfile ( @@ -59,17 +67,27 @@ export async function readWantedLockfile ( wantedVersion?: number ignoreIncompatible: boolean useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } ): Promise { - let lockfile: Lockfile | null = null + const lockfileNames: string[] = [WANTED_LOCKFILE] if (opts.useGitBranchLockfile) { - const lockfilePath = path.join(pkgPath, await getWantedLockfileName(opts)) - lockfile = (await _read(lockfilePath, pkgPath, opts)).lockfile + const gitBranchLockfileName: string = await getWantedLockfileName(opts) + if (gitBranchLockfileName !== WANTED_LOCKFILE) { + lockfileNames.unshift(gitBranchLockfileName) + } + } + let lockfile: Lockfile | null = null + for (const lockfileName of lockfileNames) { + lockfile = (await _read(path.join(pkgPath, lockfileName), pkgPath, opts)).lockfile if (lockfile) { - return lockfile + if (opts.mergeGitBranchLockfiles) { + lockfile = await _mergeGitBranchLockfiles(lockfile, pkgPath, pkgPath, opts) + } + break } } - return (await _read(path.join(pkgPath, WANTED_LOCKFILE), pkgPath, opts)).lockfile + return lockfile } async function _read ( @@ -170,3 +188,47 @@ export function createLockfileObject ( lockfileVersion: opts.lockfileVersion || LOCKFILE_VERSION, } } + +async function _mergeGitBranchLockfiles ( + lockfile: Lockfile | null, + lockfileDir: string, + prefix: string, + opts: { + autofixMergeConflicts?: boolean + wantedVersion?: number + ignoreIncompatible: boolean + } +): Promise { + if (!lockfile) { + return lockfile + } + const gitBranchLockfiles: Array<(Lockfile | null)> = (await _readGitBranchLockfiles(lockfileDir, prefix, opts)).map(({ lockfile }) => lockfile) + + for (const gitBranchLockfile of gitBranchLockfiles) { + if (gitBranchLockfile?.packages) { + lockfile.packages = { + ...lockfile.packages, + ...gitBranchLockfile.packages, + } + } + } + + return lockfile +} + +async function _readGitBranchLockfiles ( + lockfileDir: string, + prefix: string, + opts: { + autofixMergeConflicts?: boolean + wantedVersion?: number + ignoreIncompatible: boolean + } +): Promise> { + const files = await getGitBranchLockfileNames(lockfileDir) + + return Promise.all(files.map((file) => _read(path.join(lockfileDir, file), prefix, opts))) +} \ No newline at end of file diff --git a/packages/lockfile-file/src/write.ts b/packages/lockfile-file/src/write.ts index 40a9926a016..d8318763d23 100644 --- a/packages/lockfile-file/src/write.ts +++ b/packages/lockfile-file/src/write.ts @@ -11,6 +11,7 @@ import writeFileAtomicCB from 'write-file-atomic' import logger from './logger' import { sortLockfileKeys } from './sortLockfileKeys' import { getWantedLockfileName } from './lockfileName' +import { cleanGitBranchLockfiles } from './gitBranchLockfile' async function writeFileAtomic (filename: string, data: string) { return new Promise((resolve, reject) => writeFileAtomicCB(filename, data, {}, (err?: Error) => (err != null) ? reject(err) : resolve())) @@ -30,10 +31,15 @@ export async function writeWantedLockfile ( opts?: { forceSharedFormat?: boolean useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } ) { const wantedLockfileName: string = await getWantedLockfileName(opts) - return writeLockfile(wantedLockfileName, pkgPath, wantedLockfile, opts) + const writeResult = await writeLockfile(wantedLockfileName, pkgPath, wantedLockfile, opts) + if (opts?.mergeGitBranchLockfiles) { + await cleanGitBranchLockfiles(pkgPath) + } + return writeResult } export async function writeCurrentLockfile ( @@ -146,6 +152,7 @@ export default async function writeLockfiles ( currentLockfile: Lockfile currentLockfileDir: string useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean } ) { const wantedLockfileName: string = await getWantedLockfileName(opts) @@ -175,6 +182,11 @@ export default async function writeLockfiles ( await writeFileAtomic(currentLockfilePath, yamlDoc) })(), ]) + + if (opts.mergeGitBranchLockfiles) { + await cleanGitBranchLockfiles(opts.wantedLockfileDir) + } + return } @@ -192,4 +204,8 @@ export default async function writeLockfiles ( await writeFileAtomic(currentLockfilePath, currentYamlDoc) })(), ]) + + if (opts.mergeGitBranchLockfiles) { + await cleanGitBranchLockfiles(opts.wantedLockfileDir) + } } diff --git a/packages/lockfile-file/test/fixtures/6/otherFile.md b/packages/lockfile-file/test/fixtures/6/otherFile.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml b/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml index 0674b1d2f80..8f8c945c11d 100644 --- a/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml +++ b/packages/lockfile-file/test/fixtures/6/pnpm-lock.branch.yaml @@ -1,4 +1,9 @@ lockfileVersion: 5.3 specifiers: - foo: '2' + is-positive: '2.0.0' + +packages: + /is-positive/2.0.0: + resolution: {integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g='} + diff --git a/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml b/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml index 58873f9a5b2..35be8a9f8ad 100644 --- a/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml +++ b/packages/lockfile-file/test/fixtures/6/pnpm-lock.yaml @@ -1,4 +1,8 @@ lockfileVersion: 5.3 specifiers: - foo: '1' + is-positive: '1.0.0' + +packages: + /is-positive/1.0.0: + resolution: {integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g='} \ No newline at end of file diff --git a/packages/lockfile-file/test/gitBranchLockfile.test.ts b/packages/lockfile-file/test/gitBranchLockfile.test.ts new file mode 100644 index 00000000000..7a06e72e23e --- /dev/null +++ b/packages/lockfile-file/test/gitBranchLockfile.test.ts @@ -0,0 +1,10 @@ +import path from 'path' +import { getGitBranchLockfileNames } from '@pnpm/lockfile-file/lib/gitBranchLockfile' + +process.chdir(__dirname) + +test('getGitBranchLockfileNames()', async () => { + const lockfileDir: string = path.join('fixtures', '6') + const gitBranchLockfileNames = await getGitBranchLockfileNames(lockfileDir) + expect(gitBranchLockfileNames).toEqual(['pnpm-lock.branch.yaml']) +}) \ No newline at end of file diff --git a/packages/lockfile-file/test/read.test.ts b/packages/lockfile-file/test/read.test.ts index 4f728423b27..a0ee6a0b37c 100644 --- a/packages/lockfile-file/test/read.test.ts +++ b/packages/lockfile-file/test/read.test.ts @@ -200,7 +200,14 @@ test('readWantedLockfile() when useGitBranchLockfile', async () => { expect(lockfile?.importers).toEqual({ '.': { specifiers: { - foo: '1', + 'is-positive': '1.0.0', + }, + }, + }) + expect(lockfile?.packages).toStrictEqual({ + '/is-positive/1.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=', }, }, }) @@ -212,7 +219,42 @@ test('readWantedLockfile() when useGitBranchLockfile', async () => { expect(gitBranchLockfile?.importers).toEqual({ '.': { specifiers: { - foo: '2', + 'is-positive': '2.0.0', + }, + }, + }) + expect(gitBranchLockfile?.packages).toStrictEqual({ + '/is-positive/2.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=', + }, + }, + }) +}) + +test('readWantedLockfile() when useGitBranchLockfile and mergeGitBranchLockfiles', async () => { + getCurrentBranch.mockReturnValue('branch') + const lockfile = await readWantedLockfile(path.join('fixtures', '6'), { + ignoreIncompatible: false, + useGitBranchLockfile: true, + mergeGitBranchLockfiles: true, + }) + expect(lockfile?.importers).toEqual({ + '.': { + specifiers: { + 'is-positive': '1.0.0', + }, + }, + }) + expect(lockfile?.packages).toStrictEqual({ + '/is-positive/1.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=', + }, + }, + '/is-positive/2.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=', }, }, }) diff --git a/packages/plugin-commands-installation/src/install.ts b/packages/plugin-commands-installation/src/install.ts index 847c9d7936e..aa3e7d2ed0d 100644 --- a/packages/plugin-commands-installation/src/install.ts +++ b/packages/plugin-commands-installation/src/install.ts @@ -12,7 +12,7 @@ export function rcOptionsTypes () { return pick([ 'cache-dir', 'child-concurrency', - 'clean-git-branch-lockfiles', + 'merge-git-branch-lockfiles', 'dev', 'engine-strict', 'fetch-retries', @@ -141,8 +141,8 @@ For options that may be used with `-r`, see "pnpm help recursive"', name: '--fix-lockfile', }, { - description: 'Clean lockfiles were generated on git branch', - name: '--clean-git-branch-lockfiles', + description: 'Merge lockfiles were generated on git branch', + name: '--merge-git-branch-lockfiles', }, { description: 'The directory in which dependencies will be installed (instead of node_modules)', diff --git a/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts b/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts index 4d9fe7a3175..cfe02e78574 100644 --- a/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts +++ b/packages/plugin-commands-store/src/storeStatus/extendStoreStatusOptions.ts @@ -11,7 +11,6 @@ export interface StrictStoreStatusOptions { forceSharedLockfile: boolean nodeLinker: 'isolated' | 'hoisted' | 'pnp' useLockfile: boolean - useGitBranchLockfile: boolean registries: Registries shamefullyHoist: boolean @@ -39,7 +38,6 @@ const defaults = async (opts: StoreStatusOptions) => { shamefullyHoist: false, storeDir: opts.storeDir, useLockfile: true, - useGitBranchLockfile: false, } as StrictStoreStatusOptions } From e19b2e9a5054f47cacf2ae1a570c95a9ece4c616 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 26 Mar 2022 22:31:29 +0800 Subject: [PATCH 10/25] fix: cleanGitBranchLockfiles when install --merge-git-branch-lockfiles --- packages/core/src/install/index.ts | 5 +++++ packages/lockfile-file/src/index.ts | 2 ++ packages/lockfile-file/src/write.ts | 16 +--------------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/core/src/install/index.ts b/packages/core/src/install/index.ts index f3a3e6f600a..d1e6069442b 100644 --- a/packages/core/src/install/index.ts +++ b/packages/core/src/install/index.ts @@ -25,6 +25,7 @@ import { writeCurrentLockfile, writeLockfiles, writeWantedLockfile, + cleanGitBranchLockfiles, } from '@pnpm/lockfile-file' import { writePnpFile } from '@pnpm/lockfile-to-pnp' import { extendProjectsWithTargetDirs } from '@pnpm/lockfile-utils' @@ -195,6 +196,10 @@ export async function mutateModules ( streamParser.removeListener('data', reporter) } + if (opts.mergeGitBranchLockfiles) { + await cleanGitBranchLockfiles(ctx.lockfileDir) + } + return result async function _install (): Promise { diff --git a/packages/lockfile-file/src/index.ts b/packages/lockfile-file/src/index.ts index 0587041af04..9387bfd04f3 100644 --- a/packages/lockfile-file/src/index.ts +++ b/packages/lockfile-file/src/index.ts @@ -15,3 +15,5 @@ export { writeCurrentLockfile, writeWantedLockfile, } + +export { cleanGitBranchLockfiles } from './gitBranchLockfile' \ No newline at end of file diff --git a/packages/lockfile-file/src/write.ts b/packages/lockfile-file/src/write.ts index d8318763d23..36ce35289fe 100644 --- a/packages/lockfile-file/src/write.ts +++ b/packages/lockfile-file/src/write.ts @@ -11,7 +11,6 @@ import writeFileAtomicCB from 'write-file-atomic' import logger from './logger' import { sortLockfileKeys } from './sortLockfileKeys' import { getWantedLockfileName } from './lockfileName' -import { cleanGitBranchLockfiles } from './gitBranchLockfile' async function writeFileAtomic (filename: string, data: string) { return new Promise((resolve, reject) => writeFileAtomicCB(filename, data, {}, (err?: Error) => (err != null) ? reject(err) : resolve())) @@ -35,11 +34,7 @@ export async function writeWantedLockfile ( } ) { const wantedLockfileName: string = await getWantedLockfileName(opts) - const writeResult = await writeLockfile(wantedLockfileName, pkgPath, wantedLockfile, opts) - if (opts?.mergeGitBranchLockfiles) { - await cleanGitBranchLockfiles(pkgPath) - } - return writeResult + return writeLockfile(wantedLockfileName, pkgPath, wantedLockfile, opts) } export async function writeCurrentLockfile ( @@ -182,11 +177,6 @@ export default async function writeLockfiles ( await writeFileAtomic(currentLockfilePath, yamlDoc) })(), ]) - - if (opts.mergeGitBranchLockfiles) { - await cleanGitBranchLockfiles(opts.wantedLockfileDir) - } - return } @@ -204,8 +194,4 @@ export default async function writeLockfiles ( await writeFileAtomic(currentLockfilePath, currentYamlDoc) })(), ]) - - if (opts.mergeGitBranchLockfiles) { - await cleanGitBranchLockfiles(opts.wantedLockfileDir) - } } From 5f397481b305f655dcbdb1909dba76bcd9b8915d Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sun, 27 Mar 2022 17:23:45 +0800 Subject: [PATCH 11/25] refactor: reuse readwantedlockfile logic --- packages/lockfile-file/src/read.ts | 74 +++++++++++++++--------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index 340933397a9..8e928991949 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -41,24 +41,10 @@ export async function readWantedLockfileAndAutofixConflicts ( lockfile: Lockfile | null hadConflicts: boolean }> { - const lockfileNames: string[] = [WANTED_LOCKFILE] - if (opts.useGitBranchLockfile) { - const gitBranchLockfileName: string = await getWantedLockfileName(opts) - if (gitBranchLockfileName !== WANTED_LOCKFILE) { - lockfileNames.unshift(gitBranchLockfileName) - } - } - let result: { lockfile: Lockfile | null, hadConflicts: boolean } = { lockfile: null, hadConflicts: false } - for (const lockfileName of lockfileNames) { - result = await _read(path.join(pkgPath, lockfileName), pkgPath, { ...opts, autofixMergeConflicts: true }) - if (result.lockfile) { - if (opts.mergeGitBranchLockfiles) { - result.lockfile = await _mergeGitBranchLockfiles(result.lockfile, pkgPath, pkgPath, opts) - } - break - } - } - return result + return _readWantedLockfile(pkgPath, { + ...opts, + autofixMergeConflicts: true, + }) } export async function readWantedLockfile ( @@ -70,24 +56,7 @@ export async function readWantedLockfile ( mergeGitBranchLockfiles?: boolean } ): Promise { - const lockfileNames: string[] = [WANTED_LOCKFILE] - if (opts.useGitBranchLockfile) { - const gitBranchLockfileName: string = await getWantedLockfileName(opts) - if (gitBranchLockfileName !== WANTED_LOCKFILE) { - lockfileNames.unshift(gitBranchLockfileName) - } - } - let lockfile: Lockfile | null = null - for (const lockfileName of lockfileNames) { - lockfile = (await _read(path.join(pkgPath, lockfileName), pkgPath, opts)).lockfile - if (lockfile) { - if (opts.mergeGitBranchLockfiles) { - lockfile = await _mergeGitBranchLockfiles(lockfile, pkgPath, pkgPath, opts) - } - break - } - } - return lockfile + return (await _readWantedLockfile(pkgPath, opts)).lockfile } async function _read ( @@ -189,6 +158,39 @@ export function createLockfileObject ( } } +async function _readWantedLockfile ( + pkgPath: string, + opts: { + wantedVersion?: number + ignoreIncompatible: boolean + useGitBranchLockfile?: boolean + mergeGitBranchLockfiles?: boolean + autofixMergeConflicts?: boolean + } +): Promise<{ + lockfile: Lockfile | null + hadConflicts: boolean + }> { + const lockfileNames: string[] = [WANTED_LOCKFILE] + if (opts.useGitBranchLockfile) { + const gitBranchLockfileName: string = await getWantedLockfileName(opts) + if (gitBranchLockfileName !== WANTED_LOCKFILE) { + lockfileNames.unshift(gitBranchLockfileName) + } + } + let result: { lockfile: Lockfile | null, hadConflicts: boolean } = { lockfile: null, hadConflicts: false } + for (const lockfileName of lockfileNames) { + result = await _read(path.join(pkgPath, lockfileName), pkgPath, { ...opts, autofixMergeConflicts: true }) + if (result.lockfile) { + if (opts.mergeGitBranchLockfiles) { + result.lockfile = await _mergeGitBranchLockfiles(result.lockfile, pkgPath, pkgPath, opts) + } + break + } + } + return result +} + async function _mergeGitBranchLockfiles ( lockfile: Lockfile | null, lockfileDir: string, From 3708de49c8617556616fa496bec6da12967d1ebd Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sun, 27 Mar 2022 17:32:42 +0800 Subject: [PATCH 12/25] feat: merge git branch lockfiles unsupported in headless --- packages/headless/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/headless/src/index.ts b/packages/headless/src/index.ts index 7bb12029ec0..0b6728c7f5c 100644 --- a/packages/headless/src/index.ts +++ b/packages/headless/src/index.ts @@ -138,7 +138,6 @@ export interface HeadlessOptions { enableModulesDir?: boolean nodeLinker?: 'isolated' | 'hoisted' | 'pnp' useGitBranchLockfile?: boolean - mergeGitBranchLockfiles?: boolean } export default async (opts: HeadlessOptions) => { @@ -151,7 +150,8 @@ export default async (opts: HeadlessOptions) => { const wantedLockfile = opts.wantedLockfile ?? await readWantedLockfile(lockfileDir, { ignoreIncompatible: false, useGitBranchLockfile: opts.useGitBranchLockfile, - mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles, + // mergeGitBranchLockfiles is intentionally not supported in headless + mergeGitBranchLockfiles: false, }) if (wantedLockfile == null) { From 545ed3bd06712c9887ff5615a41d545ee0653ebb Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sun, 27 Mar 2022 17:41:25 +0800 Subject: [PATCH 13/25] chore: turn on sourcemap accidently --- packages/pnpm/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pnpm/tsconfig.json b/packages/pnpm/tsconfig.json index 5f6efd2034a..da152edddcf 100644 --- a/packages/pnpm/tsconfig.json +++ b/packages/pnpm/tsconfig.json @@ -4,7 +4,7 @@ "composite": false, "declaration": false, "outDir": "lib", - "sourceMap": true, + "sourceMap": false, "rootDir": "src" }, "include": [ From b2b61517f105efa07f9ba91c5196510e55ac3f9b Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 2 Apr 2022 04:38:16 +0800 Subject: [PATCH 14/25] chore: test file --- .../test/install/gitBranchLockfile.test.ts | 47 ++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts index 486bef09e81..daf004bcf90 100644 --- a/packages/core/test/install/gitBranchLockfile.test.ts +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -9,7 +9,7 @@ import { ProjectManifest } from '@pnpm/types' import writeYamlFile from 'write-yaml-file' test('install with git-branch-lockfile = true', async () => { - const project = prepareEmpty() + prepareEmpty() const branchName: string = 'main-branch' getCurrentBranch.mockReturnValue(branchName) @@ -24,9 +24,36 @@ test('install with git-branch-lockfile = true', async () => { }, }, opts) - const lockfileDir: string = project.dir() - expect(fs.existsSync(path.join(lockfileDir, `pnpm-lock.${branchName}.yaml`))).toBe(true) - expect(fs.existsSync(path.join(lockfileDir, WANTED_LOCKFILE))).toBe(false) + expect(fs.existsSync(`pnpm-lock.${branchName}.yaml`)).toBe(true) + expect(fs.existsSync(WANTED_LOCKFILE)).toBe(false) +}) + +test('install with git-branch-lockfile = true and no lockfile changes', async () => { + prepareEmpty() + + const branchName: string = 'main-branch' + getCurrentBranch.mockReturnValue(branchName) + + const manifest: ProjectManifest = { + dependencies: { + 'is-positive': '^3.0.0', + }, + } + + const opts1 = await testDefaults({ + useGitBranchLockfile: false, + }) + await install(manifest, opts1) + + expect(fs.existsSync(WANTED_LOCKFILE)).toBe(true) + + const opts2 = await testDefaults({ + useGitBranchLockfile: true, + }) + await install(manifest, opts2) + expect(fs.existsSync(WANTED_LOCKFILE)).toBe(true) + // Git branch lockfile is created only if there are changes in the lockfile + expect(fs.existsSync(`pnpm-lock.${branchName}.yaml`)).toBe(false) }) test('install a workspace with git-branch-lockfile = true', async () => { @@ -41,7 +68,7 @@ test('install a workspace with git-branch-lockfile = true', async () => { name: 'project-2', dependencies: { 'is-positive': '1.0.0' }, } - const { root } = preparePackages([ + preparePackages([ { location: '.', package: rootManifest, @@ -84,9 +111,8 @@ test('install a workspace with git-branch-lockfile = true', async () => { }, ], opts) - const lockfileDir: string = root.dir() - expect(fs.existsSync(path.join(lockfileDir, `pnpm-lock.${branchName}.yaml`))).toBe(true) - expect(fs.existsSync(path.join(lockfileDir, WANTED_LOCKFILE))).toBe(false) + expect(fs.existsSync(`pnpm-lock.${branchName}.yaml`)).toBe(true) + expect(fs.existsSync(WANTED_LOCKFILE)).toBe(false) }) test('install with --merge-git-branch-lockfiles', async () => { @@ -96,13 +122,12 @@ test('install with --merge-git-branch-lockfiles', async () => { getCurrentBranch.mockReturnValue(branchName) const otherLockfilePath: string = path.resolve('pnpm-lock.other.yaml') - const mainLockfilePath: string = path.resolve(WANTED_LOCKFILE) await writeYamlFile(otherLockfilePath, { whatever: 'whatever', }) expect(fs.existsSync(otherLockfilePath)).toBe(true) - expect(fs.existsSync(mainLockfilePath)).toBe(false) + expect(fs.existsSync(WANTED_LOCKFILE)).toBe(false) const opts = await testDefaults({ useGitBranchLockfile: true, @@ -115,5 +140,5 @@ test('install with --merge-git-branch-lockfiles', async () => { }, opts) expect(fs.existsSync(otherLockfilePath)).toBe(false) - expect(fs.existsSync(mainLockfilePath)).toBe(true) + expect(fs.existsSync(WANTED_LOCKFILE)).toBe(true) }) \ No newline at end of file From 36878d5c43fabe1ea5a5995671a10bd3b4bc1b15 Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Sat, 2 Apr 2022 05:51:58 +0800 Subject: [PATCH 15/25] feat: merge-git-branch-lockfiles-branch-pattern --- packages/config/package.json | 2 + packages/config/src/Config.ts | 1 + packages/config/src/index.ts | 15 +++- packages/config/test/index.ts | 90 +++++++++++++++++++ packages/config/tsconfig.json | 6 ++ .../src/install.ts | 3 +- pnpm-lock.yaml | 4 + 7 files changed, 119 insertions(+), 2 deletions(-) diff --git a/packages/config/package.json b/packages/config/package.json index f2bea352b3d..aab31e7fa8f 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -34,6 +34,8 @@ "dependencies": { "@pnpm/constants": "workspace:6.0.0", "@pnpm/error": "workspace:3.0.0", + "@pnpm/git-utils": "workspace:0.0.0", + "@pnpm/matcher": "workspace:3.0.0", "@pnpm/pnpmfile": "workspace:2.0.0", "@pnpm/read-project-manifest": "workspace:3.0.0", "@pnpm/types": "workspace:8.0.0", diff --git a/packages/config/src/Config.ts b/packages/config/src/Config.ts index 653424ea5a9..8d70b9a73a7 100644 --- a/packages/config/src/Config.ts +++ b/packages/config/src/Config.ts @@ -132,6 +132,7 @@ export interface Config { useLockfile: boolean useGitBranchLockfile: boolean mergeGitBranchLockfiles?: boolean + mergeGitBranchLockfilesBranchPattern?: string[] globalPnpmfile?: string npmPath?: string gitChecks?: boolean diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index c5e179e5947..59edec9ce2a 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -4,6 +4,8 @@ import { LAYOUT_VERSION } from '@pnpm/constants' import PnpmError from '@pnpm/error' import { requireHooks } from '@pnpm/pnpmfile' import { safeReadProjectManifestOnly } from '@pnpm/read-project-manifest' +import { getCurrentBranch } from '@pnpm/git-utils' +import matcher from '@pnpm/matcher' import camelcase from 'camelcase' import loadNpmConf from '@zkochan/npm-conf' import npmTypes from '@zkochan/npm-conf/lib/types' @@ -36,6 +38,7 @@ export const types = Object.assign({ 'cache-dir': String, 'child-concurrency': Number, 'merge-git-branch-lockfiles': Boolean, + 'merge-git-branch-lockfiles-branch-pattern': Array, color: ['always', 'auto', 'never'], 'config-dir': String, dev: [null, true], @@ -256,6 +259,17 @@ export default async ( if (typeof pnpmConfig['gitBranchLockfile'] === 'boolean') return pnpmConfig['gitBranchLockfile'] return false })() + pnpmConfig.mergeGitBranchLockfiles = await (async () => { + if (typeof pnpmConfig['mergeGitBranchLockfiles'] === 'boolean') return pnpmConfig['mergeGitBranchLockfiles'] + if (pnpmConfig['mergeGitBranchLockfilesBranchPattern'] != null && pnpmConfig['mergeGitBranchLockfilesBranchPattern'].length > 0) { + const branch = await getCurrentBranch() + if (branch) { + const branchMatcher = matcher(pnpmConfig['mergeGitBranchLockfilesBranchPattern']) + return branchMatcher(branch) + } + } + return undefined + })() pnpmConfig.pnpmHomeDir = getDataDir(process) if (cliOptions['global']) { @@ -309,7 +323,6 @@ export default async ( } delete pnpmConfig.lockfileDir } - pnpmConfig.useGitBranchLockfile = false if (opts.cliOptions['virtual-store-dir']) { throw new PnpmError('CONFIG_CONFLICT_VIRTUAL_STORE_DIR_WITH_GLOBAL', 'Configuration conflict. "virtual-store-dir" may not be used with "global"') diff --git a/packages/config/test/index.ts b/packages/config/test/index.ts index 8a62cd2caa1..7b45d53e884 100644 --- a/packages/config/test/index.ts +++ b/packages/config/test/index.ts @@ -2,6 +2,7 @@ import { promises as fs } from 'fs' import path from 'path' import PATH from 'path-name' +import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import getConfig from '@pnpm/config' import PnpmError from '@pnpm/error' import prepare, { prepareEmpty } from '@pnpm/prepare' @@ -786,3 +787,92 @@ test('getConfig() sets sideEffectsCacheRead and sideEffectsCacheWrite when side- expect(config.sideEffectsCacheRead).toBeTruthy() expect(config.sideEffectsCacheWrite).toBeTruthy() }) + +test('respect merge-git-branch-lockfiles-branch-pattern', async () => { + { + const { config } = await getConfig({ + cliOptions: {}, + packageManager: { + name: 'pnpm', + version: '1.0.0', + }, + }) + + expect(config.mergeGitBranchLockfilesBranchPattern).toBeUndefined() + expect(config.mergeGitBranchLockfiles).toBeUndefined() + } + { + prepareEmpty() + + const npmrc = [ + 'merge-git-branch-lockfiles-branch-pattern[]=main', + 'merge-git-branch-lockfiles-branch-pattern[]=release/**', + ].join('\n') + + await fs.writeFile('.npmrc', npmrc, 'utf8') + + const { config } = await getConfig({ + cliOptions: { + global: false, + }, + packageManager: { + name: 'pnpm', + version: '1.0.0', + }, + }) + + expect(config.mergeGitBranchLockfilesBranchPattern).toEqual(['main', 'release/**']) + } +}) + +test('getConfig() sets merge-git-branch-lockfiles when branch matches merge-git-branch-lockfiles-branch-pattern', async () => { + prepareEmpty() + { + const npmrc = [ + 'merge-git-branch-lockfiles-branch-pattern[]=main', + 'merge-git-branch-lockfiles-branch-pattern[]=release/**', + ].join('\n') + + await fs.writeFile('.npmrc', npmrc, 'utf8') + + getCurrentBranch.mockReturnValue('develop') + const { config } = await getConfig({ + cliOptions: { + global: false, + }, + packageManager: { + name: 'pnpm', + version: '1.0.0', + }, + }) + + expect(config.mergeGitBranchLockfilesBranchPattern).toEqual(['main', 'release/**']) + expect(config.mergeGitBranchLockfiles).toBe(false) + } + { + getCurrentBranch.mockReturnValue('main') + const { config } = await getConfig({ + cliOptions: { + global: false, + }, + packageManager: { + name: 'pnpm', + version: '1.0.0', + }, + }) + expect(config.mergeGitBranchLockfiles).toBe(true) + } + { + getCurrentBranch.mockReturnValue('release/1.0.0') + const { config } = await getConfig({ + cliOptions: { + global: false, + }, + packageManager: { + name: 'pnpm', + version: '1.0.0', + }, + }) + expect(config.mergeGitBranchLockfiles).toBe(true) + } +}) \ No newline at end of file diff --git a/packages/config/tsconfig.json b/packages/config/tsconfig.json index 9660d8adfdb..7a6e0ef56be 100644 --- a/packages/config/tsconfig.json +++ b/packages/config/tsconfig.json @@ -18,6 +18,12 @@ { "path": "../error" }, + { + "path": "../git-utils" + }, + { + "path": "../matcher" + }, { "path": "../pnpmfile" }, diff --git a/packages/plugin-commands-installation/src/install.ts b/packages/plugin-commands-installation/src/install.ts index aa3e7d2ed0d..a9e45b8771c 100644 --- a/packages/plugin-commands-installation/src/install.ts +++ b/packages/plugin-commands-installation/src/install.ts @@ -12,7 +12,6 @@ export function rcOptionsTypes () { return pick([ 'cache-dir', 'child-concurrency', - 'merge-git-branch-lockfiles', 'dev', 'engine-strict', 'fetch-retries', @@ -34,6 +33,8 @@ export function rcOptionsTypes () { 'lockfile-directory', 'lockfile-only', 'lockfile', + 'merge-git-branch-lockfiles', + 'merge-git-branch-lockfiles-branch-pattern', 'modules-dir', 'network-concurrency', 'node-linker', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7506bc3628b..a0b2450572c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -341,6 +341,8 @@ importers: '@pnpm/config': workspace:14.0.0 '@pnpm/constants': workspace:6.0.0 '@pnpm/error': workspace:3.0.0 + '@pnpm/git-utils': workspace:0.0.0 + '@pnpm/matcher': workspace:3.0.0 '@pnpm/pnpmfile': workspace:2.0.0 '@pnpm/prepare': workspace:* '@pnpm/read-project-manifest': workspace:3.0.0 @@ -360,6 +362,8 @@ importers: dependencies: '@pnpm/constants': link:../constants '@pnpm/error': link:../error + '@pnpm/git-utils': link:../git-utils + '@pnpm/matcher': link:../matcher '@pnpm/pnpmfile': link:../pnpmfile '@pnpm/read-project-manifest': link:../read-project-manifest '@pnpm/types': link:../types From 4d6c772cfac27a721f64861c66d88b0bfdf02c2d Mon Sep 17 00:00:00 2001 From: Cheng Liu Date: Tue, 5 Apr 2022 09:47:53 +0800 Subject: [PATCH 16/25] feat: reuse merge lockfile changes logic --- packages/lockfile-file/src/read.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/lockfile-file/src/read.ts b/packages/lockfile-file/src/read.ts index 8e928991949..ee71c371a2b 100644 --- a/packages/lockfile-file/src/read.ts +++ b/packages/lockfile-file/src/read.ts @@ -5,6 +5,7 @@ import { WANTED_LOCKFILE, } from '@pnpm/constants' import PnpmError from '@pnpm/error' +import mergeLockfileChanges from '@pnpm/merge-lockfile-changes' import { Lockfile } from '@pnpm/lockfile-types' import { DEPENDENCIES_FIELDS } from '@pnpm/types' import comverToSemver from 'comver-to-semver' @@ -206,16 +207,16 @@ async function _mergeGitBranchLockfiles ( } const gitBranchLockfiles: Array<(Lockfile | null)> = (await _readGitBranchLockfiles(lockfileDir, prefix, opts)).map(({ lockfile }) => lockfile) + let mergedLockfile: Lockfile = lockfile + for (const gitBranchLockfile of gitBranchLockfiles) { - if (gitBranchLockfile?.packages) { - lockfile.packages = { - ...lockfile.packages, - ...gitBranchLockfile.packages, - } + if (!gitBranchLockfile) { + continue } + mergedLockfile = mergeLockfileChanges(mergedLockfile, gitBranchLockfile) } - return lockfile + return mergedLockfile } async function _readGitBranchLockfiles ( From f132ebf73904fdc263fb5b9f878299368679e283 Mon Sep 17 00:00:00 2001 From: Cheng Date: Fri, 3 Jun 2022 18:45:46 +0800 Subject: [PATCH 17/25] Update packages/lockfile-file/src/gitBranchLockfile.ts Co-authored-by: David Michon --- packages/lockfile-file/src/gitBranchLockfile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lockfile-file/src/gitBranchLockfile.ts b/packages/lockfile-file/src/gitBranchLockfile.ts index b6f8acb8044..8260bb85d68 100644 --- a/packages/lockfile-file/src/gitBranchLockfile.ts +++ b/packages/lockfile-file/src/gitBranchLockfile.ts @@ -3,7 +3,7 @@ import path from 'path' export async function getGitBranchLockfileNames (lockfileDir: string) { const files = await fs.readdir(lockfileDir) - const gitBranchLockfileNames: string[] = files.filter(file => file.match(/pnpm-lock.(?:.*).yaml/)) + const gitBranchLockfileNames: string[] = files.filter(file => file.match(/^pnpm-lock.(?:.*).yaml$/)) return gitBranchLockfileNames } From acccbb2976447f512a3bf381ca768b35088db734 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Fri, 10 Jun 2022 16:51:42 +0300 Subject: [PATCH 18/25] fix: add missing dependency to @pnpm/config --- packages/config/package.json | 1 + pnpm-lock.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/packages/config/package.json b/packages/config/package.json index 5efe4d62956..e80d8aa9a3b 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -35,6 +35,7 @@ "@pnpm/constants": "workspace:6.1.0", "@pnpm/error": "workspace:3.0.1", "@pnpm/git-utils": "workspace:0.0.0", + "@pnpm/matcher": "workspace:3.0.0", "@pnpm/npm-conf": "1.0.3", "@pnpm/pnpmfile": "workspace:2.0.3", "@pnpm/read-project-manifest": "workspace:3.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 82857a67332..2bf73c6ebce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -346,6 +346,7 @@ importers: '@pnpm/constants': workspace:6.1.0 '@pnpm/error': workspace:3.0.1 '@pnpm/git-utils': workspace:0.0.0 + '@pnpm/matcher': workspace:3.0.0 '@pnpm/npm-conf': 1.0.3 '@pnpm/pnpmfile': workspace:2.0.3 '@pnpm/prepare': workspace:* @@ -366,6 +367,7 @@ importers: '@pnpm/constants': link:../constants '@pnpm/error': link:../error '@pnpm/git-utils': link:../git-utils + '@pnpm/matcher': link:../matcher '@pnpm/npm-conf': 1.0.3 '@pnpm/pnpmfile': link:../pnpmfile '@pnpm/read-project-manifest': link:../read-project-manifest From e5982185e608216c5cc51a5b9df5f4d4a4177cf3 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Fri, 10 Jun 2022 17:19:22 +0300 Subject: [PATCH 19/25] test: fix --- fixtures/with-non-package-dep/pnpm-lock.yaml | 6 ++--- packages/config/test/index.ts | 4 +-- pnpm-lock.yaml | 26 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fixtures/with-non-package-dep/pnpm-lock.yaml b/fixtures/with-non-package-dep/pnpm-lock.yaml index a07c06b6e58..57771e8883b 100644 --- a/fixtures/with-non-package-dep/pnpm-lock.yaml +++ b/fixtures/with-non-package-dep/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: camelcase: denolib/camelcase#aeb6b15f9c9957c8fa56f9731e914c4d8a6d2f2b @@ -10,6 +10,6 @@ packages: github.com/denolib/camelcase/aeb6b15f9c9957c8fa56f9731e914c4d8a6d2f2b: resolution: {tarball: https://codeload.github.com/denolib/camelcase/tar.gz/aeb6b15f9c9957c8fa56f9731e914c4d8a6d2f2b} - name: camelcase - version: denolib/camelcase#aeb6b15f9c9957c8fa56f9731e914c4d8a6d2f2b + name: camelcase#aeb6b15f9c9957c8fa56f9731e914c4d8a6d2f2b + version: 0.0.0 dev: false diff --git a/packages/config/test/index.ts b/packages/config/test/index.ts index aa49152dcc8..de546334bba 100644 --- a/packages/config/test/index.ts +++ b/packages/config/test/index.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'fs' import path from 'path' import PATH from 'path-name' -import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' +import { getCurrentBranch } from '../../git-utils/test/utils/mock' import getConfig from '@pnpm/config' import PnpmError from '@pnpm/error' import loadNpmConf from '@pnpm/npm-conf' @@ -879,4 +879,4 @@ test('getConfig() sets merge-git-branch-lockfiles when branch matches merge-git- }) expect(config.mergeGitBranchLockfiles).toBe(true) } -}) \ No newline at end of file +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2bf73c6ebce..31cea221a4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6529,7 +6529,7 @@ packages: dev: true /array-union/2.1.0: - resolution: {integrity: sha1-t5hCCtvrHego2ErNii4j0+/oXo0=} + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} /array-uniq/1.0.3: @@ -6792,7 +6792,7 @@ packages: wrap-ansi: 7.0.0 /brace-expansion/1.1.11: - resolution: {integrity: sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=} + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 @@ -8981,7 +8981,7 @@ packages: pkg-dir: 4.2.0 /findup/0.1.5: - resolution: {integrity: sha512-Udxo3C9A6alt2GZ2MNsgnIvX7De0V3VGxeP/x98NSVgSlizcDHdmJza61LI7zJy4OEtSiJyE72s0/+tBl5/ZxA==} + resolution: {integrity: sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=} engines: {node: '>=0.6'} hasBin: true dependencies: @@ -9324,7 +9324,7 @@ packages: dev: true /github-from-package/0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + resolution: {integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=} dev: true /glob-parent/5.1.2: @@ -10058,7 +10058,7 @@ packages: dev: true /is-path-cwd/2.2.0: - resolution: {integrity: sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s=} + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} engines: {node: '>=6'} /is-path-inside/3.0.3: @@ -11193,7 +11193,7 @@ packages: dev: true /manage-path/2.0.0: - resolution: {integrity: sha512-NJhyB+PJYTpxhxZJ3lecIGgh4kwIY2RAh44XvAz9UlqthlQwtPBf62uBVR8XaD8CRuSjQ6TnZH2lNJkbLPZM2A==} + resolution: {integrity: sha1-9M+EV7km7u4qg7FzUBQUvHbrlZc=} dev: true /map-age-cleaner/0.1.3: @@ -11359,7 +11359,7 @@ packages: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} /merge2/1.4.1: - resolution: {integrity: sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=} + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} /methods/1.1.2: @@ -11589,7 +11589,7 @@ packages: dev: true /mute-stream/0.0.7: - resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} + resolution: {integrity: sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=} dev: true /mv/2.1.1: @@ -12004,7 +12004,7 @@ packages: mimic-fn: 2.1.0 /opt-cli/1.5.1: - resolution: {integrity: sha512-iRFQBiQjXZ+LX/8pis04prUhS6FOYcJiZRouofN3rUJEB282b/e0s3jp9vT7aHgXY6TUpgPwu12f0i+qF40Kjw==} + resolution: {integrity: sha1-BNtEexPJa5kusxaFJm9O0NlzbcI=} hasBin: true dependencies: commander: 2.9.0 @@ -12344,7 +12344,7 @@ packages: dev: true /path-type/4.0.0: - resolution: {integrity: sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=} + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} /peek-stream/1.1.3: @@ -13619,11 +13619,11 @@ packages: engines: {node: '>=0.10.0'} /spawn-command/0.0.2: - resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} + resolution: {integrity: sha1-lUThpDygRfhTGqwaSMspva5iM44=} dev: true /spawn-command/0.0.2-1: - resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} + resolution: {integrity: sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=} dev: true /spawndamnit/2.0.0: @@ -14099,7 +14099,7 @@ packages: next-tick: 1.1.0 /tiny-each-async/2.0.3: - resolution: {integrity: sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==} + resolution: {integrity: sha1-jru/1tYpXxNwAD+7NxYq/loKUdE=} dev: false /tinylogic/1.0.3: From f53e40792ea6ea2e41476e95b52123005a56241d Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Fri, 10 Jun 2022 18:31:13 +0300 Subject: [PATCH 20/25] test: fix --- packages/core/test/install/gitBranchLockfile.test.ts | 4 ++-- packages/lockfile-file/test/gitBranchLockfile.test.ts | 4 ++-- packages/lockfile-file/test/lockfileName.test.ts | 4 ++-- packages/lockfile-file/test/read.test.ts | 4 ++-- packages/lockfile-file/test/write.test.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts index daf004bcf90..903291c4588 100644 --- a/packages/core/test/install/gitBranchLockfile.test.ts +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -1,12 +1,12 @@ import fs from 'fs' import path from 'path' -import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { prepareEmpty, preparePackages } from '@pnpm/prepare' import { install, mutateModules } from '@pnpm/core' import { testDefaults } from '../utils' import { WANTED_LOCKFILE } from '@pnpm/constants' import { ProjectManifest } from '@pnpm/types' import writeYamlFile from 'write-yaml-file' +import { getCurrentBranch } from '../../../git-utils/test/utils/mock' test('install with git-branch-lockfile = true', async () => { prepareEmpty() @@ -141,4 +141,4 @@ test('install with --merge-git-branch-lockfiles', async () => { expect(fs.existsSync(otherLockfilePath)).toBe(false) expect(fs.existsSync(WANTED_LOCKFILE)).toBe(true) -}) \ No newline at end of file +}) diff --git a/packages/lockfile-file/test/gitBranchLockfile.test.ts b/packages/lockfile-file/test/gitBranchLockfile.test.ts index 7a06e72e23e..9b026f760bf 100644 --- a/packages/lockfile-file/test/gitBranchLockfile.test.ts +++ b/packages/lockfile-file/test/gitBranchLockfile.test.ts @@ -1,5 +1,5 @@ import path from 'path' -import { getGitBranchLockfileNames } from '@pnpm/lockfile-file/lib/gitBranchLockfile' +import { getGitBranchLockfileNames } from '../lib/gitBranchLockfile' process.chdir(__dirname) @@ -7,4 +7,4 @@ test('getGitBranchLockfileNames()', async () => { const lockfileDir: string = path.join('fixtures', '6') const gitBranchLockfileNames = await getGitBranchLockfileNames(lockfileDir) expect(gitBranchLockfileNames).toEqual(['pnpm-lock.branch.yaml']) -}) \ No newline at end of file +}) diff --git a/packages/lockfile-file/test/lockfileName.test.ts b/packages/lockfile-file/test/lockfileName.test.ts index 51f7a448569..dc0d672a924 100644 --- a/packages/lockfile-file/test/lockfileName.test.ts +++ b/packages/lockfile-file/test/lockfileName.test.ts @@ -1,6 +1,6 @@ -import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { WANTED_LOCKFILE } from '@pnpm/constants' -import { getWantedLockfileName } from '@pnpm/lockfile-file/lib/lockfileName' +import { getWantedLockfileName } from '../lib/lockfileName' +import { getCurrentBranch } from '../../git-utils/test/utils/mock' describe('lockfileName', () => { afterEach(() => { diff --git a/packages/lockfile-file/test/read.test.ts b/packages/lockfile-file/test/read.test.ts index a0ee6a0b37c..a1e0f11062e 100644 --- a/packages/lockfile-file/test/read.test.ts +++ b/packages/lockfile-file/test/read.test.ts @@ -1,5 +1,4 @@ import path from 'path' -import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { existsWantedLockfile, readCurrentLockfile, @@ -8,6 +7,7 @@ import { writeWantedLockfile, } from '@pnpm/lockfile-file' import tempy from 'tempy' +import { getCurrentBranch } from '../../git-utils/test/utils/mock' process.chdir(__dirname) @@ -258,4 +258,4 @@ test('readWantedLockfile() when useGitBranchLockfile and mergeGitBranchLockfiles }, }, }) -}) \ No newline at end of file +}) diff --git a/packages/lockfile-file/test/write.test.ts b/packages/lockfile-file/test/write.test.ts index c714d7ea863..de163e38e4e 100644 --- a/packages/lockfile-file/test/write.test.ts +++ b/packages/lockfile-file/test/write.test.ts @@ -1,6 +1,5 @@ import fs from 'fs' import path from 'path' -import { getCurrentBranch } from '@pnpm/git-utils/test/utils/mock' import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants' import { readCurrentLockfile, @@ -9,6 +8,7 @@ import { } from '@pnpm/lockfile-file' import tempy from 'tempy' import yaml from 'yaml-tag' +import { getCurrentBranch } from '../../git-utils/test/utils/mock' test('writeLockfiles()', async () => { const projectPath = tempy.directory() @@ -228,4 +228,4 @@ test('writeLockfiles() when useGitBranchLockfile', async () => { }) expect(fs.existsSync(path.join(projectPath, WANTED_LOCKFILE))).toBeFalsy() expect(fs.existsSync(path.join(projectPath, `pnpm-lock.${branchName}.yaml`))).toBeTruthy() -}) \ No newline at end of file +}) From 847db0bcd9ae3e9b3db8b041f7979d4d5334ffd1 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 13 Jun 2022 01:01:19 +0300 Subject: [PATCH 21/25] fix: engines in git-utils --- packages/git-utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/git-utils/package.json b/packages/git-utils/package.json index a6156071489..e75932675ef 100644 --- a/packages/git-utils/package.json +++ b/packages/git-utils/package.json @@ -9,7 +9,7 @@ "!*.map" ], "engines": { - "node": ">=14.19" + "node": ">=14.6" }, "scripts": { "lint": "eslint src/**/*.ts test/**/*.ts", From ebb052bf04bebd5bde853840f6463c49d31a4900 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 13 Jun 2022 01:18:09 +0300 Subject: [PATCH 22/25] test: fix --- packages/config/test/index.ts | 10 ++++--- packages/core/package.json | 1 + .../test/install/gitBranchLockfile.test.ts | 12 ++++---- packages/core/tsconfig.json | 3 ++ packages/git-utils/test/utils/mock.ts | 28 ------------------- .../lockfile-file/test/lockfileName.test.ts | 12 ++++---- packages/lockfile-file/test/read.test.ts | 8 ++++-- packages/lockfile-file/test/write.test.ts | 6 ++-- pnpm-lock.yaml | 2 ++ 9 files changed, 35 insertions(+), 47 deletions(-) delete mode 100644 packages/git-utils/test/utils/mock.ts diff --git a/packages/config/test/index.ts b/packages/config/test/index.ts index 72f0f62b392..fb6f88052b0 100644 --- a/packages/config/test/index.ts +++ b/packages/config/test/index.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'fs' import path from 'path' import PATH from 'path-name' -import { getCurrentBranch } from '../../git-utils/test/utils/mock' +import { getCurrentBranch } from '@pnpm/git-utils' import getConfig from '@pnpm/config' import PnpmError from '@pnpm/error' import loadNpmConf from '@pnpm/npm-conf' @@ -10,6 +10,8 @@ import prepare, { prepareEmpty } from '@pnpm/prepare' import symlinkDir from 'symlink-dir' +jest.mock('@pnpm/git-utils', () => ({ getCurrentBranch: jest.fn() })) + // To override any local settings, // we force the default values of config delete process.env.npm_config_depth @@ -854,7 +856,7 @@ test('getConfig() sets merge-git-branch-lockfiles when branch matches merge-git- await fs.writeFile('.npmrc', npmrc, 'utf8') - getCurrentBranch.mockReturnValue('develop') + getCurrentBranch['mockReturnValue']('develop') const { config } = await getConfig({ cliOptions: { global: false, @@ -869,7 +871,7 @@ test('getConfig() sets merge-git-branch-lockfiles when branch matches merge-git- expect(config.mergeGitBranchLockfiles).toBe(false) } { - getCurrentBranch.mockReturnValue('main') + getCurrentBranch['mockReturnValue']('main') const { config } = await getConfig({ cliOptions: { global: false, @@ -882,7 +884,7 @@ test('getConfig() sets merge-git-branch-lockfiles when branch matches merge-git- expect(config.mergeGitBranchLockfiles).toBe(true) } { - getCurrentBranch.mockReturnValue('release/1.0.0') + getCurrentBranch['mockReturnValue']('release/1.0.0') const { config } = await getConfig({ cliOptions: { global: false, diff --git a/packages/core/package.json b/packages/core/package.json index 790e06e9667..56fd8bc6d24 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -71,6 +71,7 @@ "@pnpm/cafs": "workspace:4.0.4", "@pnpm/client": "workspace:7.1.4", "@pnpm/core": "workspace:5.3.1", + "@pnpm/git-utils": "workspace:0.0.0", "@pnpm/logger": "^4.0.0", "@pnpm/package-store": "workspace:13.0.7", "@pnpm/prepare": "workspace:*", diff --git a/packages/core/test/install/gitBranchLockfile.test.ts b/packages/core/test/install/gitBranchLockfile.test.ts index 903291c4588..ba546f29f86 100644 --- a/packages/core/test/install/gitBranchLockfile.test.ts +++ b/packages/core/test/install/gitBranchLockfile.test.ts @@ -5,14 +5,16 @@ import { install, mutateModules } from '@pnpm/core' import { testDefaults } from '../utils' import { WANTED_LOCKFILE } from '@pnpm/constants' import { ProjectManifest } from '@pnpm/types' +import { getCurrentBranch } from '@pnpm/git-utils' import writeYamlFile from 'write-yaml-file' -import { getCurrentBranch } from '../../../git-utils/test/utils/mock' + +jest.mock('@pnpm/git-utils', () => ({ getCurrentBranch: jest.fn() })) test('install with git-branch-lockfile = true', async () => { prepareEmpty() const branchName: string = 'main-branch' - getCurrentBranch.mockReturnValue(branchName) + getCurrentBranch['mockReturnValue'](branchName) const opts = await testDefaults({ useGitBranchLockfile: true, @@ -32,7 +34,7 @@ test('install with git-branch-lockfile = true and no lockfile changes', async () prepareEmpty() const branchName: string = 'main-branch' - getCurrentBranch.mockReturnValue(branchName) + getCurrentBranch['mockReturnValue'](branchName) const manifest: ProjectManifest = { dependencies: { @@ -84,7 +86,7 @@ test('install a workspace with git-branch-lockfile = true', async () => { ]) const branchName: string = 'main-branch' - getCurrentBranch.mockReturnValue(branchName) + getCurrentBranch['mockReturnValue'](branchName) const opts = await testDefaults({ useGitBranchLockfile: true, @@ -119,7 +121,7 @@ test('install with --merge-git-branch-lockfiles', async () => { prepareEmpty() const branchName: string = 'main-branch' - getCurrentBranch.mockReturnValue(branchName) + getCurrentBranch['mockReturnValue'](branchName) const otherLockfilePath: string = path.resolve('pnpm-lock.other.yaml') await writeYamlFile(otherLockfilePath, { diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 0ad13abbdaa..25256f27af9 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -51,6 +51,9 @@ { "path": "../get-context" }, + { + "path": "../git-utils" + }, { "path": "../headless" }, diff --git a/packages/git-utils/test/utils/mock.ts b/packages/git-utils/test/utils/mock.ts deleted file mode 100644 index 96a07880d6d..00000000000 --- a/packages/git-utils/test/utils/mock.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Mock git utils - */ - -const originalAPI = jest.requireActual('@pnpm/git-utils') - -const isGitRepo = jest.fn().mockImplementationOnce(originalAPI.isGitRepo) -const getCurrentBranch = jest.fn().mockImplementation(originalAPI.getCurrentBranch) -const isWorkingTreeClean = jest.fn().mockImplementationOnce(originalAPI.isWorkingTreeClean) -const isRemoteHistoryClean = jest.fn().mockImplementation(originalAPI.isRemoteHistoryClean) - -jest.mock('@pnpm/git-utils', () => { - return { - ...originalAPI, - isGitRepo, - getCurrentBranch, - isWorkingTreeClean, - isRemoteHistoryClean, - } -}) - -export { - isGitRepo, - getCurrentBranch, - isWorkingTreeClean, - isRemoteHistoryClean, - originalAPI, -} \ No newline at end of file diff --git a/packages/lockfile-file/test/lockfileName.test.ts b/packages/lockfile-file/test/lockfileName.test.ts index dc0d672a924..1f4f8602d98 100644 --- a/packages/lockfile-file/test/lockfileName.test.ts +++ b/packages/lockfile-file/test/lockfileName.test.ts @@ -1,10 +1,12 @@ import { WANTED_LOCKFILE } from '@pnpm/constants' +import { getCurrentBranch } from '@pnpm/git-utils' import { getWantedLockfileName } from '../lib/lockfileName' -import { getCurrentBranch } from '../../git-utils/test/utils/mock' + +jest.mock('@pnpm/git-utils', () => ({ getCurrentBranch: jest.fn() })) describe('lockfileName', () => { afterEach(() => { - getCurrentBranch.mockReset() + getCurrentBranch['mockReset']() }) test('returns default lockfile name if useGitBranchLockfile is off', async () => { @@ -12,17 +14,17 @@ describe('lockfileName', () => { }) test('returns git branch lockfile name', async () => { - getCurrentBranch.mockReturnValue('main') + getCurrentBranch['mockReturnValue']('main') await expect(getWantedLockfileName({ useGitBranchLockfile: true })).resolves.toBe('pnpm-lock.main.yaml') }) test('returns git branch lockfile name when git branch contains clashes', async () => { - getCurrentBranch.mockReturnValue('a/b/c') + getCurrentBranch['mockReturnValue']('a/b/c') await expect(getWantedLockfileName({ useGitBranchLockfile: true })).resolves.toBe('pnpm-lock.a!b!c.yaml') }) test('returns git branch lockfile name when git branch contains uppercase', async () => { - getCurrentBranch.mockReturnValue('aBc') + getCurrentBranch['mockReturnValue']('aBc') await expect(getWantedLockfileName({ useGitBranchLockfile: true })).resolves.toBe('pnpm-lock.abc.yaml') }) }) diff --git a/packages/lockfile-file/test/read.test.ts b/packages/lockfile-file/test/read.test.ts index a1e0f11062e..6e6a2523fff 100644 --- a/packages/lockfile-file/test/read.test.ts +++ b/packages/lockfile-file/test/read.test.ts @@ -1,4 +1,5 @@ import path from 'path' +import { getCurrentBranch } from '@pnpm/git-utils' import { existsWantedLockfile, readCurrentLockfile, @@ -7,7 +8,8 @@ import { writeWantedLockfile, } from '@pnpm/lockfile-file' import tempy from 'tempy' -import { getCurrentBranch } from '../../git-utils/test/utils/mock' + +jest.mock('@pnpm/git-utils', () => ({ getCurrentBranch: jest.fn() })) process.chdir(__dirname) @@ -193,7 +195,7 @@ test('existsWantedLockfile()', async () => { }) test('readWantedLockfile() when useGitBranchLockfile', async () => { - getCurrentBranch.mockReturnValue('branch') + getCurrentBranch['mockReturnValue']('branch') const lockfile = await readWantedLockfile(path.join('fixtures', '6'), { ignoreIncompatible: false, }) @@ -233,7 +235,7 @@ test('readWantedLockfile() when useGitBranchLockfile', async () => { }) test('readWantedLockfile() when useGitBranchLockfile and mergeGitBranchLockfiles', async () => { - getCurrentBranch.mockReturnValue('branch') + getCurrentBranch['mockReturnValue']('branch') const lockfile = await readWantedLockfile(path.join('fixtures', '6'), { ignoreIncompatible: false, useGitBranchLockfile: true, diff --git a/packages/lockfile-file/test/write.test.ts b/packages/lockfile-file/test/write.test.ts index de163e38e4e..69a74d8d216 100644 --- a/packages/lockfile-file/test/write.test.ts +++ b/packages/lockfile-file/test/write.test.ts @@ -8,7 +8,9 @@ import { } from '@pnpm/lockfile-file' import tempy from 'tempy' import yaml from 'yaml-tag' -import { getCurrentBranch } from '../../git-utils/test/utils/mock' +import { getCurrentBranch } from '@pnpm/git-utils' + +jest.mock('@pnpm/git-utils', () => ({ getCurrentBranch: jest.fn() })) test('writeLockfiles()', async () => { const projectPath = tempy.directory() @@ -196,7 +198,7 @@ test('writeLockfiles() does not fail if the lockfile has undefined properties', test('writeLockfiles() when useGitBranchLockfile', async () => { const branchName: string = 'branch' - getCurrentBranch.mockReturnValue(branchName) + getCurrentBranch['mockReturnValue'](branchName) const projectPath = tempy.directory() const wantedLockfile = { importers: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b985b33c7ab..e02da78da83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -407,6 +407,7 @@ importers: '@pnpm/error': workspace:3.0.1 '@pnpm/filter-lockfile': workspace:6.0.5 '@pnpm/get-context': workspace:6.1.3 + '@pnpm/git-utils': workspace:0.0.0 '@pnpm/graph-sequencer': 1.0.0 '@pnpm/headless': workspace:18.1.11 '@pnpm/hoist': workspace:6.1.3 @@ -532,6 +533,7 @@ importers: '@pnpm/cafs': link:../cafs '@pnpm/client': link:../client '@pnpm/core': 'link:' + '@pnpm/git-utils': link:../git-utils '@pnpm/logger': 4.0.0 '@pnpm/package-store': link:../package-store '@pnpm/prepare': link:../../privatePackages/prepare From 4df45531d0611456753b28d9af72ba8e3d113637 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 13 Jun 2022 01:42:38 +0300 Subject: [PATCH 23/25] test: fix --- packages/lockfile-file/test/read.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lockfile-file/test/read.test.ts b/packages/lockfile-file/test/read.test.ts index 6e6a2523fff..1becc08c588 100644 --- a/packages/lockfile-file/test/read.test.ts +++ b/packages/lockfile-file/test/read.test.ts @@ -244,7 +244,7 @@ test('readWantedLockfile() when useGitBranchLockfile and mergeGitBranchLockfiles expect(lockfile?.importers).toEqual({ '.': { specifiers: { - 'is-positive': '1.0.0', + 'is-positive': '2.0.0', }, }, }) From 04361ce9bee15f209eb88962efeebe23c9911247 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 13 Jun 2022 01:57:02 +0300 Subject: [PATCH 24/25] test: fix --- packages/lockfile-file/src/gitBranchLockfile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lockfile-file/src/gitBranchLockfile.ts b/packages/lockfile-file/src/gitBranchLockfile.ts index 8260bb85d68..e30d7a3724e 100644 --- a/packages/lockfile-file/src/gitBranchLockfile.ts +++ b/packages/lockfile-file/src/gitBranchLockfile.ts @@ -12,7 +12,7 @@ export async function cleanGitBranchLockfiles (lockfileDir: string) { await Promise.all( gitBranchLockfiles.map(async file => { const filepath: string = path.join(lockfileDir, file) - await fs.rm(filepath) + await fs.unlink(filepath) }) ) } From 958df6a1dd44583a7dc37655f725dfd71ee431e1 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Tue, 14 Jun 2022 23:30:31 +0300 Subject: [PATCH 25/25] docs: add changeset --- .changeset/silent-swans-teach.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .changeset/silent-swans-teach.md diff --git a/.changeset/silent-swans-teach.md b/.changeset/silent-swans-teach.md new file mode 100644 index 00000000000..d3709a6925c --- /dev/null +++ b/.changeset/silent-swans-teach.md @@ -0,0 +1,14 @@ +--- +"@pnpm/config": minor +"@pnpm/core": minor +"@pnpm/get-context": minor +"@pnpm/git-utils": minor +"@pnpm/headless": minor +"@pnpm/lockfile-file": minor +"@pnpm/plugin-commands-installation": minor +"@pnpm/plugin-commands-publishing": minor +"pnpm": minor +"@pnpm/assert-project": minor +--- + +New settings added: use-git-branch-lockfile, merge-git-branch-lockfiles, merge-git-branch-lockfiles-branch-pattern.