From 1694608c55459907fef6ea863414802ac5f2d2ae Mon Sep 17 00:00:00 2001 From: andyjy Date: Sat, 1 Apr 2023 16:20:06 +0100 Subject: [PATCH 1/2] Add --ignore-missing flag to continue without error on missing packages --- README.md | 8 ++++++++ .../__snapshots__/ignore-missing.test.ts.snap | 18 ++++++++++++++++++ .../ignore-missing/ignore-missing.sh | 17 +++++++++++++++++ .../ignore-missing/ignore-missing.test.ts | 5 +++++ integration-tests/ignore-missing/package.json | 11 +++++++++++ .../patches/left-pad+1.1.3.patch | 13 +++++++++++++ .../patches/missing-package+1.0.0.patch | 13 +++++++++++++ integration-tests/ignore-missing/yarn.lock | 8 ++++++++ src/applyPatches.ts | 12 ++++++++++-- src/index.ts | 12 ++++++++++++ 10 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap create mode 100755 integration-tests/ignore-missing/ignore-missing.sh create mode 100644 integration-tests/ignore-missing/ignore-missing.test.ts create mode 100644 integration-tests/ignore-missing/package.json create mode 100644 integration-tests/ignore-missing/patches/left-pad+1.1.3.patch create mode 100644 integration-tests/ignore-missing/patches/missing-package+1.0.0.patch create mode 100644 integration-tests/ignore-missing/yarn.lock diff --git a/README.md b/README.md index 0353f942..565017eb 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,14 @@ Run `patch-package` without arguments to apply all patches in your project. Specify the name for the directory in which the patch files are located +- `--ignore-missing` + + Ignores patches for packages that are not present in node_modules. + This is useful when working with monorepos and wanting to install sub-packages + separately from the root package, with pruned dependencies. + + See https://github.com/ds300/patch-package/issues/339 for background. + #### Notes To apply patches individually, you may use `git`: diff --git a/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap b/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap new file mode 100644 index 00000000..a8ea141e --- /dev/null +++ b/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Test ignore-missing: patch-package returns 1 on missing package 1`] = ` +"SNAPSHOT: patch-package returns 1 on missing package +Error: Patch file found for package missing-package which is not present at node_modules/missing-package +--- +patch-package finished with 1 error(s). +END SNAPSHOT" +`; + +exports[`Test ignore-missing: adding --ignore-missing forces patch-package to return 0 1`] = ` +"SNAPSHOT: adding --ignore-missing forces patch-package to return 0 +patch-package 0.0.0 +Applying patches... +left-pad@1.1.3 ✔ +Skipping missing missing-package@1.0.0 ✔ +END SNAPSHOT" +`; diff --git a/integration-tests/ignore-missing/ignore-missing.sh b/integration-tests/ignore-missing/ignore-missing.sh new file mode 100755 index 00000000..39a4c35d --- /dev/null +++ b/integration-tests/ignore-missing/ignore-missing.sh @@ -0,0 +1,17 @@ +# make sure errors stop the script +set -e + +echo "add patch-package" +yarn add $1 +alias patch-package=./node_modules/.bin/patch-package + +(>&2 echo "SNAPSHOT: patch-package returns 1 on missing package") +if patch-package; +then + exit 1 +fi +(>&2 echo "END SNAPSHOT") + +echo "SNAPSHOT: adding --ignore-missing forces patch-package to return 0" +patch-package --ignore-missing; +echo "END SNAPSHOT" diff --git a/integration-tests/ignore-missing/ignore-missing.test.ts b/integration-tests/ignore-missing/ignore-missing.test.ts new file mode 100644 index 00000000..5b5b8717 --- /dev/null +++ b/integration-tests/ignore-missing/ignore-missing.test.ts @@ -0,0 +1,5 @@ +import { runIntegrationTest } from "../runIntegrationTest" +runIntegrationTest({ + projectName: "ignore-missing", + shouldProduceSnapshots: true, +}) diff --git a/integration-tests/ignore-missing/package.json b/integration-tests/ignore-missing/package.json new file mode 100644 index 00000000..287cde3b --- /dev/null +++ b/integration-tests/ignore-missing/package.json @@ -0,0 +1,11 @@ +{ + "name": "ignore-missing", + "version": "1.0.0", + "description": "integration test for patch-package", + "main": "index.js", + "author": "", + "license": "ISC", + "dependencies": { + "left-pad": "1.1.3" + } +} diff --git a/integration-tests/ignore-missing/patches/left-pad+1.1.3.patch b/integration-tests/ignore-missing/patches/left-pad+1.1.3.patch new file mode 100644 index 00000000..0600ef9f --- /dev/null +++ b/integration-tests/ignore-missing/patches/left-pad+1.1.3.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/left-pad/index.js b/node_modules/left-pad/index.js +index 26f73ff..60f3f56 100644 +--- a/node_modules/left-pad/index.js ++++ b/node_modules/left-pad/index.js +@@ -4,7 +4,7 @@ + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. */ + 'use strict'; +-module.exports = leftPad; ++module.exports = patch-package; + + var cache = [ + '', diff --git a/integration-tests/ignore-missing/patches/missing-package+1.0.0.patch b/integration-tests/ignore-missing/patches/missing-package+1.0.0.patch new file mode 100644 index 00000000..e294d98b --- /dev/null +++ b/integration-tests/ignore-missing/patches/missing-package+1.0.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/left-pad/index.js b/node_modules/left-pad/index.js +index 26f73ff..60f3f56 100644 +--- a/node_modules/left-pad/index.js ++++ b/node_modules/left-pad/index.js +@@ -7,7 +7,7 @@ + module.exports = leftPad; + + var cache = [ +- '', ++ "", + ' ', + ' ', + ' ', \ No newline at end of file diff --git a/integration-tests/ignore-missing/yarn.lock b/integration-tests/ignore-missing/yarn.lock new file mode 100644 index 00000000..392d269a --- /dev/null +++ b/integration-tests/ignore-missing/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +left-pad@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.1.3.tgz#612f61c033f3a9e08e939f1caebeea41b6f3199a" + integrity sha1-YS9hwDPzqeCOk58crr7qQbbzGZo= diff --git a/src/applyPatches.ts b/src/applyPatches.ts index 2bc4aba3..28e483e6 100644 --- a/src/applyPatches.ts +++ b/src/applyPatches.ts @@ -33,18 +33,23 @@ function getInstalledPackageVersion({ pathSpecifier, isDevOnly, patchFilename, + ignoreMissing, }: { appPath: string path: string pathSpecifier: string isDevOnly: boolean patchFilename: string + ignoreMissing: boolean }): null | string { const packageDir = join(appPath, path) if (!existsSync(packageDir)) { if (process.env.NODE_ENV === "production" && isDevOnly) { return null } + if (ignoreMissing) { + return null + } let err = `${chalk.red("Error:")} Patch file found for package ${posix.basename( @@ -85,12 +90,14 @@ export function applyPatchesForApp({ patchDir, shouldExitWithError, shouldExitWithWarning, + ignoreMissing, }: { appPath: string reverse: boolean patchDir: string shouldExitWithError: boolean shouldExitWithWarning: boolean + ignoreMissing: boolean }): void { const patchesDirectory = join(appPath, patchDir) const files = findPatchFiles(patchesDirectory) @@ -133,11 +140,12 @@ export function applyPatchesForApp({ (process.env.NODE_ENV === "production" && packageIsDevDependency({ appPath, packageDetails })), patchFilename, + ignoreMissing, }) if (!installedPackageVersion) { - // it's ok we're in production mode and this is a dev only package + // it's ok we're ignoring missing packages OR in production mode and this is a dev only package console.log( - `Skipping dev-only ${chalk.bold( + `Skipping ${ignoreMissing ? "missing" : "dev-only"} ${chalk.bold( pathSpecifier, )}@${version} ${chalk.blue("✔")}`, ) diff --git a/src/index.ts b/src/index.ts index c9ccc236..9f057d45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,7 @@ const argv = minimist(process.argv.slice(2), { "error-on-fail", "error-on-warn", "create-issue", + "ignore-missing", ], string: ["patch-dir"], }) @@ -82,12 +83,15 @@ if (argv.version || argv.v) { const shouldExitWithWarning = !!argv["error-on-warn"] + const ignoreMissing = !!argv["ignore-missing"] + applyPatchesForApp({ appPath, reverse, patchDir, shouldExitWithError, shouldExitWithWarning, + ignoreMissing, }) } } @@ -144,6 +148,14 @@ Usage: and patch file updates (https://github.com/ds300/patch-package/issues/37), but might be useful in other contexts too. + ${chalk.bold("--ignore-missing")} + + Ignores patches for packages that are not present in node_modules. + This is useful when working with monorepos and wanting to install sub-packages + separately from the root package, with pruned dependencies. + + See https://github.com/ds300/patch-package/issues/339 for background. + 2. Creating patch files ======================= From 0aef3ba8ca263380b769381e84ce71d772567042 Mon Sep 17 00:00:00 2001 From: andyjy Date: Wed, 5 Jul 2023 15:27:20 +0100 Subject: [PATCH 2/2] add support for PATCH_PACKAGE_IGNORE_MISSING env var --- .../__snapshots__/ignore-missing.test.ts.snap | 9 +++++++++ integration-tests/ignore-missing/ignore-missing.sh | 5 +++++ src/index.ts | 10 +++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap b/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap index a8ea141e..a1b3ff33 100644 --- a/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap +++ b/integration-tests/ignore-missing/__snapshots__/ignore-missing.test.ts.snap @@ -16,3 +16,12 @@ left-pad@1.1.3 ✔ Skipping missing missing-package@1.0.0 ✔ END SNAPSHOT" `; + +exports[`Test ignore-missing: setting PATCH_PACKAGE_IGNORE_MISSING=1 forces patch-package to return 0 1`] = ` +"SNAPSHOT: setting PATCH_PACKAGE_IGNORE_MISSING=1 forces patch-package to return 0 +patch-package 0.0.0 +Applying patches... +left-pad@1.1.3 ✔ +Skipping missing missing-package@1.0.0 ✔ +END SNAPSHOT" +`; diff --git a/integration-tests/ignore-missing/ignore-missing.sh b/integration-tests/ignore-missing/ignore-missing.sh index 39a4c35d..b44f60f5 100755 --- a/integration-tests/ignore-missing/ignore-missing.sh +++ b/integration-tests/ignore-missing/ignore-missing.sh @@ -15,3 +15,8 @@ fi echo "SNAPSHOT: adding --ignore-missing forces patch-package to return 0" patch-package --ignore-missing; echo "END SNAPSHOT" + +export PATCH_PACKAGE_IGNORE_MISSING=1 +echo "SNAPSHOT: setting PATCH_PACKAGE_IGNORE_MISSING=1 forces patch-package to return 0" +patch-package; +echo "END SNAPSHOT" diff --git a/src/index.ts b/src/index.ts index fd04f626..df47e879 100644 --- a/src/index.ts +++ b/src/index.ts @@ -86,7 +86,8 @@ if (argv.version || argv.v) { const shouldExitWithWarning = !!argv["error-on-warn"] - const ignoreMissing = !!argv["ignore-missing"] + const ignoreMissing = + !!argv["ignore-missing"] || !!process.env.PATCH_PACKAGE_IGNORE_MISSING applyPatchesForApp({ appPath, @@ -157,6 +158,13 @@ Usage: This is useful when working with monorepos and wanting to install sub-packages separately from the root package, with pruned dependencies. + This option is can also be set via the environment variable + PATCH_PACKAGE_IGNORE_MISSING=1. Setting this env variable during the deployment + build process is recommended instead of using the --ignore-missing command option + when we want to ignore missing packages during deployment (of a monorepo with + pruned dependencies), but ensure we fail loudly during development if any + dependencies are moved or removed without updating the patches accordingly. + See https://github.com/ds300/patch-package/issues/339 for background.