Giter Site home page Giter Site logo

ds300 / patch-package Goto Github PK

View Code? Open in Web Editor NEW
9.9K 40.0 276.0 2.41 MB

Fix broken node modules instantly 🏃🏽‍♀️💨

License: MIT License

JavaScript 1.22% TypeScript 80.87% Shell 17.92%
javascript javascript-tools nodejs node node-js node-modules patch patcher diff dependencies

patch-package's Introduction

patch-package

patch-package lets app authors instantly make and keep fixes to npm dependencies. It's a vital band-aid for those of us living on the bleeding edge.

# fix a bug in one of your dependencies
vim node_modules/some-package/brokenFile.js

# run patch-package to create a .patch file
npx patch-package some-package

# commit the patch file to share the fix with your team
git add patches/some-package+3.14.15.patch
git commit -m "fix brokenFile.js in some-package"

Patches created by patch-package are automatically and gracefully applied when you use npm(>=5) or yarn.

No more waiting around for pull requests to be merged and published. No more forking repos just to fix that one tiny thing preventing your app from working.

Set-up

In package.json

 "scripts": {
+  "postinstall": "patch-package"
 }

Then

npm

npm i patch-package

You can use --save-dev if you don't need to run npm in production, e.g. if you're making a web frontend.

yarn v1

yarn add patch-package postinstall-postinstall

You can use --dev if you don't need to run yarn in production, e.g. if you're making a web frontend.

To understand why yarn needs the postinstall-postinstall package see: Why use postinstall-postinstall

yarn workspaces

Same as for yarn ☝️ Note that if you want to patch un-hoisted packages you'll need to repeat the setup process for the child package. Also make sure you're in the child package directory when you run patch-package to generate the patch files.

yarn v2+

yarn 2+ have native support for patching dependencies via yarn patch. You do not need to use patch-package on these projects.

pnpm

pnpm has native support for patching dependencies via pnpm patch. You do not need to use patch-package on these projects.

Heroku

For patch-package to work on Heroku applications, you must specify NPM_CONFIG_PRODUCTION=false or YARN_PRODUCTION=false. See this issue for more details.

Docker and CI

  • If having errors about working directory ("cannot run in wd [...]") when building in Docker, you might need to adjust configuration in .npmrc. See #185.
  • In your Dockerfile, remember to copy over the patch files before running [npm|yarn] install
  • If you cache node_modules rather than running yarn install every time, make sure that the patches dir is included in your cache key somehow. Otherwise if you update a patch then the change may not be reflected on subsequent CI runs.

CircleCI

Create a hash of your patches before loading/saving your cache. If using a Linux machine, run md5sum patches/* > patches.hash. If running on a macOS machine, use md5 patches/* > patches.hash

- run:
    name: patch-package hash
    command: md5sum patches/* > patches.hash

Then, update your hash key to include a checksum of that file:

- restore_cache:
    key:
      app-node_modules-v1-{{ checksum "yarn.lock" }}-{{ checksum "patches.hash"
      }}

As well as the save_cache

- save_cache:
    key:
      app-node_modules-v1-{{ checksum "yarn.lock" }}-{{ checksum "patches.hash"
      }}
    paths:
      - ./node_modules

Usage

Making patches

First make changes to the files of a particular package in your node_modules folder, then run

yarn patch-package package-name

or use npx (included with npm > 5.2)

npx patch-package package-name

where package-name matches the name of the package you made changes to.

If this is the first time you've used patch-package, it will create a folder called patches in the root dir of your app. Inside will be a file called package-name+0.44.0.patch or something, which is a diff between normal old package-name and your fixed version. Commit this to share the fix with your team.

Options

  • --create-issue

    For packages whose source is hosted on GitHub this option opens a web browser with a draft issue based on your diff.

  • --use-yarn

    By default, patch-package checks whether you use npm or yarn based on which lockfile you have. If you have both, it uses npm by default. Set this option to override that default and always use yarn.

  • --exclude <regexp>

    Ignore paths matching the regexp when creating patch files. Paths are relative to the root dir of the package to be patched.

    Default value: package\\.json$

  • --include <regexp>

    Only consider paths matching the regexp when creating patch files. Paths are relative to the root dir of the package to be patched.

    Default value: .*

  • --case-sensitive-path-filtering

    Make regexps used in --include or --exclude filters case-sensitive.

  • --patch-dir

    Specify the name for the directory in which to put the patch files.

Nested packages

If you are trying to patch a package at, e.g. node_modules/package/node_modules/another-package you can just put a / between the package names:

npx patch-package package/another-package

It works with scoped packages too

npx patch-package @my/package/@my/other-package

Updating patches

Use exactly the same process as for making patches in the first place, i.e. make more changes, run patch-package, commit the changes to the patch file.

Applying patches

Run patch-package without arguments to apply all patches in your project.

Options

  • --error-on-fail

    Forces patch-package to exit with code 1 after failing.

    When running locally patch-package always exits with 0 by default. This happens even after failing to apply patches because otherwise yarn.lock and package.json might get out of sync with node_modules, which can be very confusing.

    --error-on-fail is switched on by default on CI.

    See #86 for background.

  • --reverse

    Un-applies all patches.

    Note that this will fail if the patched files have changed since being patched. In that case, you'll probably need to re-install node_modules.

    This option was added to help people using CircleCI avoid an issue around caching and patch file updates but might be useful in other contexts too.

  • --patch-dir

    Specify the name for the directory in which the patch files are located

Notes

To apply patches individually, you may use git:

git apply --ignore-whitespace patches/package-name+0.44.2.patch

or patch in unixy environments:

patch -p1 -i patches/package-name+0.44.2.patch

Dev-only patches

If you deploy your package to production (e.g. your package is a server) then any patched devDependencies will not be present when patch-package runs in production. It will happily ignore those patch files if the package to be patched is listed directly in the devDependencies of your package.json. If it's a transitive dependency patch-package can't detect that it is safe to ignore and will throw an error. To fix this, mark patches for transitive dev dependencies as dev-only by renaming from, e.g.

package-name+0.44.0.patch

to

package-name+0.44.0.dev.patch

This will allow those patch files to be safely ignored when NODE_ENV=production.

Creating multiple patches for the same package

💡 This is an advanced feature and is not recommended unless you really, really need it.

Let's say you have a patch for react-native called

  • patches/react-native+0.72.0.patch

If you want to add another patch file to react-native, you can use the --append flag while supplying a name for the patch.

Just make you changes inside node_modules/react-native then run e.g.

npx patch-package react-native --append 'fix-touchable-opacity'

This will create a new patch file while renaming the old patch file so that you now have:

  • patches/react-native+0.72.0+001+initial.patch
  • patches/react-native+0.72.0+002+fix-touchable-opacity.patch

The patches are ordered in a sequence, so that they can build on each other if necessary. Think of these as commits in a git history.

Updating a sequenced patch file

If the patch file is the last one in the sequence, you can just make your changes inside e.g. node_modules/react-native and then run

npx patch-package react-native

This will update the last patch file in the sequence.

If the patch file is not the last one in the sequence you need to use the --rebase feature to un-apply the succeeding patch files first.

Using the example above, let's say you want to update the 001+initial patch but leave the other patch alone. You can run

npx patch-package react-native --rebase patches/react-native+0.72.0+001+initial.patch

This will undo the 002-fix-touchable-opacity patch file. You can then make your changes and run

npx patch-package react-native

to finish the rebase by updating the 001+initial patch file and re-apply the 002-fix-touchable-opacity patch file, leaving you with all patches applied and up-to-date.

Inserting a new patch file in the middle of an existing sequence

Using the above example, let's say you want to insert a new patch file between the 001+initial and 002+fix-touchable-opacity patch files. You can run

npx patch-package react-native --rebase patches/react-native+0.72.0+001+initial.patch

This will undo the 002-fix-touchable-opacity patch file. You can then make any changes you want to insert in a new patch file and run

npx patch-package react-native --append 'fix-console-warnings'

This will create a new patch file while renaming any successive patches to maintain the sequence order, leaving you with

  • patches/react-native+0.72.0+001+initial.patch
  • patches/react-native+0.72.0+002+fix-console-warnings.patch
  • patches/react-native+0.72.0+003+fix-touchable-opacity.patch

To insert a new patch file at the start of the sequence, you can run

npx patch-package react-native --rebase 0

Which will un-apply all patch files in the sequence. Then follow the process above to create a new patch file numbered 001.

Deleting a sequenced patch file

To delete a sequenced patch file, just delete it, then remove and reinstall your node_modules folder.

If you deleted one of the patch files other than the last one, you don't need to update the sequence numbers in the successive patch file names, but you might want to do so to keep things tidy.

Partially applying a broken patch file

Normally patch application is atomic per patch file. i.e. if a patch file contains an error anywhere then none of the changes in the patch file will be applied and saved to disk.

This can be problematic if you have a patch with many changes and you want to keep some of them and update others.

In this case you can use the --partial option. Patch-package will apply as many of the changes as it can and then leave it to you to fix the rest.

Any errors encountered will be written to a file ./patch-package-errors.log to help you keep track of what needs fixing.

Benefits of patching over forking

  • Sometimes forks need extra build steps, e.g. with react-native for Android. Forget that noise.
  • Get told in big red letters when the dependency changed and you need to check that your fix is still valid.
  • Keep your patches colocated with the code that depends on them.
  • Patches can be reviewed as part of your normal review process, forks probably can't

When to fork instead

  • The change is too consequential to be developed in situ.
  • The change would be useful to other people as-is.
  • You can afford to make a proper PR to upstream.

Isn't this dangerous?

Nope. The technique is quite robust. Here are some things to keep in mind though:

  • It's easy to forget to run yarn or npm when switching between branches that do and don't have patch files.
  • Long lived patches can be costly to maintain if they affect an area of code that is updated regularly and you want to update the package regularly too.
  • Big semantic changes can be hard to review. Keep them small and obvious or add plenty of comments.
  • Changes can also impact the behaviour of other untouched packages. It's normally obvious when this will happen, and often desired, but be careful nonetheless.

Why use postinstall-postinstall with Yarn?

Most times when you do a yarn, yarn add, yarn remove, or yarn install (which is the same as just yarn) Yarn will completely replace the contents of your node_modules with freshly unpackaged modules. patch-package uses the postinstall hook to modify these fresh modules, so that they behave well according to your will.

Yarn only runs the postinstall hook after yarn and yarn add, but not after yarn remove. The postinstall-postinstall package is used to make sure your postinstall hook gets executed even after a yarn remove.

License

MIT

Empowered by Futurice's open source sponsorship program

patch-package's People

Contributors

akwodkiewicz avatar asadm avatar ashmind avatar bdwain avatar bloodyknuckles avatar bschlenk avatar cherniavskii avatar christianbundy avatar danielruf avatar davidpett avatar dijonkitchen avatar dmhalejr avatar ds300 avatar gomain avatar haroenv avatar harriha avatar impaler avatar janv avatar jimmyltsinn avatar kevinvlaanderen avatar lots0logs avatar maman avatar mhekert avatar milahu avatar nminhnguyen avatar orta avatar rokiyama avatar snowystinger avatar srandazzo avatar stianjensen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

patch-package's Issues

Patch fails when created with v6.0.0-5

Hi,

First, congrats for the project, I think helps a lot the Developer Experience (DX).

So, after running into this whitespace issue #36, I moved to the beta npm channel but got another one:

The patch is created OK:

❯ cat patches/localforage+1.7.1.patch
diff --git node_modules/localforage/src/drivers/indexeddb.js node_modules/localforage/src/drivers/indexeddb.js
index c77786f..f54a612 100644
--- node_modules/localforage/src/drivers/indexeddb.js
+++ node_modules/localforage/src/drivers/indexeddb.js
@@ -664,7 +664,12 @@ function setItem(key, value, callback) {

                             resolve(value);
                         };
-                        transaction.onabort = transaction.onerror = function() {
+
+                        transaction.onerror = function() {
+                            reject(req.error);
+                        };
+
+                        transaction.onabort = function() {
                             var err = req.error
                                 ? req.error
                                 : req.transaction.error;

But yarn patch-package fails with:

❯ yarn patch-package
yarn run v1.5.1
$ /Users/gonzalo/dev/lernin/game-wrapper-app/node_modules/.bin/patch-package
patch-package: Applying patches...

**ERROR** Failed to apply patch for package localforage

  This error was caused because patch-package cannot apply the following patch file:

    patches/localforage+1.7.1.patch

  If removing node_modules and trying again doesn't fix this, maybe there was
  an accidental change made to the patch file? If not, then it's probably a bug
  in patch-package, so please submit a bug report. Thanks!

    https://github.com/ds300/patch-package/issues


error An unexpected error occurred: "Command failed.
Exit code: 1
Command: sh
Arguments: -c /Users/gonzalo/dev/lernin/game-wrapper-app/node_modules/.bin/patch-package
Directory: /Users/gonzalo/dev/lernin/game-wrapper-app
Output:
".
info If you think this is a bug, please open a bug report with the information provided in "/Users/gonzalo/dev/lernin/game-wrapper-app/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Aplying the patch manually works:

❯ patch -p0 < patches/localforage+1.7.1.patch
patching file node_modules/localforage/src/drivers/indexeddb.js

Thank you.

Should work with npm

Now that we have npm5, folks who didn't jump on the yarn train are feeling left in the cold when they try to use this:

Error: Command failed: cp '/Users/charlie/slack-desktop/yarn.lock' /var/folders/80/5h887mds2w9_dbcsnt2qh1000000gp/T/tmp-79561F6V6u24aVt5x
cp: /Users/charlie/slack-desktop/yarn.lock: No such file or directory

😔😔😔

[Feature] Support custom `git diff` options

Yesterday, patch-package created a diff that contained all of the patched file, even though only some lines changed. The culprit in this case were differences in line-endings; my locally changed files had only LFs in them (edited on Mac) but the files installed via npm contained (CRs).
I then created a patch manually with --strip-trailing-cr which only included the lines that actually changed.

I'm note sure whether the Git config affects how patches are created and applied, so I propose adding an option to patch-package (and maybe make it the default?) to ignore changes w.r.t. line endings and/or whitespaces.

Maybe you want to ponder adding an option to pass arbitrary parameters to git diff just in case ;)

Doesn't work with npm CI

patch-package fails when using npm ci to install packages. yarn install and npm install works well. patch-package is missing from the node_modules/.bin folder, but other binaries of other dependencies are there.

npm 5.8.0
patch-package 5.1.1

0 info it worked if it ends with ok
1 verbose cli [ '/Users/danieldecsi/.nvm/versions/node/v9.4.0/bin/node',
1 verbose cli   '/Users/danieldecsi/.nvm/versions/node/v9.4.0/bin/npm',
1 verbose cli   'run',
1 verbose cli   'prepare' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prepare' ]
5 info lifecycle [email protected]~prepare: [email protected]
6 verbose lifecycle [email protected]~prepare: unsafe-perm in lifecycle true
7 verbose lifecycle [email protected]~prepare: PATH: /Users/danieldecsi/.nvm/versions/node/v9.4.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/danieldecsi/Projects/projectname-npm-ci/node_modules/.bin:/Users/danieldecsi/.nvm/versions/node/v9.4.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/danieldecsi/Projects/projectname-npm-ci/node_modules/postinstall-prepare/node_modules/.bin:/Users/danieldecsi/Projects/projectname-npm-ci/node_modules/.bin:/Users/danieldecsi/.rbenv/shims:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin:/Users/danieldecsi/.nvm/versions/node/v9.4.0/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/danieldecsi/Library/Android/sdk/platform-tools:/Users/danieldecsi/Library/Android/sdk/tools
8 verbose lifecycle [email protected]~prepare: CWD: /Users/danieldecsi/Projects/projectname-npm-ci
9 silly lifecycle [email protected]~prepare: Args: [ '-c', 'patch-package' ]
10 info lifecycle [email protected]~prepare: Failed to exec prepare script
11 verbose stack Error: [email protected] prepare: `patch-package`
11 verbose stack spawn ENOENT
11 verbose stack     at ChildProcess.<anonymous> (/Users/danieldecsi/.nvm/versions/node/v9.4.0/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:48:18)
11 verbose stack     at ChildProcess.emit (events.js:160:13)
11 verbose stack     at maybeClose (internal/child_process.js:943:16)
11 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:220:5)
12 verbose pkgid [email protected]
13 verbose cwd /Users/danieldecsi/Projects/projectname-npm-ci
14 verbose Darwin 17.4.0
15 verbose argv "/Users/danieldecsi/.nvm/versions/node/v9.4.0/bin/node" "/Users/danieldecsi/.nvm/versions/node/v9.4.0/bin/npm" "run" "prepare"
16 verbose node v9.4.0
17 verbose npm  v5.8.0
18 error file sh
19 error code ELIFECYCLE
20 error errno ENOENT
21 error syscall spawn
22 error [email protected] prepare: `patch-package`
22 error spawn ENOENT
23 error Failed at the [email protected] prepare script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

Related part of our package.json file:

"scripts": {
	"prepare": "patch-package"
},
"dependencies": {
	"apsl-react-native-button": "^3.1.0",
	"babel-plugin-transform-decorators-legacy": "^1.3.4",
	"color": "^2.0.0",
	"date-easter": "^0.2.2",
	"deepmerge": "^1.5.2",
	"fuse.js": "^3.2.0",
	"lodash.clonedeep": "^4.5.0",
	"lodash.debounce": "^4.0.8",
	"lodash.set": "^4.3.2",
	"lodash.throttle": "^4.1.1",
	"memoarray": "^0.1.0",
	"memobind": "^0.5.0",
	"moment": "git+https://github.com/tqc/moment#no-dynamic-import",
	"postinstall-prepare": "^1.0.1",
	"prop-types": "^15.5.10",
	"react": "16.0.0-beta.5",
	"react-extra-prop-types": "^0.3.1",
	"react-native": "0.49.3",
	"react-native-adjust": "^4.12.0",
	"react-native-android-location-services-dialog-box": "^2.3.2",
	"react-native-appboy-sdk": "^1.5.1",
	"react-native-collapsible": "^0.9.0",
	"react-native-config": "^0.9.0",
	"react-native-dash": "team-supercharge/react-native-dash#master",
	"react-native-deep-linking": "^2.1.0",
	"react-native-device-info": "0.21.2",
	"react-native-extended-stylesheet": "^0.6.0",
	"react-native-fabric": "^0.5.1",
	"react-native-fabric-crashlytics": "^0.1.8",
	"react-native-fbsdk": "team-supercharge/react-native-fbsdk#master",
	"react-native-firebase": "^3.1.1",
	"react-native-fit-image": "^1.5.2",
	"react-native-google-analytics-bridge": "5.6.2",
	"react-native-hyperlink": "^0.0.11",
	"react-native-i18n": "^2.0.5",
	"react-native-image-sequence": "^0.5.0",
	"react-native-iphone-x-helper": "^1.0.1",
	"react-native-keyboard-aware-scroll-view": "^0.4.1",
	"react-native-open-settings": "^1.0.1",
	"react-native-permissions": "yonahforst/react-native-permissions#master",
	"react-native-phone-call": "^1.0.4",
	"react-native-read-more-text": "^1.0.0",
	"react-native-redux-toast": "team-supercharge/react-native-redux-toast#master",
	"react-native-root-modal": "^3.0.0",
	"react-native-section-list-get-item-layout": "^2.0.0",
	"react-native-slider": "^0.11.0",
	"react-navigation": "1.0.0-beta.19",
	"react-redux": "^5.0.6",
	"recompose": "^0.26.0",
	"redux": "^3.7.2",
	"redux-actions": "^2.2.1",
	"redux-batched-actions": "^0.1.6",
	"redux-form": "^7.1.1",
	"redux-logger": "^3.0.6",
	"redux-observable": "^0.17.0",
	"redux-persist": "^5.4.0",
	"redux-thunk": "^2.2.0",
	"remove-accents": "^0.4.2",
	"reselect": "^3.0.1",
	"rxjs": "5.5.2"
},
"devDependencies": {
	"babel-eslint": "^7.2.3",
	"babel-jest": "20.0.3",
	"babel-plugin-module-resolver": "^2.7.1",
	"babel-plugin-transform-class-properties": "^6.24.1",
	"babel-preset-react-native": "3.0.1",
	"dotize": "^0.2.0",
	"eslint": "^4.5.0",
	"eslint-config-airbnb": "^15.1.0",
	"eslint-plugin-import": "^2.7.0",
	"eslint-plugin-jsx-a11y": "^5.1.1",
	"eslint-plugin-prefer-object-spread": "^1.2.1",
	"eslint-plugin-react": "^7.3.0",
	"eslint-plugin-react-native": "^3.0.1",
	"gulp": "3.9.0",
	"gulp-file": "^0.3.0",
	"jest": "20.0.4",
	"patch-package": "^5.1.1",
	"react-addons-perf": "^15.4.2",
	"react-native-debugger-open": "^0.3.15",
	"react-native-schemes-manager": "Thinkmill/react-native-schemes-manager#master",
	"react-test-renderer": "16.0.0-alpha.12",
	"why-did-you-update": "^0.1.0"
},

Not detecting shrinkwrap

I'm receiving an error that it's not finding package-lock.json or yarn.lock however I am using shrinkwrap. Any suggestions?

Error when installing or upgrading another package

I get this error when I install or upgrade another package:

Exit code: 1
Command: sh
Arguments: -c ln -s lib/{ios,android} .
Directory: /Users/alexandermann/Code/Whisk/whisk-mobile-client/node_modules/react-native-interactable
Output:
ln: ./ios: File exists
ln: ./android: File exists

I am using zsh as my default shell and am assuming it has something to do with that?

Clear info on missing patches

I was just dockerizing one of my projects and due to funny COPY syntax i copied my patches to root of the project instead to ./patches directory. Which resulted in silent fail to patch packages.

The console output was:

patch-package: Applying patches...

I assumed that i just successfully applied patches. When it really did nothing.

I propose one of two things:

  1. Fail when no patches were found. This seems like kinda logical step to me — if there are no patches something is wrong.
  2. Make console output more ovious like write: NO PACKAGES FOUND (but exit with 0).

I am willing to make a PR after agreeing on what's better.

Not able to include package.json in the patch

I was commenting on here as we are (for some unknown reason so far) not able to download the latest beta version which seem to fix the issue about the error after applying a patch.

@ds300 let me explain out situation so maybe you can point the way to go. We are having this issue: a third party package we are using has not properly set the folder directories to point to the /lib and /es folders.

We opened this PR for them to merge but even if that happens then the other package we want to use rc-slider. So in total this means waiting on two external PRs.

As a workaround we wanted to modify or local packages, patch them, to allow this changes which already make our build succesful but we are not able to include the package.jsonfile. We tried yarn patch-package rc-util --use-yarn --exclude /$.^/ as a void regexp to reenable the disbales package.json tracking for the patch but with no success.

As another workaround we modified the /es files to patch the package but the patch-package is presenting the whitespace error This is usually caused by inconsistent whitespace in the patch file.

TL,DR: What would be the way to include package.jsonin the patch?

Error with local filesystem packages

Summary:

I have a package.json where some packages are installed from local filesystem, not npm, such as

"process-scarecrow": "file:./process-scarecrow",

But I'm patching something else, patch-package ssb-keys. (I had initially installed all packages with yarn, just FYI). Then I get an error which apparently aborts the patching process so I don't get the file patches/ssb-keys:1.2.3.patch.

Expected:

Patch file created and the module is patched as usual.

Actual:

Error when running patch-package ssb-keys


***Warning***
patch-package currently only works after `yarn remove` when you install a
project-local copy of yarn.
See https://github.com/ds300/patch-package#why-patch-yarn for details

error "/private/var/folders/4k/xjj8sw652m7046nc2006k8fc0000gn/T/tmp-10745p4f76427JQ7b/process-scarecrow" doesn't exist.
{ Error: Command failed: yarn
error "/private/var/folders/4k/xjj8sw652m7046nc2006k8fc0000gn/T/tmp-10745p4f76427JQ7b/process-scarecrow" doesn't exist.

    at checkExecSyncError (child_process.js:481:13)
    at Object.execSync (child_process.js:521:13)
    at tmpExec (/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/makePatch.js:35:63)
    at Object.makePatch [as default] (/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/makePatch.js:39:9)
    at /Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/index.js:21:32
    at Array.forEach (native)
    at Object.<anonymous> (/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/index.js:20:22)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
  error: null,
  cmd: 'yarn',
  file: '/bin/sh',
  args: [ '/bin/sh', '-c', 'yarn' ],
  options:
   { cwd: '/var/folders/4k/xjj8sw652m7046nc2006k8fc0000gn/T/tmp-10745p4f76427JQ7b',
     shell: true,
     file: '/bin/sh',
     args: [ '/bin/sh', '-c', 'yarn' ],
     envPairs: [],
     stdio: [ [Object], [Object], [Object] ] },
  envPairs: [],
  stderr: <Buffer 65 72 72 6f 72 20 22 2f 70 72 69 76 61 74 65 2f 76 61 72 2f 66 6f 6c 64 65 72 73 2f 34 6b 2f 78 6a 6a 38 73 77 36 35 32 6d 37 30 34 36 6e 63 32 30 30 ... >,
  stdout: <Buffer 79 61 72 6e 20 69 6e 73 74 61 6c 6c 20 76 30 2e 32 34 2e 35 0a 5b 31 2f 34 5d 20 52 65 73 6f 6c 76 69 6e 67 20 70 61 63 6b 61 67 65 73 2e 2e 2e 0a 69 ... >,
  pid: 10750,
  output:
   [ null,
     <Buffer 79 61 72 6e 20 69 6e 73 74 61 6c 6c 20 76 30 2e 32 34 2e 35 0a 5b 31 2f 34 5d 20 52 65 73 6f 6c 76 69 6e 67 20 70 61 63 6b 61 67 65 73 2e 2e 2e 0a 69 ... >,
     <Buffer 65 72 72 6f 72 20 22 2f 70 72 69 76 61 74 65 2f 76 61 72 2f 66 6f 6c 64 65 72 73 2f 34 6b 2f 78 6a 6a 38 73 77 36 35 32 6d 37 30 34 36 6e 63 32 30 30 ... > ],
  signal: null,
  status: 1 }
/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/makePatch.js:64
        throw e;
        ^

Error: Command failed: yarn
error "/private/var/folders/4k/xjj8sw652m7046nc2006k8fc0000gn/T/tmp-10745p4f76427JQ7b/process-scarecrow" doesn't exist.

    at checkExecSyncError (child_process.js:481:13)
    at Object.execSync (child_process.js:521:13)
    at tmpExec (/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/makePatch.js:35:63)
    at Object.makePatch [as default] (/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/makePatch.js:39:9)
    at /Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/index.js:21:32
    at Array.forEach (native)
    at Object.<anonymous> (/Users/staltz/.nvm/versions/node/v6.10.3/lib/node_modules/patch-package/dist/index.js:20:22)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)

More:

node: v6.10.3
yarn: v0.24.5
patch-package: 2.1.1

Failed to apply patch for package, but versions match

patch-package version: v2.0.0

Reproduction:

I don't have a repo to point to, but in my case I'm using [email protected] as installer, I have some transitive dependencies in node_modules, e.g. vfile is in my node_modules but it's not in my package.json. I have a patches/vfile:1.4.0.patch file, and the version installed is also v1.4.0.

Expected: patch-package to patch a package without errors

Actual:

click here
***ERROR***
patch-package requires yarn as a local peer-dependency

Applying patches to node_modules...
[email protected][email protected] ✔

**ERROR** Failed to apply patch for package vfile

  Patch was made for version 1.4.0
  Meanwhile node_modules/vfile is version 1.4.0

  Run:

     patch --forward -p1 -i patches/vfile:1.4.0.patch

  To generate rejection files and see just what the heck happened.

I also got the rejection files, but it doesn't explain anything new:

patching file node_modules/vfile/index.js
patch unexpectedly ends in middle of line
Hunk #1 FAILED at 43.
1 out of 1 hunk FAILED -- saving rejects to file node_modules/vfile/index.js.rej
index.js.rej
***************
*** 43,49 ****
  var SEPARATOR = '/';
  
  try {
-     SEPARATOR = require('pa' + 'th').sep;
  
  
  
--- 43,49 ----
  var SEPARATOR = '/';
  
  try {
+     SEPARATOR = require('path').sep;
  
  
  
index.js.orig
/**
 * @author Titus Wormer
 * @copyright 2015 Titus Wormer
 * @license MIT
 * @module vfile
 * @fileoverview Virtual file format to attach additional
 *   information related to processed input.  Similar to
 *   `wearefractal/vinyl`.  Additionally, `VFile` can be
 *   passed directly to ESLint formatters to visualise
 *   warnings and errors relating to a file.
 * @example
 *   var VFile = require('vfile');
 *
 *   var file = new VFile({
 *     'directory': '~',
 *     'filename': 'example',
 *     'extension': 'txt',
 *     'contents': 'Foo *bar* baz'
 *   });
 *
 *   file.toString(); // 'Foo *bar* baz'
 *   file.filePath(); // '~/example.txt'
 *
 *   file.move({'extension': 'md'});
 *   file.filePath(); // '~/example.md'
 *
 *   file.warn('Something went wrong', {'line': 2, 'column': 3});
 *   // { [~/example.md:2:3: Something went wrong]
 *   //   name: '~/example.md:2:3',
 *   //   file: '~/example.md',
 *   //   reason: 'Something went wrong',
 *   //   line: 2,
 *   //   column: 3,
 *   //   fatal: false }
 */

'use strict';

/* eslint-env commonjs */

var proto;

var SEPARATOR = '/';

try {
    SEPARATOR = require('pa' + 'th').sep;
} catch (e) { /* empty */ }

/**
 * Construct a new file message.
 * ...
 * ...

"Include" and "exclude" path documentation is incorrect

The documentation for --include and --exclude says "Paths are relative to the root dir of the package to be patched." However, the fileName here appears to be relative to the parent repository. I see a prefix of node_modules/the-package-being-patched/ for every file.

Documentation should read: "Paths are relative to your project's root directory."

Doesn't detect package.json changes

I'm trying to use patch-package to quick fix modules that haven't been updated for years and they use vulnerable modules like lodash 1.0.1. Yarn lacks a deep upgrade functionality so I figured patch-package might be the easiest and most maintainable option for this.

For some reason when I update package.json for the module, patch-package says there's no changes in the module. Is this a bug or am I just doing something wrong?

Patching from a module

First off very cool stuff. Works great.

What are your thoughts on allowing patches to be applied via an npm module?

i.e. User installs module X which has patches for module Y runs

patch-package --apply module-x

Module X would contain the patches dir etc...

Support for Yarn workspaces/monorepos

First of all, thanks for the awesome work on this package!

I've started exploring the new "workspaces"/"monorepos" feature of Yarn (https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/), which enables "hoisting" of all node_modules from any sub-projects to a single parent repository (so that if you have sub-folders with individual package.jsons, each one would install its deps in the "parent" node_modules and link them, unless there are version conflicts).

However, patch-package no longer automatically applies patches to sub-project packages in its default configuration (i.e. when I run yarn in the parent folder, it only applies patches/ from the "parent" folder). I had to move all patches from sub-projects into the "parent" patches/ to make it work, however that sort of "pollutes" the "global" patch space with patches from sub-projects.

Are you familiar with this feature, and are there any other (better) solutions to enable automatic patching of sub-projects (I know it's a lot to ask, was just hoping to hear your thoughts)?

Thanks again!

Under Cygwin Windows-style paths are used

Appended is the output of npm run prepare -- epub.js. Notice the fatal: pathspec 'node_modules\epub.js\package.json' did not match any files. The slashes are windows-style, while the cygwin git expects posix paths.

I'll submit a PR if I figure out a solution. Help debugging would be appreciated.

npm run prepare -- epub.js

> [email protected] prepare E:\ivairus\cygwin\home\Dominykas\darbalaukiai\__kontraktai\iko-app
> patch-package "epub.js"

☑ Creating temporary folder
☑ Building clean node_modules with npm
☑ Diffing your files with clean files
fatal: pathspec 'node_modules\epub.js\package.json' did not match any files

{ status: 128,
  signal: null,
  output:
   [ null,
     <Buffer >,
     <Buffer 66 61 74 61 6c 3a 20 70 61 74 68 73 70 65 63 20 27 6e 6f 64 65 5f 6d 6f 64 75 6c 65 73 5c 65 70 75 62 2e 6a 73 5c 70 61 63 6b 61 67 65 2e 6a 73 6f 6e ... > ],
  pid: 8160,
  stdout: <Buffer >,
  stderr: <Buffer 66 61 74 61 6c 3a 20 70 61 74 68 73 70 65 63 20 27 6e 6f 64 65 5f 6d 6f 64 75 6c 65 73 5c 65 70 75 62 2e 6a 73 5c 70 61 63 6b 61 67 65 2e 6a 73 6f 6e ... >,
  envPairs:
   [ 'ALLUSERSPROFILE=C:\\ProgramData',
     'APPDATA=C:\\Users\\Dominykas\\AppData\\Roaming',
     'BROWSER=cygstart',
     'COMMONPROGRAMFILES=C:\\Program Files\\Common Files',
     'CommonProgramFiles(x86)=C:\\Program Files (x86)\\Common Files',
     'CommonProgramW6432=C:\\Program Files\\Common Files',
     'COMPUTERNAME=HP8540P',
     'COMSPEC=C:\\WINDOWS\\system32\\cmd.exe',
     'C_EM64T_REDIST11=C:\\Program Files (x86)\\Common Files\\Intel\\Shared Files\\cpp\\',
     'HOME=C:\\Users\\Dominykas',
     'HOMEDRIVE=C:',
     'HOMEPATH=\\Users\\Dominykas',
     'INIT_CWD=E:\\ivairus\\cygwin\\home\\Dominykas\\darbalaukiai\\__kontraktai\\iko-app',
     'JDK_BIN=C:\\Program Files\\Java\\jdk1.8.0_112\\bin',
     'JRE_BIN=C:\\Program Files\\Java\\jre1.8.0_112\\bin',
     'LANG=C.UTF-8',
     'LOCALAPPDATA=C:\\Users\\Dominykas\\AppData\\Local',
     'LOGONSERVER=\\\\HP8540P',
     'LS_COLORS=no=00;38;5;60:fi=00:rs=0:di=01;38;5;104:ln=01;38;5;111:mh=00:pi=48;5;230;38;5;136;01:so=48;5;230;38;5;136;01:bd=;4;230;38;5;142;01:cd=;1;230;38;5;94;01:or=38;5;009;48;5;052:ex=0;38;5;2:*.clj=01;38;5;72:*.cljs=01;38;5;108:*.sh=01;38;5;95:*.html=01;38;5;36:*.swp=00;38;5;243:*.swo=00;38;5;243:*.aac=00;38;5;61:*.au=00;38;5;61:*.flac=00;38;5;61:*.mid=00;38;5;61:*.midi=00;38;5;61:*.mka=00;38;5;61:*.mp3=00;38;5;61:*.ogg=00;38;5;61:*.wav=00;38;5;61:*.m4a=00;38;5;61:*.mov=01;38;5;61:*.mpg=01;38;5;61:*.mpeg=01;38;5;61:*.m2v=01;38;5;61:*.mkv=01;38;5;61:*.ogm=01;38;5;61:*.mp4=01;38;5;61:*.m4v=01;38;5;61:*.mp4v=01;38;5;61:*.vob=01;38;5;61:*.qt=01;38;5;61:*.nuv=01;38;5;61:*.wmv=01;38;5;61:*.asf=01;38;5;61:*.rm=01;38;5;61:*.rmvb=01;38;5;61:*.flc=01;38;5;61:*.avi=01;38;5;61:*.fli=01;38;5;61:*.flv=01;38;5;61:*.gl=01;38;5;61:*.m2ts=01;38;5;61:*.divx=01;38;5;61:*.webm=01;38;5;61:*.jpg=00;38;5;61:*.JPG=00;38;5;61:*.jpeg=00;38;5;61:*.gif=00;38;5;61:*.bmp=00;38;5;61:*.pbm=00;38;5;61:*.pgm=00;38;5;61:*.ppm=00;38;5;61:*.tga=00;38;5;61:*.xbm=00;38;5;61:*.xpm=00;38;5;61:*.tif=00;38;5;61:*.tiff=00;38;5;61:*.png=00;38;5;61:*.svg=00;38;5;61:*.svgz=00;38;5;61:*.mng=00;38;5;61:*.pcx=00;38;5;61:*.dl=00;38;5;61:*.xcf=00;38;5;61:*.xwd=00;38;5;61:*.yuv=00;38;5;61:*.cgm=00;38;5;61:*.emf=00;38;5;61:*.eps=00;38;5;61:*.CR2=00;38;5;61:*.ico=00;38;5;61:*.zip=01;38;5;67:*.tar=00;38;5;67:*.tgz=01;38;5;67:*.lzh=01;38;5;67:*.z=01;38;5;67:*.Z=01;38;5;67:*.7z=01;38;5;67:*.gz=01;38;5;67:*.bz2=01;38;5;67:*.bz=01;38;5;67:*.deb=01;38;5;67:*.rpm=01;38;5;67:*.jar=01;38;5;103:*.rar=01;38;5;67:*.apk=01;38;5;67:*.gem=01;38;5;67:',
     'NODE=C:\\Program Files\\nodejs\\node.exe',
     'npm_config_access=',
     'npm_config_allow_same_version=',
     'npm_config_also=',
     'npm_config_always_auth=',
     'npm_config_argv={"remain":["epub.js"],"cooked":["run","prepare","--","epub.js"],"original":["run","prepare","--","epub.js"]}',
     'npm_config_auth_type=legacy',
     'npm_config_bin_links=true',
     'npm_config_browser=',
     'npm_config_ca=',
     'npm_config_cache=C:\\Users\\Dominykas\\AppData\\Roaming\\npm-cache',
     'npm_config_cache_lock_retries=10',
     'npm_config_cache_lock_stale=60000',
     'npm_config_cache_lock_wait=10000',
     'npm_config_cache_max=Infinity',
     'npm_config_cache_min=10',
     'npm_config_cafile=',
     'npm_config_cert=',
     'npm_config_color=true',
     'npm_config_commit_hooks=true',
     'npm_config_depth=Infinity',
     'npm_config_description=true',
     'npm_config_dev=',
     'npm_config_dry_run=',
     'npm_config_editor=notepad.exe',
     'npm_config_engine_strict=',
     'npm_config_fetch_retries=2',
     'npm_config_fetch_retry_factor=10',
     'npm_config_fetch_retry_maxtimeout=60000',
     'npm_config_fetch_retry_mintimeout=10000',
     'npm_config_force=',
     'npm_config_git=git',
     'npm_config_git_tag_version=true',
     'npm_config_global=',
     'npm_config_globalconfig=C:\\Users\\Dominykas\\AppData\\Roaming\\npm\\etc\\npmrc',
     'npm_config_globalignorefile=C:\\Users\\Dominykas\\AppData\\Roaming\\npm\\etc\\npmignore',
     'npm_config_global_style=',
     'npm_config_group=',
     'npm_config_ham_it_up=',
     'npm_config_heading=npm',
     'npm_config_https_proxy=',
     'npm_config_if_present=',
     'npm_config_ignore_prepublish=',
     'npm_config_ignore_scripts=',
     'npm_config_init_author_email=',
     'npm_config_init_author_name=',
     'npm_config_init_author_url=',
     'npm_config_init_license=ISC',
     'npm_config_init_module=C:\\Users\\Dominykas\\.npm-init.js',
     'npm_config_init_version=1.0.0',
     'npm_config_json=',
     'npm_config_key=',
     'npm_config_legacy_bundling=',
     'npm_config_link=',
     'npm_config_local_address=',
     'npm_config_loglevel=notice',
     'npm_config_logs_max=10',
     'npm_config_long=',
     'npm_config_maxsockets=50',
     'npm_config_message=%s',
     'npm_config_metrics_registry=https://registry.npmjs.org/',
     'npm_config_node_version=8.1.2',
     'npm_config_offline=',
     'npm_config_onload_script=',
     'npm_config_only=',
     'npm_config_optional=true',
     'npm_config_package_lock=true',
     'npm_config_parseable=',
     'npm_config_prefer_offline=',
     'npm_config_prefer_online=',
     'npm_config_prefix=C:\\Users\\Dominykas\\AppData\\Roaming\\npm',
     'npm_config_production=',
     'npm_config_progress=true',
     'npm_config_proxy=',
     'npm_config_rebuild_bundle=true',
     'npm_config_registry=https://registry.npmjs.org/',
     'npm_config_rollback=true',
     'npm_config_save=true',
     'npm_config_save_bundle=',
     'npm_config_save_dev=',
     'npm_config_save_exact=',
     ... 134 more items ],
  options:
   { cwd: 'C:\\Users\\DOMINY~1\\AppData\\Local\\Temp\\tmp-4304KzO9Ce5tCHcH',
     file: 'git',
     args: [ 'git', 'rm', '--cached', 'node_modules\\epub.js\\package.json' ],
     envPairs:
      [ 'ALLUSERSPROFILE=C:\\ProgramData',
        'APPDATA=C:\\Users\\Dominykas\\AppData\\Roaming',
        'BROWSER=cygstart',
        'COMMONPROGRAMFILES=C:\\Program Files\\Common Files',
        'CommonProgramFiles(x86)=C:\\Program Files (x86)\\Common Files',
        'CommonProgramW6432=C:\\Program Files\\Common Files',
        'COMPUTERNAME=HP8540P',
        'COMSPEC=C:\\WINDOWS\\system32\\cmd.exe',
        'C_EM64T_REDIST11=C:\\Program Files (x86)\\Common Files\\Intel\\Shared Files\\cpp\\',
        'HOME=C:\\Users\\Dominykas',
        'HOMEDRIVE=C:',
        'HOMEPATH=\\Users\\Dominykas',
        'INIT_CWD=E:\\ivairus\\cygwin\\home\\Dominykas\\darbalaukiai\\__kontraktai\\iko-app',
        'JDK_BIN=C:\\Program Files\\Java\\jdk1.8.0_112\\bin',
        'JRE_BIN=C:\\Program Files\\Java\\jre1.8.0_112\\bin',
        'LANG=C.UTF-8',
        'LOCALAPPDATA=C:\\Users\\Dominykas\\AppData\\Local',
        'LOGONSERVER=\\\\HP8540P',
        'LS_COLORS=no=00;38;5;60:fi=00:rs=0:di=01;38;5;104:ln=01;38;5;111:mh=00:pi=48;5;230;38;5;136;01:so=48;5;230;38;5;136;01:bd=;4;230;38;5;142;01:cd=;1;230;38;5;94;01:or=38;5;009;48;5;052:ex=0;38;5;2:*.clj=01;38;5;72:*.cljs=01;38;5;108:*.sh=01;38;5;95:*.html=01;38;5;36:*.swp=00;38;5;243:*.swo=00;38;5;243:*.aac=00;38;5;61:*.au=00;38;5;61:*.flac=00;38;5;61:*.mid=00;38;5;61:*.midi=00;38;5;61:*.mka=00;38;5;61:*.mp3=00;38;5;61:*.ogg=00;38;5;61:*.wav=00;38;5;61:*.m4a=00;38;5;61:*.mov=01;38;5;61:*.mpg=01;38;5;61:*.mpeg=01;38;5;61:*.m2v=01;38;5;61:*.mkv=01;38;5;61:*.ogm=01;38;5;61:*.mp4=01;38;5;61:*.m4v=01;38;5;61:*.mp4v=01;38;5;61:*.vob=01;38;5;61:*.qt=01;38;5;61:*.nuv=01;38;5;61:*.wmv=01;38;5;61:*.asf=01;38;5;61:*.rm=01;38;5;61:*.rmvb=01;38;5;61:*.flc=01;38;5;61:*.avi=01;38;5;61:*.fli=01;38;5;61:*.flv=01;38;5;61:*.gl=01;38;5;61:*.m2ts=01;38;5;61:*.divx=01;38;5;61:*.webm=01;38;5;61:*.jpg=00;38;5;61:*.JPG=00;38;5;61:*.jpeg=00;38;5;61:*.gif=00;38;5;61:*.bmp=00;38;5;61:*.pbm=00;38;5;61:*.pgm=00;38;5;61:*.ppm=00;38;5;61:*.tga=00;38;5;61:*.xbm=00;38;5;61:*.xpm=00;38;5;61:*.tif=00;38;5;61:*.tiff=00;38;5;61:*.png=00;38;5;61:*.svg=00;38;5;61:*.svgz=00;38;5;61:*.mng=00;38;5;61:*.pcx=00;38;5;61:*.dl=00;38;5;61:*.xcf=00;38;5;61:*.xwd=00;38;5;61:*.yuv=00;38;5;61:*.cgm=00;38;5;61:*.emf=00;38;5;61:*.eps=00;38;5;61:*.CR2=00;38;5;61:*.ico=00;38;5;61:*.zip=01;38;5;67:*.tar=00;38;5;67:*.tgz=01;38;5;67:*.lzh=01;38;5;67:*.z=01;38;5;67:*.Z=01;38;5;67:*.7z=01;38;5;67:*.gz=01;38;5;67:*.bz2=01;38;5;67:*.bz=01;38;5;67:*.deb=01;38;5;67:*.rpm=01;38;5;67:*.jar=01;38;5;103:*.rar=01;38;5;67:*.apk=01;38;5;67:*.gem=01;38;5;67:',
        'NODE=C:\\Program Files\\nodejs\\node.exe',
        'npm_config_access=',
        'npm_config_allow_same_version=',
        'npm_config_also=',
        'npm_config_always_auth=',
        'npm_config_argv={"remain":["epub.js"],"cooked":["run","prepare","--","epub.js"],"original":["run","prepare","--","epub.js"]}',
        'npm_config_auth_type=legacy',
        'npm_config_bin_links=true',
        'npm_config_browser=',
        'npm_config_ca=',
        'npm_config_cache=C:\\Users\\Dominykas\\AppData\\Roaming\\npm-cache',
        'npm_config_cache_lock_retries=10',
        'npm_config_cache_lock_stale=60000',
        'npm_config_cache_lock_wait=10000',
        'npm_config_cache_max=Infinity',
        'npm_config_cache_min=10',
        'npm_config_cafile=',
        'npm_config_cert=',
        'npm_config_color=true',
        'npm_config_commit_hooks=true',
        'npm_config_depth=Infinity',
        'npm_config_description=true',
        'npm_config_dev=',
        'npm_config_dry_run=',
        'npm_config_editor=notepad.exe',
        'npm_config_engine_strict=',
        'npm_config_fetch_retries=2',
        'npm_config_fetch_retry_factor=10',
        'npm_config_fetch_retry_maxtimeout=60000',
        'npm_config_fetch_retry_mintimeout=10000',
        'npm_config_force=',
        'npm_config_git=git',
        'npm_config_git_tag_version=true',
        'npm_config_global=',
        'npm_config_globalconfig=C:\\Users\\Dominykas\\AppData\\Roaming\\npm\\etc\\npmrc',
        'npm_config_globalignorefile=C:\\Users\\Dominykas\\AppData\\Roaming\\npm\\etc\\npmignore',
        'npm_config_global_style=',
        'npm_config_group=',
        'npm_config_ham_it_up=',
        'npm_config_heading=npm',
        'npm_config_https_proxy=',
        'npm_config_if_present=',
        'npm_config_ignore_prepublish=',
        'npm_config_ignore_scripts=',
        'npm_config_init_author_email=',
        'npm_config_init_author_name=',
        'npm_config_init_author_url=',
        'npm_config_init_license=ISC',
        'npm_config_init_module=C:\\Users\\Dominykas\\.npm-init.js',
        'npm_config_init_version=1.0.0',
        'npm_config_json=',
        'npm_config_key=',
        'npm_config_legacy_bundling=',
        'npm_config_link=',
        'npm_config_local_address=',
        'npm_config_loglevel=notice',
        'npm_config_logs_max=10',
        'npm_config_long=',
        'npm_config_maxsockets=50',
        'npm_config_message=%s',
        'npm_config_metrics_registry=https://registry.npmjs.org/',
        'npm_config_node_version=8.1.2',
        'npm_config_offline=',
        'npm_config_onload_script=',
        'npm_config_only=',
        'npm_config_optional=true',
        'npm_config_package_lock=true',
        'npm_config_parseable=',
        'npm_config_prefer_offline=',
        'npm_config_prefer_online=',
        'npm_config_prefix=C:\\Users\\Dominykas\\AppData\\Roaming\\npm',
        'npm_config_production=',
        'npm_config_progress=true',
        'npm_config_proxy=',
        'npm_config_rebuild_bundle=true',
        'npm_config_registry=https://registry.npmjs.org/',
        'npm_config_rollback=true',
        'npm_config_save=true',
        'npm_config_save_bundle=',
        'npm_config_save_dev=',
        'npm_config_save_exact=',
        ... 134 more items ],
     killSignal: undefined,
     stdio: [ [Object], [Object], [Object] ] },
  args: [ 'git', 'rm', '--cached', 'node_modules\\epub.js\\package.json' ],
  file: 'git',
  error: null }


Patch fails when created with v5

I get the following

This error was caused because Git cannot apply the following patch file:
    patches/react-scripts+1.0.17.patch
  This is usually caused by inconsistent whitespace in the patch file.

when CI tries to apply the patch that I created locally (OSX) with patch package 5. Downgrading to v3 resolves the issue.

Doesn't handle missing `git`

My CI job was failing at the patch step, with error messages that my patch file couldn't be applied. When I added apk update && apk add git (I'm using the apline node docker image), it started working.

patch-package should really say, "Hey, I need git," if that's what it needs to work.

Strange thing is it was working before, when the patch file was simpler...

Each second patch-package run reverses patches

Version: 5.1.0
NPM: 5.6.0
NodeJS: 8.9.1

I created a patch for a package.
Every first time I do "npm run prepare" patch is applied and every second time patch is reversed.

UPDATE: 5.0.0 works perfectly

Improve yarn compatibility

Nobody uses the yarn patching facility. Not even me. It hasn't even been kept up to date, and it's an ugly hack.

I should replace yarn patching with patch status checking, or do some open source activity to get yarn to run prepare after package removal.

prepare doesn't patch when installing npm package indirectly

Lets say I have a project 'A' with a patch-package and patches to apply to its deps.
Lets say I have a project 'B' where I want to add 'A' as a dependency.

When do yarn add 'A' inside of project 'B', the the 'prepare' script isn't run. Meaning, the patches aren't installed properly.

Package creation fails on Windows (command cp doesn't exist)

Error: Command failed: cp '[REDACTED]\WebApp\package.json' 'C:\Users\Andrey\AppData\Local\Temp\tmp-67620GzG5P14Xw1BW'
'cp' is not recognized as an internal or external command,
operable program or batch file.

    at checkExecSyncError (child_process.js:568:13)
    at Object.execSync (child_process.js:608:13)
    at Object.makePatch [as default] ([REDACTED]\WebApp\node_modules\patch-package\dist\makePatch.js:42:25)
    at [REDACTED]\WebApp\node_modules\patch-package\dist\index.js:20:32
    at Array.forEach (native)
    at Object.<anonymous> ([REDACTED]\WebApp\node_modules\patch-package\dist\index.js:19:22)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)

Update documentation for Windows

Recently I used patch-package (3.4.0) on macOS (which worked very well) but my colleagues on Windows got an error during npm install. I followed the documentation, i.e., I set autocrlf=true on Windows but this did not help.

After investigating this issue, I found the following:

  • git apply skipped the patches on Windows
  • the patches created on macOS could be applied manually on Windows using patch (from git-bash)
  • creating the patches anew on Windows via patch-package worked (i.e., npm install did not error out, patches were applied)

I compared the patches created on macOS with those on Windows and found that they were exactly the same, except that the newly created patches on Windows did NOT have CRLF but LF ending.
Then I removed the autocrlf setting and forced LF EOL on patch files via .gitattribute and then the patches from macOS worked, too.

So, I propose to change the documentation, stating that autocrlf is not necessary. Instead, create a .gitattributes file in the patches folder containing at least this:

*.patch eol=lf

patch react-native android

From the README.md:

Sometimes forks need extra build steps, e.g. with react-native for Android. Forget that noise.

Is it actually possible to patch a java file from react-native? As far as I know, react-native includes an aar and thus changes on the source files will not have any effect.

Recommended practice - partching "src" or "dist" ?

I am using patch-package on a Vue-CLI project which (obviously) depends on Vue and Vue-router. I want to patch both dependencies but wonder what is the best practice for doing it. I mean - packages contain both src and dist folder. If I modify file(s) in src folder - this does not lead to automatic rebuild of files in dist folder of the package. Am I supposed to only patch files in the dist folder ? Or should I patch files in src and then manually rebuild the patched packages ? dist folder contains different variants of the package (like vue.common.js, vue.esm.js, vue.runtime.common.js, vue.runtime.min.js ...) which are build from the same src files.
Either way has a disadvantage:

  • patching only files in dist folder potentially requires applying the same patch over several files
  • patching only files in src folder requires manual build (and multiple 100+ Mb luggage of ./node_modules for each patched package)

How do you do it ?

Idiot-proof tutorial? "patch-package: command not found"

I followed the instructions on the package page, but I can't get it to work:

https://www.npmjs.com/package/patch-package

I did this:

  1. cd ~/git/myproject/src (directory containing my package.json file, my node_modules directory is located in the parent myproject directory.
  2. npm install patch-package --save (seems to report [email protected] and its dependencies were installed successfully.
  3. I made my tweaks to a package "badpackage" in my nodue_modules directory.
  4. patch-package badpackage gives me this output:
    bash: patch-package: command not found
  5. npm patch-package badpackage (gives me the npm Usage printout)
  6. ./patch-package
    bash: ./patch-package: No such file or directory

Other npm-managed commands like ng (for ng serve, ng build, etc) work fine.

I'm using bash 4.4.12 on mingw64.

Better handling for cached 'node_modules' folder

Use case

We are using patch-package to fix some nasty dependency issues, it works great during development. But it sometimes causes CircleCI failures when a partially patched node_modules folder is cached by CI.

The issue

  1. Install patch-package and add it as prepare script, as instructed by README.
  2. Patch module foo-bar using patch-package foo-bar. Commit the resulted patches/foo-bar+X.X.X.patch to repo.
  3. When CI is run, CircleCI installs and patches the node_modules folder and saves the result to cache.
  4. Modify module foo-bar and regenerate patch file.
  5. CircleCI restores the previous cached node_modules folder (which has incorporated previous version of the patch).
  6. CircleCI fails when applying new patch to node_modules:
**ERROR** Failed to apply patch for package foo-bar

  This error was caused because Git cannot apply the following patch file:

    patches/foo-bar+X.X.X.patch

  This is usually caused by inconsistent whitespace in the patch file.

Proposed solutions

  1. Add a checksum file for the patches folder so we can easily check if patches has been changed before restoring cache from CI.

  2. Or, add a operation that can revert applied patches, such as patch-package revert. So we can revert the patches and save the clean node_modules folder to cache.

Problem with scoped packages

I've got an error while trying to patch scoped npm package, e.g. @types/rollup

Error: Command failed: git add -f 'node_modules/[at]types/rollup'
fatal: pathspec 'node_modules/[at]types/rollup' did not match any files

Error 'Must use npm@>=5' while using npm 5.4.2

Eriks-Air:neonwallet erik$ ./node_modules/.bin/patch-package react-navigation

ERROR No package-lock.json, npm-shrinkwrap.json, or yarn.lock file.

You must use either npm@>=5, yarn, or npm-shrinkwrap to manage this project's
dependencies.

Eriks-Air:neonwallet erik$ npm -v
5.4.2

Also likely related:

Eriks-Air:neonwallet erik$ npm -v
5.4.2
Eriks-Air:neonwallet erik$ grep "prepare" package.json
"prepare": "patch-package"
Eriks-Air:neonwallet erik$ npm prepare -- react-navigation

Usage: npm

where is one of:
access, adduser, bin, bugs, c, cache, completion, config,
ddp, dedupe, deprecate, dist-tag, docs, doctor, edit,
explore, get, help, help-search, i, init, install,
install-test, it, link, list, ln, login, logout, ls,
outdated, owner, pack, ping, prefix, prune, publish, rb,
rebuild, repo, restart, root, run, run-script, s, se,
search, set, shrinkwrap, star, stars, start, stop, t, team,
test, tst, un, uninstall, unpublish, unstar, up, update, v,
version, view, whoami

npm -h quick help on
npm -l display full usage info
npm help search for help on
npm help npm involved overview

Specify configs in the ini-formatted file:
/Users/erik/.npmrc
or on the command line via: npm --key value
Config info can be viewed via: npm help config

[email protected] /usr/local/lib/node_modules/npm

I've followed all the instructions as far as I can see. I also can't really tell why it's failing. Any help/tips are appreciated

Remove colon character from patch filenames

Hi @ds300,

Great work on this!

Can I suggest that patches are named as some-package 3.14.15.patch instead of some-package:3.14.15.patch?

The colon character is invalid for filenames on Windows. If you clone a repo with colons in the filenames onto a Windows machine, the files will be renamed. Apart from this issue, patch-package appears to work on Windows (when used via Git Bash which includes GNU patch).

Spaces are not valid npm package names, so I think the space will serve just as well as the colon as a separator.

Cheers,
Keegan

Can't create patches if there are also shell scripts used in preinstall/postinstall

If there are additional actions required during normal pre/post install for the program, the patch-package tries to run those as well as part of the build new package process. However, because it has not copied them to the temp build directory, those scripts cannot be found so the build fails.

For example:
./util/pre-install.sh

#!/bin/bash
if [ ! -f "${PWD}/.env"]
then
    echo "REACT_APP_DEMO_MODE=true"
fi

package.json:

{
  "scripts": {
    "preinstall": "./util/pre-install.sh",
    "postinstall": "patch-package"
  }
}

The failure log states that the "./util/pre-install.sh" script was not found in the temp directory.

Patch is not applied under windows (not a CRLF problem)

It seems that the latest patch-package has issues working under windows (I did not check the other versions). My patch file has LF endings, the file in node_modules/ also does.

$ patch-package
patch-package: Applying patches...
**ERROR** Failed to apply patch for package jison-lex
...

Note that the patch applied successfully through

$ patch -p1 -i patches/jison-lex+0.3.4.patch
patching file node_modules/jison-lex/regexp-lexer.js

Maybe just use patch in your package? :)
That patch that I am using is here: https://github.com/roman-spiridonov/sandbox/tree/master/%5BStanford%5D%20Compilers/cool-jison.

P.S. I do not know how to create and apply the patch through git diff/git apply manually, because node_modules/ folder is in my global .gitignore. Note that patch is created just fine but I cannot apply that.

Command not found: patch-package

Hello,

run patch-package to create a .patch file

patch-package some-package

After "npm install patch-package",
I run the command "patch-package" on terminal but got "zsh: command not found: patch-package".

I'm using macOS Sierra.

Please advise.
Thanks.

patch-package failed but git apply succeed

We are using patch-package for developing our app and it works great in development environments. But it shows a strange error when we deployed it to CircleCI.

$ "/home/circleci/project/node_modules/.bin/patch-package"
patch-package: Applying patches...

**ERROR** Failed to apply patch for package react-native-device-info

  This error was caused because Git cannot apply the following patch file:

    patches/react-native-device-info+0.11.0.patch

  This is usually caused by inconsistent whitespace in the patch file.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Exited with code 1

But the patches seem to be working fine when I use git apply

$ git apply patches/*

(Succeeded, no output message)

The environment for CircleCI is:

  • Docker container: circleci/node:8
  • Node v8.6.0
  • Yarn v1.1.0
  • patch-package v3.4.2

Support multiple patches per package

I've been manually patching React Native for quite some time and I love the idea of this tool. It makes extracting a patch so much easier than the manual process I'm used to using.

The one thing that stands in the way of my complete adoption of patch-package is its lack of support for multiple patches upon the same package. I like to separate my patches by concern, and it'd be nice if patch-package allowed a third segment in the patch name that can be customized by the user.

For example, it'd be great if I could split my one mega-patch into the following three patch files:

patches/react-native+0.52.0+babel.patch
patches/react-native+0.52.0+cookies.patch
patches/react-native+0.52.0+scrollview.patch

patch-package could apply the patches in lexically-sorted order. If the order of patch application matters, the user could include a sorting ordinal in the custom third segment, like such:

patches/react-native+0.52.0+00-scrollview.patch
patches/react-native+0.52.0+01-cookies.patch

The trickiest part of this will be excluding existing patches at the time that a new patch is extracted from a package. I'm not entirely sure how to handle that, but I'm also unconvinced that support for multiple patches needs to hinge on first-class support for extracting and isolating multiple patches. For now, if you want to use this power-user feature, you would just need to ensure that each patch is authored on a clean base package.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper integration’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Patch-package tries to apply the same patch twice and fails

I've set patch-package up according to the directions in the README, adding it as a prepare script in my package.json file, and I've added a single patch file. On a clean run with no node_modules, or with the patch not applied yet, the patch works great! However after the patch has been applied running yarn again seems to try to apply the patch again which fails. Here's some sample output:

[nix-shell:~/project]$ rm -rf node_modules/ && yarn
yarn install v1.0.1
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning "[email protected]" has incorrect peer dependency "ajv@>=5.0.0".
[4/4] Building fresh packages...
warning Your current version of Yarn is out of date. The latest version is "1.3.2" while you're on "1.0.1".
info To upgrade, run the following command:
$ curl -o- -L https://yarnpkg.com/install.sh | bash
$ patch-package
patch-package: Applying patches...
@types/[email protected] ✔
Done in 10.07s.

[nix-shell:~/project]$ yarn
yarn install v1.0.1
[1/4] Resolving packages...
success Already up-to-date.
$ patch-package
patch-package: Applying patches...

**ERROR** Failed to apply patch for package @types/ramda

  This error was caused because Git cannot apply the following patch file:

    patches/@types/ramda+0.24.17.patch

  This is usually caused by inconsistent whitespace in the patch file.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

Add patched metadata to package-lock.json

This works great overall, so thanks for your work on it!

Issue

We currently use a checksum of package-lock.json as a cache key on our CI. Should patch-package save the fact that it's patched a given module into that lock file (or the yarn equivalent) so anything doing a checksum off of those lock files has an accurate view of the what's truly there or what has changed?

Something like a "patched": <hash of patch file(s) applied to this module> would be the most robust.

Related

This relates to #37 (essentially asking for something like Option 1 there but in this case it manifests itself in the package/yarn lock files).

Doesn't work with local NPM dependencies

Hey,
Looks like there's an issue if you use a local npm file:// path as a dependency

☑ Creating temporary folder
☑ Building clean node_modules with npm
npm ERR! code ENOLOCAL
npm ERR! Could not install from "..\common" as it does not contain a package.json file.

Thanks,

Allow excluding certain paths from patches

Every time after I run Yarn the applying Patches gives me the error

**ERROR** Failed to apply patch for package react-native-audio-toolkit

This error was caused because Git cannot apply the following patch file:

patches/react-native-audio-toolkit+1.0.5.patch

This is usually caused by inconsistent whitespace in the patch file.

When I run patch -p1 -i patches/react-native-audio-toolkit+1.0.5.patch

I got the following for each build file:

The next patch would create the file node_modules/react-native-audio-toolkit/node_modules/async/applyEachSeries.js,
which already exists!  Assume -R? [n] 

Is there an option to exclude the build and node_module files from the package from patching?

Inconsistent information provided when patching fails

This issue seems to be similar to #19 so I updated my yarn and node versions. I am on 64-bit Windows 10 with yarn v1.1.0, node 8.6.0 and npm v5.3.0. I can successfully generate a patch file and I have successfully applied the very same file in the past with $yarn prepare. I have noticed that this issue seems to occur when I switch branches in git.

$ yarn prepare
yarn run v1.1.0
$ patch-package
patch-package: Applying patches...

**ERROR** Failed to apply patch for package react-native-deprecated-custom-components

  This error was caused because react-native-deprecated-custom-components has changed since you
  made the patch file for it. This introduced conflicts with your patch,
  just like a merge conflict in Git when separate incompatible changes are
  made to the same piece of code.

  Maybe this means your patch file is no longer necessary, in which case
  hooray! Just delete it!

  Otherwise, you need to manually fix the patch file. Or generate a new one

  To generate a new one, just repeat the steps you made to generate the first
  one, but accounting for the changes in react-native-deprecated-custom-components.

  i.e. make changes, run `patch-package react-native-deprecated-custom-components`, and commit.

  To manually fix a patch file, Run:

     patch -p1 -i patches/react-native-deprecated-custom-components+0.1.1.patch --verbose --dry-run

  To list rejected hunks. A 'hunk' is a section of patch file that describes
  one contiguous area of changes. They are numbered from 1 and begin with lines
  that look like this:

    diff --git a/node_modules/thing/thing.js b/node_modules/thing/thing.json

  Remove the conflicting hunks, then manually edit files in

    node_modules/react-native-deprecated-custom-components

  to reflect the changes that the conflicting hunks were supposed to make.

  Then run `patch-package react-native-deprecated-custom-components`

  Info:
    Patch was made for version 0.1.1
    Meanwhile node_modules/react-native-deprecated-custom-components is version 0.1.1

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Note that the info: section seems to indicate a belief that the version numbers are out of sync but they are actually identical. Better error messages would be helpful for debugging this.

Here is the package.json file from the library I'm trying to patch in my node_modules folder:

{
  "name": "react-native-deprecated-custom-components",
  "version": "0.1.1",
  "description": "Deprecated custom components that originally shipped with React Native",
  "repository": {
    "type": "git",
    "url": "[email protected]:facebookarchive/react-native-custom-components.git"
  },
  "main": "src/CustomComponents.js",
  "dependencies": {
    "fbjs": "~0.8.9",
    "immutable": "~3.7.6",
    "prop-types": "^15.5.10",
    "react-timer-mixin": "^0.13.2",
    "rebound": "^0.0.13"
  },
  "peerDependencies": {
    "react-native": "*"
  }
}

and here is the patch file itself:

diff --git a/node_modules/react-native-deprecated-custom-components/src/NavigatorBreadcrumbNavigationBar.js b/node_modules/react-native-deprecated-custom-components/src/NavigatorBreadcrumbNavigationBar.js
index 704216e..09efbbe 100644
--- a/node_modules/react-native-deprecated-custom-components/src/NavigatorBreadcrumbNavigationBar.js
+++ b/node_modules/react-native-deprecated-custom-components/src/NavigatorBreadcrumbNavigationBar.js
@@ -93,9 +93,9 @@ class NavigatorBreadcrumbNavigationBar extends React.Component {
       titleContentForRoute: PropTypes.func,
       iconForRoute: PropTypes.func,
     }),
-    navState: React.PropTypes.shape({
-      routeStack: React.PropTypes.arrayOf(React.PropTypes.object),
-      presentedIndex: React.PropTypes.number,
+    navState: PropTypes.shape({
+      routeStack: PropTypes.arrayOf(PropTypes.object),
+      presentedIndex: PropTypes.number,
     }),
     style: ViewPropTypes.style,
   };

Patches failing unexpectedly/unnecessarily on upgrades.

I'm currently using patch-package 6.0.0-5 on Ubuntu Linux 16.04 with node v8.11.1 and yarn 1.6.0.

I am finding that when a package is upgraded using patch-package 6.0.0-5 the patch for the previous version almost always fails to apply, and reports that there was a conflict. In the v5.x.x series of patch-package most patches were still able to be applied to the next version.

Usually, the failed patch applies with no problems using the command-line patch command.

I'm attaching a patch for react-scripts-ts as an example of one of the unexpected failures. It was made for react-scripts-ts v2.15.1. On upgrading to react-scripts-ts v2.16.0, patch-package reported the following error and refused to use the old patch:

**ERROR** Failed to apply patch for package react-scripts-ts

  This error was caused because react-scripts-ts has changed since you
  made the patch file for it. This introduced conflicts with your patch,
  just like a merge conflict in Git when separate incompatible changes are
  made to the same piece of code.

  Maybe this means your patch file is no longer necessary, in which case
  hooray! Just delete it!

  Otherwise, you need to manually fix the patch file. Or generate a new one

  To generate a new one, just repeat the steps you made to generate the first
  one, but accounting for the changes in react-scripts-ts.

  i.e. make changes, run `patch-package react-scripts-ts`, and commit.

  To manually fix a patch file, Run:

     patch -p1 -i patches/react-scripts-ts+2.15.1.patch --verbose --dry-run

  To list rejected hunks. A 'hunk' is a section of patch file that describes
  one contiguous area of changes. They are numbered from 1 and begin with lines
  that look like this:

    @@ -48,5 +49,6 @@ function foo(bar) {

  Remove the conflicting hunks, then manually edit files in

    node_modules/react-scripts-ts

  to reflect the changes that the conflicting hunks were supposed to make.

  Then run `patch-package react-scripts-ts`

  Info:
    Patch was made for version 2.15.1
    Meanwhile node_modules/react-scripts-ts is version 2.16.0

error Command failed with exit code 1.

Using patch applied the patch with minor line offsets to the second & third chunk:

$> patch -p1 -i patches/react-scripts-ts+2.15.1.patch
patching file node_modules/react-scripts-ts/config/paths.js
Hunk #2 succeeded at 72 (offset 1 line).
Hunk #3 succeeded at 105 (offset 2 lines).

I know that there was a change in how patches are applied in the v6 branch. I think the above indicates that there may be an issue with the current implementation, as the example patch really should have been able to be applied to the newer react-scripts-ts package version.

[Feature] Reference a PR via URL to create Patch

The list of outstanding PRs in react-native and the react community is long. It would be great, if we could add links to those PRs i.e. inside the package json, so the PR is applied automatically.

As an interface we could simply add them to the package.json

Proposal

By simply applying .patch or .diff to a github PR, a full fledge patch is provided. This would make patching much simpler.

Try it out:
Pull Request: facebook/react-native#12807
Pull Request as Patch: https://github.com/facebook/react-native/pull/12807.patch

To manage this centrally, we could just use the package.json:

// pacakge.json
{
  "name": "name",
  "version": "1.0.0",
  "dependencies": {
    "react": "16.0.0-alpha.12",
    "react-native": "^0.47.2",
    "react-native-scandit": "^1.1.7",
    "styled-components": "^2.1.2",
    "patch-package": "X.XX"
  },

// New Property for patch-package
  "patch-package": {
    "react-native": [
      {
        // Link to PR. Most cases, all what is needed.
        "pullRequest": "https://github.com/facebook/react-native/pull/12807",
        // Optional. Default is head. Leads to: https://github.com/facebook/react-native/pull/12807/commits/1a44b86e4af6dbb62819348cd963ffa6a443f32e
        "commit": "1a44b86e4af6dbb62819348cd963ffa6a443f32e", 
        // Optional. Restrict to specific package version or version range
        "version": "^0.47.2",
        // Optional. In case the package to be patched is in a subfolder of the repository
        "fromBaseFolder": ".", 
        // Optional. In case the folder we want to patch is called differently in the npm distribution, due to some build script
        "targetBaseFolder": ".", 
        // Optional. Restrict the scope of the applied patch
        "restrictChangesToPathFromBaseFolder": [
          "ReactAndroid/src/main/java/com/facebook/react/uimanager",
          "ReactAndroid/src/main/java/com/facebook/react/views/webview"
        ] 
      },
      // next patch in array for react-native
      {} 
    ]
  },
// End new Property

The patch file follows all the commits in the subject line. So to limit a patch up until a specific point, simply truncate it after the last wanted SHA. I.e. sometimes PRs are merged so late, that they are adapted to a new published version we not yet use.

screen shot 2017-09-11 at 10 45 09

Relevance

patch-package is necessary. The maintainers can just not follow up. However, this is an even stronger incentive to create private hacks because patches are difficult to share. By allowing a "simple" reference to a PR, the community is incentivised to make at least a PR to the upstream package and reference that PR them self as an easier way of patching until it is merged.

Btw: This approach has the nice side effect, that testing PRs becomes dump easy for novices. Up on problems, people will report back/complain to the PR, enforcing quality and bringing less garbage PRs inside a repo!

Prior to patch package, we applied a few patches with the vanilla bash commands via a post install script. Not ideal.

And I said it before. Love your sharp mind in all this.

Patch includes temp file directories

I'm using patch-package in a Cygwin ZSH shell (I don't know if that's relevant). I depend on onessg. When I run patch-package onessg, I get the following:

patch-package
--- a/node_modules/onessg/index.js
+++ b/node_modules/onessg/index.js
@@ -31,12 +31,16 @@ function processFile(filePath) {
   .then(middleware)
   .then(getDefaults)
   .then(data => {
+    if (data._draft && !conf.draft) return;
+
     // If _layout, render it:
     if (data._layout) return render(data);
     // Else, return _body:
     else return data._body;
   })
   .then(html => {
+    if (html === void 0) return;
+    
     // Get path to write to using path-extra:
     var writePath = path.replaceExt(path.join(conf.dist, filePath), '.html');
     // Output using fs-extra:
@@ -72,7 +76,7 @@ function middleware(data) {
   case '.md':
   case '.markdown':
     // Render markdown:
-    return marked(data._body)
+    return (conf.renderer || marked)(data._body)
     .then(res => {
       // Overwrite data._body:
       data._body = res;
--- a/node_modules/onessg/node_modules/fs-extra/package.json
+++ b/node_modules/onessg/node_modules/fs-extra/package.json
@@ -2,7 +2,7 @@
   "_args": [
     [
       "[email protected]",
-      "C:\\Tools\\cygwin64\\tmp\\tmp-1573262pyOIX4Olmm"
+      "C:\\Users\\me\\Source\\website\\site"
     ]
   ],
   "_development": true,
@@ -27,7 +27,7 @@
   ],
   "_resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
   "_spec": "2.1.2",
-  "_where": "C:\\Tools\\cygwin64\\tmp\\tmp-1573262pyOIX4Olmm",
+  "_where": "C:\\Users\\me\\Source\\website\\site",
   "author": {
     "name": "JP Richardson",
     "email": "[email protected]"
--- a/node_modules/onessg/node_modules/jsonfile/package.json
+++ b/node_modules/onessg/node_modules/jsonfile/package.json
@@ -2,7 +2,7 @@
   "_args": [
     [
       "[email protected]",
-      "C:\\Tools\\cygwin64\\tmp\\tmp-1573262pyOIX4Olmm"
+      "C:\\Users\\me\\Source\\website\\site"
     ]
   ],
   "_development": true,
@@ -27,7 +27,7 @@
   ],
   "_resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
   "_spec": "2.4.0",
-  "_where": "C:\\Tools\\cygwin64\\tmp\\tmp-1573262pyOIX4Olmm",
+  "_where": "C:\\Users\\me\\Source\\website\\site",
   "author": {
     "name": "JP Richardson",
     "email": "[email protected]"

The patch file should only include the first part:

patch-package
--- a/node_modules/onessg/index.js
+++ b/node_modules/onessg/index.js
@@ -31,12 +31,16 @@ function processFile(filePath) {
   .then(middleware)
   .then(getDefaults)
   .then(data => {
+    if (data._draft && !conf.draft) return;
+
     // If _layout, render it:
     if (data._layout) return render(data);
     // Else, return _body:
     else return data._body;
   })
   .then(html => {
+    if (html === void 0) return;
+    
     // Get path to write to using path-extra:
     var writePath = path.replaceExt(path.join(conf.dist, filePath), '.html');
     // Output using fs-extra:
@@ -72,7 +76,7 @@ function middleware(data) {
   case '.md':
   case '.markdown':
     // Render markdown:
-    return marked(data._body)
+    return (conf.renderer || marked)(data._body)
     .then(res => {
       // Overwrite data._body:
       data._body = res;

[Windows] Error with git not finding the dir due to path join slashes

Getting this error:

Error: Command failed: git add -f 'node_modules\codemirror'
fatal: pathspec ''node_modules\codemirror'' did not match any files

    at checkExecSyncError (child_process.js:568:13)
    at Object.execSync (child_process.js:608:13)
    at tmpExec_1 ([REDACTED]\WebApp\node_modules\patch-package\dist\makePatch.js:41:65)
    at stageFiles ([REDACTED]\WebApp\node_modules\patch-package\dist\makePatch.js:58:13)
    at Object.makePatch [as default] ([REDACTED]\WebApp\node_modules\patch-package\dist\makePatch.js:71:9)
    at [REDACTED]\WebApp\node_modules\patch-package\dist\index.js:20:32
    at Array.forEach (native)
    at Object.<anonymous> ([REDACTED]\WebApp\node_modules\patch-package\dist\index.js:19:22)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)

cwd: 'C:\\Users\\Andrey\\AppData\\Local\\Temp\\tmp-717323zCq3bl394D3'

The path actually does exist under that temp directory (while script is running), and if I update source to force / instead of path.join (that produces \) it works.

Not sure if that's the right solution or there is some kind of extra escaping required.

Patching doesn't work

When patch-package is run.. the target files remain intact. I did some debugging and it turns out that 'git apply -v file.patch' is skipping patches.

Skipped patch 'node_modules/react-native-ssdp/lib/client.js'.
Skipped patch 'node_modules/react-native-ssdp/lib/index.js'.
Skipped patch 'node_modules/react-native-ssdp/node_modules/react-native-udp/UdpSocket.js'.

Not sure why. This happens on Windows and MacOS.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.