mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-30 21:11:55 -04:00
fix: pnpm patch should ignore files that are not included in the patched package (#6596)
close #6565 --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
@@ -5,14 +5,17 @@ import { type 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 glob from 'fast-glob'
|
||||
import normalizePath from 'normalize-path'
|
||||
import pick from 'ramda/src/pick'
|
||||
import equals from 'ramda/src/equals'
|
||||
import execa from 'safe-execa'
|
||||
import escapeStringRegexp from 'escape-string-regexp'
|
||||
import renderHelp from 'render-help'
|
||||
import tempy from 'tempy'
|
||||
import { writePackage } from './writePackage'
|
||||
import { parseWantedDependency } from '@pnpm/parse-wanted-dependency'
|
||||
import packlist from 'npm-packlist'
|
||||
|
||||
export const rcOptionsTypes = cliOptionsTypes
|
||||
|
||||
@@ -49,7 +52,10 @@ export async function handler (opts: install.InstallCommandOptions & Pick<Config
|
||||
const pkgNameAndVersion = `${patchedPkgManifest.name}@${patchedPkgManifest.version}`
|
||||
const srcDir = tempy.directory()
|
||||
await writePackage(parseWantedDependency(pkgNameAndVersion), srcDir, opts)
|
||||
const patchContent = await diffFolders(srcDir, userDir)
|
||||
|
||||
const patchedPkgDir = await preparePkgFilesForDiff(userDir)
|
||||
const patchContent = await diffFolders(srcDir, patchedPkgDir)
|
||||
|
||||
const patchFileName = pkgNameAndVersion.replace('/', '__')
|
||||
await fs.promises.writeFile(path.join(patchesDir, `${patchFileName}.patch`), patchContent, 'utf8')
|
||||
const { writeProjectManifest, manifest } = await tryReadProjectManifest(lockfileDir)
|
||||
@@ -129,3 +135,36 @@ function removeTrailingAndLeadingSlash (p: string) {
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
/**
|
||||
* Link files from the source directory to a new temporary directory,
|
||||
* but only if not all files in the source directory should be included in the package.
|
||||
* If all files should be included, return the original source directory without creating any links.
|
||||
* This is required in order for the diff to not include files that are not part of the package.
|
||||
*/
|
||||
async function preparePkgFilesForDiff (src: string): Promise<string> {
|
||||
const files = Array.from(new Set((await packlist({ path: src })).map((f) => path.join(f))))
|
||||
// If there are no extra files in the source directories, then there is no reason
|
||||
// to copy.
|
||||
if (await areAllFilesInPkg(files, src)) {
|
||||
return src
|
||||
}
|
||||
const dest = tempy.directory()
|
||||
await Promise.all(
|
||||
files.map(async (file) => {
|
||||
const srcFile = path.join(src, file)
|
||||
const destFile = path.join(dest, file)
|
||||
const destDir = path.dirname(destFile)
|
||||
await fs.promises.mkdir(destDir, { recursive: true })
|
||||
await fs.promises.link(srcFile, destFile)
|
||||
})
|
||||
)
|
||||
return dest
|
||||
}
|
||||
|
||||
async function areAllFilesInPkg (files: string[], basePath: string) {
|
||||
const allFiles = await glob('**', {
|
||||
cwd: basePath,
|
||||
})
|
||||
return equals(allFiles.sort(), files.sort())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user