feat: support --patches-dir on patch-commit command (#6215)

close #6202

Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
Tao Zhou
2023-03-15 17:45:17 -07:00
committed by GitHub
parent b92857aa25
commit 40845b9add
7 changed files with 62 additions and 8 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/plugin-commands-patching": minor
"pnpm": minor
---
Allow to set a custom directory for storing patch files via the `patches-dir` setting [#6215](https://github.com/pnpm/pnpm/pull/6215)

View File

@@ -157,6 +157,7 @@ export interface Config {
legacyDirFiltering?: boolean
onlyBuiltDependencies?: string[]
dedupePeerDependents?: boolean
patchesDir?: string
registries: Registries
ignoreWorkspaceRootCheck: boolean

View File

@@ -83,6 +83,7 @@ export const types = Object.assign({
offline: Boolean,
'only-built-dependencies': [String],
'package-import-method': ['auto', 'hardlink', 'clone', 'copy'],
'patches-dir': String,
pnpmfile: String,
'prefer-frozen-lockfile': Boolean,
'prefer-offline': Boolean,

View File

@@ -38,6 +38,7 @@
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/test-fixtures": "workspace:*",
"@types/normalize-path": "^3.0.0",
"@types/ramda": "0.28.20",
"@types/semver": "7.3.13",
"write-yaml-file": "^4.2.0"
@@ -47,6 +48,8 @@
"@pnpm/config": "workspace:*",
"@pnpm/constants": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/lockfile-file": "workspace:*",
"@pnpm/lockfile-utils": "workspace:*",
"@pnpm/modules-yaml": "workspace:*",
"@pnpm/parse-wanted-dependency": "workspace:*",
"@pnpm/patching.apply-patch": "workspace:*",
@@ -55,10 +58,9 @@
"@pnpm/read-package-json": "workspace:*",
"@pnpm/read-project-manifest": "workspace:*",
"@pnpm/store-connection-manager": "workspace:*",
"@pnpm/lockfile-file": "workspace:*",
"@pnpm/lockfile-utils": "workspace:*",
"enquirer": "^2.3.6",
"escape-string-regexp": "^4.0.0",
"normalize-path": "^3.0.0",
"ramda": "npm:@pnpm/ramda@0.28.1",
"realpath-missing": "^1.1.0",
"render-help": "^1.0.3",

View File

@@ -5,6 +5,7 @@ import { Config, types as allTypes } from '@pnpm/config'
import { install } from '@pnpm/plugin-commands-installation'
import { readPackageJsonFromDir } from '@pnpm/read-package-json'
import { tryReadProjectManifest } from '@pnpm/read-project-manifest'
import normalizePath from 'normalize-path'
import pick from 'ramda/src/pick'
import execa from 'safe-execa'
import escapeStringRegexp from 'escape-string-regexp'
@@ -16,7 +17,7 @@ import { parseWantedDependency } from '@pnpm/parse-wanted-dependency'
export const rcOptionsTypes = cliOptionsTypes
export function cliOptionsTypes () {
return pick([], allTypes)
return pick(['patches-dir'], allTypes)
}
export const commandNames = ['patch-commit']
@@ -24,16 +25,25 @@ export const commandNames = ['patch-commit']
export function help () {
return renderHelp({
description: 'Generate a patch out of a directory',
descriptionLists: [],
descriptionLists: [{
title: 'Options',
list: [
{
description: 'The generated patch file will be saved to this directory',
name: '--patches-dir',
},
],
}],
url: docsUrl('patch-commit'),
usages: ['pnpm patch-commit <patchDir>'],
})
}
export async function handler (opts: install.InstallCommandOptions & Pick<Config, 'rootProjectManifest'>, params: string[]) {
export async function handler (opts: install.InstallCommandOptions & Pick<Config, 'patchesDir' | 'rootProjectManifest'>, params: string[]) {
const userDir = params[0]
const lockfileDir = opts.lockfileDir ?? opts.dir ?? process.cwd()
const patchesDir = path.join(lockfileDir, 'patches')
const patchesDirName = normalizePath(path.normalize(opts.patchesDir ?? 'patches'))
const patchesDir = path.join(lockfileDir, patchesDirName)
await fs.promises.mkdir(patchesDir, { recursive: true })
const patchedPkgManifest = await readPackageJsonFromDir(userDir)
const pkgNameAndVersion = `${patchedPkgManifest.name}@${patchedPkgManifest.version}`
@@ -53,7 +63,7 @@ export async function handler (opts: install.InstallCommandOptions & Pick<Config
} else if (!rootProjectManifest.pnpm.patchedDependencies) {
rootProjectManifest.pnpm.patchedDependencies = {}
}
rootProjectManifest.pnpm.patchedDependencies![pkgNameAndVersion] = `patches/${patchFileName}.patch`
rootProjectManifest.pnpm.patchedDependencies![pkgNameAndVersion] = `${patchesDirName}/${patchFileName}.patch`
await writeProjectManifest(rootProjectManifest)
if (opts?.selectedProjectsGraph?.[lockfileDir]) {

View File

@@ -112,6 +112,33 @@ describe('patch and commit', () => {
expect(fs.readFileSync('node_modules/is-positive/index.js', 'utf8')).toContain('// test patching')
})
test('patch and commit with custom patches dir', async () => {
const patchesDir = 'ts/src/../custom-patches'
const output = await patch.handler({ ...defaultPatchOption }, ['is-positive@1.0.0'])
const patchDir = getPatchDirFromPatchOutput(output)
expect(fs.existsSync(path.normalize(patchesDir))).toBe(false)
fs.appendFileSync(path.join(patchDir, 'index.js'), '// test patching', 'utf8')
await patchCommit.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
frozenLockfile: false,
fixLockfile: true,
patchesDir,
}, [patchDir])
const { manifest } = await readProjectManifest(process.cwd())
expect(manifest.pnpm?.patchedDependencies).toStrictEqual({
'is-positive@1.0.0': 'ts/custom-patches/is-positive@1.0.0.patch',
})
expect(fs.existsSync(path.normalize(patchesDir))).toBe(true)
expect(fs.readFileSync(path.join(patchesDir, 'is-positive@1.0.0.patch'), 'utf8')).toContain('// test patching')
expect(fs.readFileSync('node_modules/is-positive/index.js', 'utf8')).toContain('// test patching')
})
test('patch throws an error if the edit-dir already exists and is not empty', async () => {
const editDir = tempy.directory()
fs.writeFileSync(path.join(editDir, 'test.txt'), '', 'utf8')

9
pnpm-lock.yaml generated
View File

@@ -2531,6 +2531,9 @@ importers:
escape-string-regexp:
specifier: ^4.0.0
version: 4.0.0
normalize-path:
specifier: ^3.0.0
version: 3.0.0
ramda:
specifier: npm:@pnpm/ramda@0.28.1
version: /@pnpm/ramda@0.28.1
@@ -2565,6 +2568,9 @@ importers:
'@pnpm/test-fixtures':
specifier: workspace:*
version: link:../../__utils__/test-fixtures
'@types/normalize-path':
specifier: ^3.0.0
version: 3.0.0
'@types/ramda':
specifier: 0.28.20
version: 0.28.20
@@ -8033,7 +8039,7 @@ packages:
'@pnpm/find-workspace-dir': 5.0.1
'@pnpm/find-workspace-packages': 5.0.36(@pnpm/logger@5.0.0)(@yarnpkg/core@4.0.0-rc.14)(typanion@3.12.1)
'@pnpm/logger': 5.0.0
'@pnpm/types': 8.9.0
'@pnpm/types': 8.10.0
'@yarnpkg/core': 4.0.0-rc.14(typanion@3.12.1)
load-json-file: 7.0.1
meow: 10.1.5
@@ -8582,6 +8588,7 @@ packages:
/@pnpm/types@8.9.0:
resolution: {integrity: sha512-3MYHYm8epnciApn6w5Fzx6sepawmsNU7l6lvIq+ER22/DPSrr83YMhU/EQWnf4lORn2YyiXFj0FJSyJzEtIGmw==}
engines: {node: '>=14.6'}
dev: false
/@pnpm/util.lex-comparator@1.0.0:
resolution: {integrity: sha512-3aBQPHntVgk5AweBWZn+1I/fqZ9krK/w01197aYVkAJQGftb+BVWgEepxY5GChjSW12j52XX+CmfynYZ/p0DFQ==}