mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-02 20:18:15 -05:00
102 lines
3.2 KiB
TypeScript
102 lines
3.2 KiB
TypeScript
import fs from 'fs'
|
|
import path from 'path'
|
|
import { applyPatchToDir } from '@pnpm/patching.apply-patch'
|
|
import { docsUrl } from '@pnpm/cli-utils'
|
|
import { Config, types as allTypes } from '@pnpm/config'
|
|
import { LogBase } from '@pnpm/logger'
|
|
import {
|
|
CreateStoreControllerOptions,
|
|
} from '@pnpm/store-connection-manager'
|
|
import pick from 'ramda/src/pick'
|
|
import renderHelp from 'render-help'
|
|
import tempy from 'tempy'
|
|
import { PnpmError } from '@pnpm/error'
|
|
import { writePackage, ParseWantedDependencyResult } from './writePackage'
|
|
|
|
export function rcOptionsTypes () {
|
|
return pick([], allTypes)
|
|
}
|
|
|
|
export function cliOptionsTypes () {
|
|
return { ...rcOptionsTypes(), 'edit-dir': String, 'ignore-existing': Boolean }
|
|
}
|
|
|
|
export const shorthands = {
|
|
d: '--edit-dir',
|
|
}
|
|
|
|
export const commandNames = ['patch']
|
|
|
|
export function help () {
|
|
return renderHelp({
|
|
description: 'Prepare a package for patching',
|
|
descriptionLists: [{
|
|
title: 'Options',
|
|
list: [
|
|
{
|
|
description: 'The package that needs to be modified will be extracted to this directory',
|
|
name: '--edit-dir',
|
|
},
|
|
{
|
|
description: 'Ignore existing patch files when patching',
|
|
name: '--ignore-existing',
|
|
},
|
|
],
|
|
}],
|
|
url: docsUrl('patch'),
|
|
usages: ['pnpm patch <pkg name>@<version>'],
|
|
})
|
|
}
|
|
|
|
export type PatchCommandOptions = Pick<Config, 'dir' | 'registries' | 'tag' | 'storeDir' | 'rootProjectManifest' | 'lockfileDir'> & CreateStoreControllerOptions & {
|
|
editDir?: string
|
|
reporter?: (logObj: LogBase) => void
|
|
ignoreExisting?: boolean
|
|
}
|
|
|
|
export async function handler (opts: PatchCommandOptions, params: string[]) {
|
|
if (opts.editDir && fs.existsSync(opts.editDir) && fs.readdirSync(opts.editDir).length > 0) {
|
|
throw new PnpmError('PATCH_EDIT_DIR_EXISTS', `The target directory already exists: '${opts.editDir}'`)
|
|
}
|
|
const editDir = opts.editDir ?? tempy.directory()
|
|
const patchedDep = await writePackage(params[0], editDir, opts)
|
|
if (!opts.ignoreExisting && opts.rootProjectManifest?.pnpm?.patchedDependencies) {
|
|
tryPatchWithExistingPatchFile({
|
|
patchedDep,
|
|
patchedDir: editDir,
|
|
patchedDependencies: opts.rootProjectManifest.pnpm.patchedDependencies,
|
|
lockfileDir: opts.lockfileDir ?? opts.dir ?? process.cwd(),
|
|
})
|
|
}
|
|
return `You can now edit the following folder: ${editDir}
|
|
|
|
Once you're done with your changes, run "pnpm patch-commit ${editDir}"`
|
|
}
|
|
|
|
function tryPatchWithExistingPatchFile (
|
|
{
|
|
patchedDep,
|
|
patchedDir,
|
|
patchedDependencies,
|
|
lockfileDir,
|
|
}: {
|
|
patchedDep: ParseWantedDependencyResult
|
|
patchedDir: string
|
|
patchedDependencies: Record<string, string>
|
|
lockfileDir: string
|
|
}
|
|
) {
|
|
if (!patchedDep.alias || !patchedDep.pref) {
|
|
return
|
|
}
|
|
const existingPatchFile = patchedDependencies[`${patchedDep.alias}@${patchedDep.pref}`]
|
|
if (!existingPatchFile) {
|
|
return
|
|
}
|
|
const existingPatchFilePath = path.resolve(lockfileDir, existingPatchFile)
|
|
if (!fs.existsSync(existingPatchFilePath)) {
|
|
throw new PnpmError('PATCH_FILE_NOT_FOUND', `Unable to find patch file ${existingPatchFilePath}`)
|
|
}
|
|
applyPatchToDir({ patchedDir, patchFilePath: existingPatchFilePath })
|
|
}
|