Coder Social home page Coder Social logo

vaimo / composer-patches Goto Github PK

View Code? Open in Web Editor NEW
272.0 11.0 40.0 1.65 MB

Applies a patch from a local or remote file to any package that is part of a given composer project. Patches can be defined both on project and on package level. Optional support for patch versioning, sequencing, custom patch applier configuration and composer command for testing/troubleshooting patches.

License: MIT License

PHP 91.42% Shell 8.37% Roff 0.21%
composer maintenance constraints patching patcher patches applier composer-plugin plugin composer-commands

composer-patches's Introduction

Vaimo Composer Patches

Latest Stable Version Build Status Total Downloads Daily Downloads Minimum PHP Version Scrutinizer Code Quality Code Climate

Applies a patch from a local or remote file to any package that is part of a given composer project. Patches can be defined both on project and on package level in package config or separate JSON file. Declaration-free mode (using embedded info within patch files) is available as well.

The way the patches are applied (the commands, pre-checks) by the plugin is fully configurable (including the actual commands that are executed to apply the patch) from the composer.json of the project.

Note that the plugin is kept on very old PHP version as legacy software is usually the most common context where patches are needed.

Full Documentation

  • Basic Usage - Defining patches via configuration files or embedded metadata
  • Advanced Usage - Advanced usage options when defining patches
  • Configuration - Configuration options for the patch applier
  • Commands - Details on the CLI commands that ship with the plugin
  • Environment Variables - Environment variables to change plugin behavior
  • Error Handling - Handling encountered errors
  • Development - Details on the development workflow of the plugin
  • Examples - Examples on usage of the plugin
  • Changes - List of changes/fixes per plugin release

Quick Start

Composer packages can be targeted with patches in two ways:

  • Embedded metadata (recommended default approach)
  • JSON declaration and embedded (recommended for remote patches)

Usage: Embedded Metadata

{
  "require": {
    "some/package-name": "1.2.3"
  },
  "extra": {
    "patcher": {
      "search": "patches"
    }
  }
}

Contents of patches/changes.patch:

This patch changes... 
absolutely everything

@package some/package-name

--- Models/Example.php.org
+++ Models/Example.php
@@ -31,7 +31,7 @@
      */
     protected function someFunction($someArg)
     {
-        $var1 = 123;
+        $var1 = 456; // patched by composer-patches
         /**
          * rest of the logic of the function
          */

As a good practice you might want to add a hint, that the file was patched.

Full list of tag options (that cover all features of the plugin can be found HERE).

Note that tags cover most of the features of the module so every explanation given for the json declaration of the patches applies for tags as well.

Usage: JSON Declaration

{
  "require": {
    "some/package-name": "1.2.3"
  },
  "extra": {
    "patches": {
      "some/package-name": {
        "This patch changes ... absolutely everything": "patches/changes.patch",
        "remote patch": "http://www.example.com/remote-patch.patch",
        "remote patch with checksum check": {
          "source": "http://www.example.com/other-patch.patch",
          "sha1": "5a52eeee822c068ea19f0f56c7518d8a05aef16e"
        }
      }
    }
  }
}

Contents of patches/changes.patch:

--- Models/Example.php.org
+++ Models/Example.php
@@ -31,7 +31,7 @@
      */
     protected function someFunction($someArg)
     {
-        $var1 = 123;
+        $var1 = 456;
         /**
          * rest of the logic of the function
          */

Applier Configuration

The way patches are applied can be manipulated by changing the configuration of the patcher or by introducing additional patch appliers.

In most cases there should not be much of a need to reconfigure the module as it does ship with reasonable defaults. The appliers supported by default: patch, git.

More information on said topic can be found HERE.

Upgrades

When upgrading the module, one might encounter odd crashes about classes not being found or class constructor arguments being wrong.

This usually means that the class structure or constructor footprint in some of the classes have changed after the upgrade which means that the plugin might be running with some classes from the old and some classes from the new version.

Due to the fact that the patcher kicks in very late in the process of installing a project (before auto-loader generation), developers are advised to re-execute composer install.

Ideally, plugins should always be updated with explicit --no-plugins flag added to the composer update call to avoid issues that plugin usage with potentially mixed logic from two different plugin releases being in use.

composer-patches's People

Contributors

adamj88 avatar allanpaiste avatar amenk avatar bogdan-soroka-monsoonconsulting avatar bsod85 avatar c33s avatar cweagans avatar dave1010 avatar dennisverspuij avatar dependabot[bot] avatar diazwatson avatar doncallisto avatar evktalo avatar greg-1-anderson avatar h3rj4n avatar hostep avatar johnorourke avatar kayue avatar konstantinkuklin avatar lionsad avatar mougrim avatar peterjaap avatar pierrotevrard-idp avatar pivulic avatar seldaek avatar v-r avatar valga avatar yched avatar zamoroka avatar zamoroka-vaimo 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

composer-patches's Issues

Avoid conflicts with other patch applier plugins

Is your feature request related to a problem? Please describe.

The plugin clashes with other Composer plugins that deal with similar topic - making it unviable to use the module as dependency.

The issue comes from using general extra.patches for the patches reference (patches-search is fine though).

Describe the solution you'd like

Add configuration option on package-level where the plugin would only deal with applying patches from the packages that use it as dependency. When the plugin is not required by project root and all of the packages claim exclusive usage of the patcher, avoid applying patches from anywhere else.

In short, this would mean that the patch applier would only work against modules that directly, explicitly require it.

Additionally: output a warning when other plugins with same purpose present in a project. In that case allow the more focused functionality to be enabled via ROOT package configuration.

Describe alternatives you've considered

Another alternative would be just to warn the user and not provide any way to continue which would just be more inconvenient.

Yet another would be to switch the configuration keys for patch definition to completely new keys.

or ... allow the patches owner package to define they key from where the patches are read from.

patch:undo command resets applied patches info, but does not undo the changes

Using the command patch:undo does not undo the changes done to files in the vendor folder. When subsequently running patch:apply, receive an error that the patch is already applied.

Pre-requisites
This is based on an installation of Magento 2.3.0 and composter-patches 4.20.2
patches.json file:

{
    "magento/product-enterprise-edition": {
        "[MDVA-1400] Unable to send the cookie; Maximum number of cookies would be exceeded": {
            "source": {
                "2.0.* || 2.1.0 - 2.1.17 || 2.2.0 - 2.2.3": "https://magentopatches.com/2.2/MDVA-1400_2.0_COMPOSER_v1.patch",
                "2.2.4 - 2.2.11 || 2.3.0 - 2.3.4": "https://magentopatches.com/2.2/MDVA-1400_2.0_v1.patch"
            }
        }
    }
}

patch file:

From 3776a9196ba858da9b51ea745f13aa2f61faaa58 Mon Sep 17 00:00:00 2001
From: Ivan Novykov <[email protected]>
Date: Mon, 7 Nov 2016 21:30:22 +0200
Subject: [PATCH] MDVA-1400: [Magento Cloud] - Regular 503 errors on production

---
 vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php       | 2 +-
 1 files changed, 1 insertions(+), 2 1eletions(-)

diff --git a/vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php b/vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php
index 0463fd8..ce5e5d8 100644
--- a/vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php
+++ b/vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php
@@ -29,7 +29,7 @@ class PhpCookieManager implements CookieManagerInterface
      * RFC 2109 - Page 15
      * http://www.ietf.org/rfc/rfc6265.txt
      */
-    const MAX_NUM_COOKIES = 50;
+    const MAX_NUM_COOKIES = 200;
     const MAX_COOKIE_SIZE = 4096;
     const EXPIRE_NOW_TIME = 1;
     const EXPIRE_AT_END_OF_SESSION_TIME = 0;

To Reproduce
Steps to reproduce the behavior:

  1. Have the above configuration
  2. Run composer patch:apply (or have it automatically applied as part of composer install)
  3. Run composer patch:undo
  4. Run composer patch:apply

Expected
All patches are reverted and re-applied

Actual
Patch info is reset, but changes are not revered

Notes
As we are supporting several clients on different Magento versions, we are trying to maintain a single list of patches and apply patches based on the version of magento/product-enterprise-edition

note that patch is a required util

Note that patch (the CLI tool) is a prerequisite for patch-package.
We didn't have it on one of our production systems and were wondering why the deploy failed.

also note that it just failed with couldn't apply patch instead of a command not found indication.

Cannot be used with PHP version over 5.6

drupol/phposinfo 1.6.1.2 requires php ^5.3 || ^5.4 || ^5.5 || ^5.6 -> your PHP version (7) does not satisfy that requirement.

The dependency does not allow php version over 5.6.

different line endings

If the file uses CRLF, and the patch don't uses CRLF

patching file <file>
Hunk #1 FAILED at <line> (different line endings).

If the file uses CRLF, and the patch uses CRLF, and the --binary flag is not set:

(Stripping trailing CRs from patch; use --binary to disable.)
patching file <file>
Hunk #1 FAILED at <line> (different line endings).

--ignore-whitespace dosn't work, but adding --binary worked

Does ist support using patches from the Magento Main repo?

I am using the following configuration:

"extra": {
    "magento-force": "override",
    "patches": {
        "magento/module-offline-shipping": {
            "Bugfix Issue 11720 notice": "https://github.com/magento/magento2/commit/f64281102c6c16b0e67d779d178054f179044187.patch"
        }
    }
}

But the patched seems to ignore the hunk:

Processing patches configuration
  - Applying patches for magento/module-offline-shipping (1)
    ~ project: https://github.com/magento/magento2/commit/f64281102c6c16b0e67d779d178054f179044187.patch
      Bugfix Issue 11720 notice
can't find file to patch at input line 15
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|From f64281102c6c16b0e67d779d178054f179044187 Mon Sep 17 00:00:00 2001
|From: Alexander Menk <[email protected]>
|Date: Wed, 25 Oct 2017 13:33:13 +0200
|Subject: [PATCH] Fix Notice: freePackageValue is undefined
|
|As visible from the code, freePackageValue can be undefined in some cases but accessed. `$request->getAllItems() == false` and `$request->getPackageQty() == $freeQty` is true and `!empty($rate) && $rate['price'] >= 0` is false This fixes this
|---
| app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php | 3 ++-
| 1 file changed, 2 insertions(+), 1 deletion(-)
|
|diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
|index b12691ad1624..87d4b984cf93 100644
|--- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
|+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
--------------------------
File to patch: 
Skip this patch? [y] 
Skipping patch.
1 out of 1 hunk ignored
Validation (type=PATCH) failed with p=0. Retrying with p=1
SUCCESS with type=GIT (p=0)

Writing patch info to install file

As you probably know (as there are Magento examples in the readme), Magento 2 splits the full repo to the git modules. I guess the module supports that? But do I have do specific some -p5 parameter to split out app/code/Magento/OfflineShipping/ ?

Reversed patch application not detected, causing upstream fix to be removed

In my project I have a simple one-line addition patch, that was applied upstream in a new version of the targeted composer package. Due to this, the patch command invocation detected that this is an already applied patch, and applied the patch in reverse, effectively removing the fix from the package.

From the example 'operation-failures' configuration I assume that this is supposed to be treated as an error condition, as it checks for reversals, but this doesn't seem to happen.

Expected
Non-application of patch, or warning/error stating patch is already applied (so we can clean up or restrict our patches to appropriate package versions)

Actual
Reverse application of patch, effectively removing the upstream fix causing the issue the patch was meant to fix to return

Notes
Full verbose output of patch application process:

  - Applying patches for adyen/module-payment (1)
    ~ reach-digital/project-grandvision: composer-patches/adyen-module-payment-fix-csrf-validation.patch [NEW]
      Fix CSRF validation with Magento 2.3.2
      Executing command (/data/web/magento2/vendor/adyen/module-payment): which patch
      /usr/bin/patch
      Executing command (/data/web/magento2/vendor/adyen/module-payment): /usr/bin/patch -t --verbose -p'0' --no-backup-if-mismatch --dry-run < '/data/web/magento2/composer-patches/adyen-module-payment-fix-csrf-validation.patch'
      Hmm...  Looks like a unified diff to me...
      can't find file to patch at input line 8
      Perhaps you used the wrong -p or --strip option?
      The text leading up to this was:
      --------------------------
      |Fix CSRF validation with Magento 2.3.2
      |
      |@package adyen/module-payment
      |
      |diff -Nru adyen/module-payment_orig/Controller/Process/Json.php adyen/module-payment/Controller/Process/Json.php
      |--- adyen/module-payment_orig/Controller/Process/Json.php	2019-08-16 11:35:13.714588586 +0000
      |+++ adyen/module-payment/Controller/Process/Json.php	2019-08-16 11:35:31.410547035 +0000
      --------------------------
      No file to patch.  Skipping patch.
      Hunk #1 ignored at 75.
      1 out of 1 hunk ignored
      done
      Validation (type=PATCH) failed with p=0
      Executing command (/data/web/magento2/vendor/adyen/module-payment): which git
      /usr/bin/git
      *** The expected result to execution is a failure***
      Executing command (/data/web/magento2/vendor/adyen/module-payment): cd .. && /usr/bin/git rev-parse --is-inside-work-tree
      true
      Usability test (type=GIT) failed with p=0
      Executing command (/data/web/magento2/vendor/adyen/module-payment): /usr/bin/patch -t --verbose -p'1' --no-backup-if-mismatch --dry-run < '/data/web/magento2/composer-patches/adyen-module-payment-fix-csrf-validation.patch'
      Hmm...
      Looks like a unified diff to me...
      can't find file to patch at input line 8
      Perhaps you used the wrong -p or --strip option?
      The text leading up to this was:
      --------------------------
      |Fix CSRF validation with Magento 2.3.2
      |
      |@package adyen/module-payment
      |
      |diff -Nru adyen/module-payment_orig/Controller/Process/Json.php adyen/module-payment/Controller/Process/Json.php
      |--- adyen/module-payment_orig/Controller/Process/Json.php	2019-08-16 11:35:13.714588586 +0000
      |+++ adyen/module-payment/Controller/Process/Json.php	2019-08-16 11:35:31.410547035 +0000
      --------------------------
      No file to patch.  Skipping patch.
      Hunk #1 ignored at 75.
      1 out of 1 hunk ignored
      done
      Validation (type=PATCH) failed with p=1
      *** The expected result to execution is a failure***
      Usability test (type=GIT) failed with p=1
      Executing command (/data/web/magento2/vendor/adyen/module-payment): /usr/bin/patch -t --verbose -p'2' --no-backup-if-mismatch --dry-run < '/data/web/magento2/composer-patches/adyen-module-payment-fix-csrf-validation.patch'
      Hmm...  Looks like a unified diff to me...
      The text leading up to this was:
      --------------------------
      |Fix CSRF validation with Magento 2.3.2
      |
      |@package adyen/module-payment
      |
      |diff -Nru adyen/module-payment_orig/Controller/Process/Json.php adyen/module-payment/Controller/Process/Json.php
      |--- adyen/module-payment_orig/Controller/Process/Json.php	2019-08-16 11:35:13.714588586 +0000
      |+++ adyen/module-payment/Controller/Process/Json.php	2019-08-16 11:35:31.410547035 +0000
      --------------------------
      checking file Controller/Process/Json.php
      Using Plan A...
      Reversed (or previously applied) patch detected!  Assuming -R.
      Hunk #1 succeeded at 83 with fuzz 2 (offset 8 lines).
      done
      Executing command (/data/web/magento2/vendor/adyen/module-payment): /usr/bin/patch -t -p'2' --no-backup-if-mismatch < '/data/web/magento2/composer-patches/adyen-module-payment-fix-csrf-validation.patch'
      patching file Controller/Process/Json.php
      Reversed (or previously applied) patch detected!  Assuming -R.
      Hunk #1 succeeded at 83 with fuzz 2 (offset 8 lines).
      SUCCESS with type=PATCH (p=2)

Writing patch info to install file

Patch contents:

Fix CSRF validation with Magento 2.3.2

@package adyen/module-payment

diff -Nru adyen/module-payment_orig/Controller/Process/Json.php adyen/module-payment/Controller/Process/Json.php
--- adyen/module-payment_orig/Controller/Process/Json.php	2019-08-16 11:35:13.714588586 +0000
+++ adyen/module-payment/Controller/Process/Json.php	2019-08-16 11:35:31.410547035 +0000
@@ -75,6 +75,7 @@
             $request = $this->getRequest();
             if ($request instanceof HttpRequest && $request->isPost()) {
                 $request->setParam('isAjax', true);
+                $request->getHeaders()->addHeaderLine('X_REQUESTED_WITH', 'XMLHttpRequest');
             }
         }
     }

Targeted composer package +version: adyen/module-payment 5.0.2

Possibility to disable this composer plugin from executing

Is your feature request related to a problem? Please describe.
Hi

I have a very specific case where I would like all composer plugins to still execute during composer install and composer update, just not this one.
As far as I know, in composer we only have the possibility to disable all plugins at once with the --no-plugins flag but not specific ones.

Describe the solution you'd like
Maybe introduce an extra environment variable to stop the plugin from acting?

Describe alternatives you've considered
None yet

Additional context
We have a custom application which runs every night over all our projects and tries to update all dependencies to the latest available version and generates a report based on how well this works. The application often fails on trying to apply patches
by this plugin because if we update a package to the latest version, a patch might no longer apply cleanly to it.
Also, since the composer v2 compatble version of this plugin was created, and we update this plugin itself to the latest version, it always crashes with Argument 1 passed to Vaimo\ComposerPatches\Patch\DefinitionList\LoaderComponents\DownloaderComponent::__construct() must be an instance of Composer\Composer, instance of Composer\Package\CompletePackage given. Only a second execution of composer install/update works without an error.
If we have a flag to not execute this plugin, we can work around this issue I hope.

I'd understand it if you don't want to implement this, since this is a very specific case which probably nobody else needs 🙂

Empty needle

A clear and concise description of what the bug is.

When we tried to uninstall Klarna on our M2.3.3 project, we got an exception strpos() Empty Needle. We made a patch here, just in case $item was blank/null we returned false: \Vaimo\ComposerPatches\Package\ConfigAnalyser::ownsNamespace

Expected
No error when running composer functions

Actual
`$aja project remove-module klarna/m2-checkout
Dependency "composer/composer" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 1 update, 8 removals

  • Removing phpxmlrpc/phpxmlrpc (4.4.1)
    Removing Phpxmlrpc/Phpxmlrpc
    [ErrorException]
    strpos(): Empty needle `

Notes
I didn't figure out What caused a blank $item in that function...

Packages (targeted by patches) reinstalled on fresh install

The current logic has been built so that when there are patches that have not yet been applied, the packages that they target are re-installed beforehand - even when there are no patches applied previously that would call such a re-install.

Pre-requisites

  1. Have a project that uses the plugin
  2. Have patches defined that target some package
  3. Have no vendor folder (clean install)
  4. Have composer.lock (just makes the repetition faster)

To Reproduce

Steps to reproduce the behaviour:

  1. composer install -vvv

Expected

  1. packages are installed
  2. log contains information about patches being collected
  3. patches are applied

Actual

  1. packages are installed
  2. log contains information about patches being collected
  3. patched packages are again re-installed (note: unzipped from cache, not re-downloaded, but still)
  4. patches are applied

Notes

This has always been the way the plugin works, but can give extra speed boost when avoided if possible.

Unfortunately I can't recall what exactly caused this to be the way it got implemented, but I do remember being more frugal about resets to cause some edge-case issues when using bundled patches. The test-coverage in terms of scenarios has to be greatly improved before this can be properly tightened up.

Use PhpUnit as test-runner

Is your feature request related to a problem? Please describe.

Currently the test scenarios are based on custom scripts that do not allow convenient development flow and test runner utilization via IDE. It also introduces avoidable overhead for new developers who otherwise could tap into their previous experience with commonly used testing frameworks/runners.

Describe the solution you'd like

Port over the installations/scenarios/assertions to run with PhpUnit runner. Make sure that IDE picks up the tests properly.

Describe alternatives you've considered

Have not seen a real need to consider any alternatives here as PhpUnit is relatively light-weight and well known.

Additional context

This change would also make it easier to run the tests on different platforms as long as php is available. It will also make much easier for users to step through the patch applying flow.

Composer 2 - Package not available during patching

A clear and concise description of what the bug is.

Pre-requisites

  1. Magento 2.3.6 installed via composer
  2. Add compatibility for composer 2 https://gist.github.com/hostep/26de0bf2bb695eb3b6d51858c2e4562e
  3. Install vaimo composer patches using composer require vaimo/composer-patches 4.22.1
  4. Composer version 2.0.9 2021-01-27 16:09:27

To Reproduce
Steps to reproduce the behavior:

  1. Add following lines to composer.json
...
            "extra": {
                "magento-force": "override",
                "patches": {
                    "tedivm/jshrink": {
                        "Static content deploy - Performance fix for JS/CSS minifier": {
                            "source": "patches/jshrink.diff",
                            "level": 1
                        }
                    },
...

  1. put the following content in the patches/jshrink.diff:
diff --git a/src/JShrink/Minifier.php b/src/JShrink/Minifier.php
index ad8157f..fad43d2 100644
--- a/src/JShrink/Minifier.php
+++ b/src/JShrink/Minifier.php
@@ -38,6 +38,13 @@ class Minifier
      */
     protected $input;
 
+    /**
+     * Length of input javascript.
+     *
+     * @var int
+     */
+    protected $len = 0;
+
     /**
      * The location of the character (in the input string) that is next to be
      * processed.
@@ -77,7 +84,7 @@ class Minifier
     /**
      * These characters are used to define strings.
      */
-    protected $stringDelimiters = ['\'', '"', '`'];
+    protected $stringDelimiters = ['\'' => true, '"' => true, '`' => true];
 
     /**
      * Contains the default options for minification. This array is merged with
@@ -86,7 +93,7 @@ class Minifier
      *
      * @var array
      */
-    protected static $defaultOptions = array('flaggedComments' => true);
+    protected static $defaultOptions = ['flaggedComments' => true];
 
     /**
      * Contains lock ids which are used to replace certain code patterns and
@@ -94,7 +101,7 @@ class Minifier
      *
      * @var array
      */
-    protected $locks = array();
+    protected $locks = [];
 
     /**
      * Takes a string containing javascript and removes unneeded characters in
@@ -105,7 +112,7 @@ class Minifier
      * @throws \Exception
      * @return bool|string
      */
-    public static function minify($js, $options = array())
+    public static function minify($js, $options = [])
     {
         try {
             ob_start();
@@ -157,21 +164,34 @@ protected function minifyDirectToOutput($js, $options)
     protected function initialize($js, $options)
     {
         $this->options = array_merge(static::$defaultOptions, $options);
-        $js = str_replace("\r\n", "\n", $js);
-        $js = str_replace('/**/', '', $js);
-        $this->input = str_replace("\r", "\n", $js);
+        $this->input = str_replace(["\r\n", '/**/', "\r"], ["\n", "", "\n"], $js);
 
         // We add a newline to the end of the script to make it easier to deal
         // with comments at the bottom of the script- this prevents the unclosed
         // comment error that can otherwise occur.
         $this->input .= PHP_EOL;
 
+        // save input length to skip calculation every time
+        $this->len = strlen($this->input);
+
         // Populate "a" with a new line, "b" with the first character, before
         // entering the loop
         $this->a = "\n";
         $this->b = $this->getReal();
     }
 
+    /**
+     * Characters that can't stand alone preserve the newline.
+     *
+     * @var array
+     */
+    protected $noNewLineCharacters = [
+        '(' => true,
+        '-' => true,
+        '+' => true,
+        '[' => true,
+        '@' => true];
+
     /**
      * The primary action occurs here. This function loops through the input string,
      * outputting anything that's relevant and discarding anything that is not.
@@ -183,7 +203,7 @@ protected function loop()
                 // new lines
                 case "\n":
                     // if the next line is something that can't stand alone preserve the newline
-                    if ($this->b !== false && strpos('(-+[@', $this->b) !== false) {
+                    if ($this->b !== false && isset($this->noNewLineCharacters[$this->b])) {
                         echo $this->a;
                         $this->saveString();
                         break;
@@ -226,7 +246,7 @@ protected function loop()
                                 break;
                             }
 
-                                // no break
+                        // no break
                         default:
                             // check for some regex that breaks stuff
                             if ($this->a === '/' && ($this->b === '\'' || $this->b === '"')) {
@@ -257,6 +277,7 @@ protected function loop()
     protected function clean()
     {
         unset($this->input);
+        $this->len = 0;
         $this->index = 0;
         $this->a = $this->b = '';
         unset($this->c);
@@ -276,7 +297,7 @@ protected function getChar()
             unset($this->c);
         } else {
             // Otherwise we start pulling from the input.
-            $char = substr($this->input, $this->index, 1);
+            $char = $this->index < $this->len ? $this->input[$this->index] : false;
 
             // If the next character doesn't exist return false.
             if (isset($char) && $char === false) {
@@ -289,7 +310,7 @@ protected function getChar()
 
         // Normalize all whitespace except for the newline character into a
         // standard space.
-        if ($char !== "\n" && ord($char) < 32) {
+        if ($char !== "\n" && $char < "\x20") {
             return ' ';
         }
 
@@ -340,7 +361,7 @@ protected function getReal()
      */
     protected function processOneLineComments($startIndex)
     {
-        $thirdCommentString = substr($this->input, $this->index, 1);
+        $thirdCommentString = $this->index < $this->len ? $this->input[$this->index] : false;
 
         // kill rest of line
         $this->getNext("\n");
@@ -429,7 +450,7 @@ protected function getNext($string)
         $this->index = $pos;
 
         // Return the first character of that string.
-        return substr($this->input, $this->index, 1);
+        return $this->index < $this->len ? $this->input[$this->index] : false;
     }
 
     /**
@@ -447,7 +468,7 @@ protected function saveString()
         $this->a = $this->b;
 
         // If this isn't a string we don't need to do anything.
-        if (!in_array($this->a, $this->stringDelimiters)) {
+        if (!isset($this->stringDelimiters[$this->a])) {
             return;
         }
 
@@ -557,7 +578,7 @@ protected function lock($js)
         /* lock things like <code>"asd" + ++x;</code> */
         $lock = '"LOCK---' . crc32(time()) . '"';
 
-        $matches = array();
+        $matches = [];
         preg_match('/([+-])(\s+)([+-])/S', $js, $matches);
         if (empty($matches)) {
             return $js;
  1. Run composer install -vvv

Expected
The patch should be applied

Actual
Patch applying failing with "No such file or directory" error:
image

image

Notes
The directory of the package is empty after the command failure
image

The composer update crashes on plugin upgrade

This does not happen all the times, but when the amount of changes introduced is large enough and covers things like:

  • renaming methods
  • re-ordering arguments
  • adding new arguments

... then it can cause issues where half of the already in-memory classes are from the old plugin and half from the new (depends on when they were loaded by the autoloader)

Pre-requisites

  1. Use any composer version, on any platform
  2. A use Composer project without the plugin

To Reproduce

  1. Install the plugin on 4.0.0
  2. Upgrade the plugin to latest available version

Expected

The plugin either updates and works right away without issues or some notification is shown on the fact that it can't execute within that run.

Actual

The plugin crashes with a call stack that might lead the user to think that it's broken/unusable - no extra guide presented in the output about the fact that new run would actually work a-ok.

Notes

Maybe the way to deal with this would be to just report that the plugin did not run when it detects that it was updated and a guide would be included how to run it manually.

Broken composer.lock after aborting command

Broken lock file without feedback when composer hangs/is killed in middle of process.

Pre-requisites

  1. Have clean project without patches applied

To Reproduce
Steps to reproduce the behavior:

  1. Run eg. composer update for a random package
  2. Abort execution at some point using (ctrl-c) At least during "Processing patches configuration" step this has happened.

Expected
Composer.lock does not contain "applied_patches"

Actual

patches_applied objects are applied to lock file, and (likely) accidentally committed to VCS:

                 "php": "~7.1.3||~7.2.0"
             },
             "type": "magento2-module",
+            "extra": {
+                "patches_applied": {
+                    "vaimo/patches-magento::::src/Magento_Deploy/fix-verbosity-to-affect-compilation-errors-reporting/version-100.2.0.patch": "Fix: verbosity to affect compilation errors to aid developer with extra information, md5:dd89217197b797738e8f39d52155fe29"
+                }
+            },
             "autoload": {
                 "files": [
                     "cli_commands.php",

Notes
When patches_applied is accidentally committed to lock file, it causes patches not being applied during build process, when composer thinks they are already applied.

Move files related to development to separate branch

The plugin currently includes quite a many files that are only needed for development which end up being installed to every project that uses the plugin.

Create a new branch (develop) that would include those files that a person developing the module could git checkout develop when setting up the development environment.

Parse error: syntax error, unexpected 'LIST' (T_LIST)

Hi!
Many thanks for your changes! Composer-patches became more configurable and useful.
I have next problem:
For php5.5 and php5.6 (maybe other old versions) there is next problem:

PHP Parse error:  syntax error, unexpected 'LIST' (T_LIST) in vendor/vaimo/composer-patches/src/Factories/PatchesRepositoryFactory.php on line 50.

The problem is with constant LIST in file src/Config.php, which is keyword in php.
There is "php": ">=5.3.0" in composer.json, so it looks like should be supported.
I suggest to rename constant to PATCHES_LIST. I would create pull request with constant renaming if you say, what new names of constants.

Also it would be great to add tests for all supported versions, and run it using travis-ci, or something like this.

Include VSCode devcontainer config

Is your feature request related to a problem? Please describe.

To allow new developers to be included to a project as efficiently as possible it would be great if they could start with already proven/usable IDE setup that has all tools/runners/views in place.

Describe the solution you'd like

There are several really awesome tools that ship with VSCode, where one of them allows remote development in a custom development container and project-based extension setup that could be used here where contributors could rely on having a standard setup/editor/tools made available for them rather than having to start from a blank slate (which would remain an option when needed).

The configuration that gets added to the repository is VERY light-weight (one docker-compose yaml, devcontainer.json and few scripts for Mutagen).

Describe alternatives you've considered

Used to work with WebStorm in the past, but converted over to VSCode when discovered the Remove Development and have not looked back since.

Additional context

https://code.visualstudio.com/docs/remote/containers

Uncaught Error: Call to a member function getRequires() on bool

PHP Fatal error:  Uncaught Error: Call to a member function getRequires() on bool in /dev/code/vendor/vaimo/composer-patches/src/Patch/DefinitionList/LoaderComponents/ConstraintsComponent.php:62
Stack trace:
#0 /dev/code/vendor/vaimo/composer-patches/src/Patch/DefinitionList/Loader.php(62): Vaimo\ComposerPatches\Patch\DefinitionList\LoaderComponents\ConstraintsComponent->process(Array, Array)
#1 [internal function]: Vaimo\ComposerPatches\Patch\DefinitionList\Loader->Vaimo\ComposerPatches\Patch\DefinitionList\{closure}(Array, Object(Vaimo\ComposerPatches\Patch\DefinitionList\LoaderComponents\ConstraintsComponent))
#2 /dev/code/vendor/vaimo/composer-patches/src/Patch/DefinitionList/Loader.php(60): array_reduce(Array, Object(Closure), Array)
#3 /dev/code/vendor/vaimo/composer-patches/src/Repository/Processor.php(40): Vaimo\ComposerPatches\Patch\DefinitionList\Loader->loadFromPacka in /dev/code/vendor/vaimo/composer-patches/src/Patch/DefinitionList/LoaderComponents/ConstraintsComponent.php on line 62

I am getting the above error when I run composer require vaimo/composer-patches

PHP Fatal error: Interface 'Composer\Plugin\Capability\CommandProvider' not found

A clear and concise description of what the bug is.

Pre-requisites

  1. magento 2.1.9
  2. module version 4.14.0

To Reproduce
Steps to reproduce the behavior:

  1. composer update to 4.16.0
  2. bin/magento c:f

Expected

Flushed cache types:
config
layout
block_html
collections
reflection
db_ddl
eav
customer_notification
config_integration
config_integration_api
full_page
config_webservice
translate

Actual

PHP Fatal error:  Interface 'Composer\Plugin\Capability\CommandProvider' not found in /vendor/vaimo/composer-patches/src/Composer/CommandsProvider.php on line 8
PHP Stack trace:
PHP   1. {main}() /bin/magento:0
PHP   2. Magento\Framework\Console\Cli->__construct($name = *uninitialized*, $version = *uninitialized*) /bin/magento:22
PHP   3. Magento\Framework\App\ProductMetadata->getVersion() /vendor/magento/framework/Console/Cli.php:81
PHP   4. Magento\Framework\App\ProductMetadata->getSystemPackageVersion() /vendor/magento/framework/App/ProductMetadata.php:65
PHP   5. Magento\Framework\Composer\ComposerInformation->getSystemPackages() /vendor/magento/framework/App/ProductMetadata.php:104
PHP   6. Magento\Framework\Composer\ComposerInformation->getLocker() /vendor/magento/framework/Composer/ComposerInformation.php:242
PHP   7. Magento\Framework\Composer\ComposerInformation->getComposer() /vendor/magento/framework/Composer/ComposerInformation.php:375
PHP   8. Magento\Framework\Composer\ComposerFactory->create() /vendor/magento/framework/Composer/ComposerInformation.php:362
PHP   9. Composer\Factory::create($io = *uninitialized*, $config = *uninitialized*, $disablePlugins = *uninitialized*) /vendor/magento/framework/Composer/ComposerFactory.php:47
PHP  10. Composer\Factory->createComposer($io = *uninitialized*, $localConfig = *uninitialized*, $disablePlugins = *uninitialized*, $cwd = *uninitialized*, $fullLoad = *uninitialized*) /vendor/composer/composer/src/Composer/Factory.php:532
PHP  11. Composer\Plugin\PluginManager->loadInstalledPlugins() /vendor/composer/composer/src/Composer/Factory.php:354
PHP  12. Composer\Plugin\PluginManager->loadRepository($repo = *uninitialized*) /vendor/composer/composer/src/Composer/Plugin/PluginManager.php:76
PHP  13. Composer\Plugin\PluginManager->registerPackage($package = *uninitialized*, $failOnMissingClasses = *uninitialized*) /vendor/composer/composer/src/Composer/Plugin/PluginManager.php:240
PHP  14. Composer\Plugin\PluginManager->addPlugin($plugin = *uninitialized*) /vendor/composer/composer/src/Composer/Plugin/PluginManager.php:188
PHP  15. Vaimo\ComposerPatches\Plugin->activate($composer = *uninitialized*, $io = *uninitialized*) /vendor/composer/composer/src/Composer/Plugin/PluginManager.php:215
PHP  16. Vaimo\ComposerPatches\Bootstrap->preloadPluginClasses() /vendor/vaimo/composer-patches/src/Plugin.php:42
PHP  17. Vaimo\ComposerPatches\Package\SourcesPreloader->preload($package = *uninitialized*) /vendor/vaimo/composer-patches/src/Bootstrap.php:122
PHP  18. require_once() /vendor/vaimo/composer-patches/src/Package/SourcesPreloader.php:50

error on patch

hi

we have an issue on composer

Generating autoload files
Processing patches configuration
Nothing to patch
PHP Fatal error: Uncaught Error: Call to a member function setExtra() on array in /var/webroot/vendor/vaimo/composer-patches/src/Bootstrap.php:110
Stack trace:
#0 /var/webroot/vendor/vaimo/composer-patches/src/Plugin.php(65): Vaimo\ComposerPatches\Bootstrap->sanitizeLocker(Object(Composer\Package\Locker))
#1 [internal function]: Vaimo\ComposerPatches\Plugin->postInstall(Object(Composer\Script\Event))
#2 phar:///home/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php(176): call_user_func(Array, Object(Composer\Script\Event))
#3 phar:///home/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php(96): Composer\EventDispatcher\EventDispatcher->doDispatch(Object(Composer\Script\Event))
#4 phar:///home/composer.phar/src/Composer/Autoload/AutoloadGenerator.php(111): Composer\EventDispatcher\EventDispatcher->dispatchScript('pre-autoload-du...', true, Array, Array)
#5 phar:///home/composer.phar/ in /var/webroot/vendor/vaimo/composer-patches/src/Bootstrap.php on line 110

Fatal error: Uncaught Error: Call to a member function setExtra() on array in /var/webroot/vendor/vaimo/composer-patches/src/Bootstrap.php:110
Stack trace:
#0 /var/webroot/vendor/vaimo/composer-patches/src/Plugin.php(65): Vaimo\ComposerPatches\Bootstrap->sanitizeLocker(Object(Composer\Package\Locker))
#1 [internal function]: Vaimo\ComposerPatches\Plugin->postInstall(Object(Composer\Script\Event))
#2 phar:///home/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php(176): call_user_func(Array, Object(Composer\Script\Event))

did you know why?

Collaborate?

I'm not sure I understand why you forked this. I don't see a single issue or PR open from @allanpaiste in the main repo.

In any case, I'd love some assistance maintaining the original plugin if you're interested. 2.x is well in swing and will be adding substantial test coverage and functionality to the plugin, so if you're interested, now is the time to jump in.

Add patch markers to patched code

Is your feature request related to a problem? Please describe.

In case one is working on a large-scale project or works in an agency where the patching of project is handled by a specific core team - there might be cases where someone in a project team ends up relying on a piece of code/logic that has been introduced by a patch. Because the production code does not have any indicators that some rows were patched in (unless patch author has taken care of this), it takes extra effort to check this.

Describe the solution you'd like

Introduce mechanism that would automatically add comments near the patched in code. Might be reference to the file and package that owns the patch.

This would be somewhat tricky to achieve as the comments have to be removed in case there are multiple patches targeting the same part of the code (or that layer on top of each other -- something that is not out-of-this-world scenario when the patches are managed in relatively granular manner).

Describe alternatives you've considered

Enforcing comments in patches would be another way to achieve this (where the patch applier would just error out when patch does not introduce such contextual comments). Not very convenient though.

One could also consider erroring out when patch removes part of code without adding anything - which might be confusing as well (in this case the validator could require a one-liner replacement)

Additional context

This could be considered somewhat edge-case'y and might not be something that the main plugin needs, but have experienced situations where production code becomes very much unintentionally dependent on the patched-in code.

Patches dependency of dependency

Processing patches configuration
Nothing to patch

If I need to patch a dependency of dependency, I need to pull this dependency into my own composer.json.

This is not convenient and not correct.

Alphabetic ordering of patches-search files

In our TravisCI environment, it seems that vaimo/composer-patches are applied in random order, instead of alphabetic order.

I have multiple patches for a package, named as follows:

firebear-configurableproducts-1-fix-order-items.patch
firebear-configurableproducts-2-fix-qty-check.patch
firebear-configurableproducts-3-fix-console-command-early-db-access.patch
firebear-configurableproducts-4-fix-stock-indexer-query.patch

They are stored under the root package folder under composer-patches, and configured in composer.json through:

    "extra": {
        "patches-search": "composer-patches"
    },

In my local dev environment these are applied in alphabetic order; however in our TravisCI environment, patch 3 and 4 are applied first, which fails as patch 4 is dependent on patch 1.

Although you can enforce patch ordering with the @after keyword, it would be nice if alphabetic ordering could be enforced in some way, so we can just drop in patches with the right filename and be on our way.

I suppose making alphabetic sorting the default might break a lot of projects if they haven't used the @after keyword and patches by chance apply correctly, so alphabetic sorting should probably be made a toggle

Use drupol/phposinfo

Hi !

It seems that tivie/php-os-detector is a dependency. It can produces false results, see the corresponding issue: tivie/php-os-detector#3

Based on this, I've created my own package: drupol/phposinfo that fixes the issue.

This issue is to propose the replacement of tivie/php-os-detector with drupol/phposinfo.

Switch from bin/bash-scripts to php scripts to seamless run on windows

all scripts in bin are linux only. would be nice to use OS agnostic tools like php or https://robo.li to do all the task running.
a simple composer install schould not break it.

composer install
> bin/bootstrap-test-env
'bin' is not recognized as an internal or external command,
operable program or batch file.
Script bin/bootstrap-test-env handling the pre-install-cmd event returned with error code 1

Could run in windows?

I try to run this in windows, but it will have errors.
it can't read/write patch file in "/tmp" folder (could use TMP enviroment variable?)

composer patch:apply misses a --no-scripts option

running composer patch:apply --from-source -vvv always triggers the post-install-cmd which installs node modules, create symlinks, ...

all this sometimes not needed after patching but this plugin does not support the --no-scripts options the prevent to call the composer scripts

Package reset halted due to encountering local changes

From time to time I catch this error while installing composer packages. So what can be a possible reason of this happening? Thanks!

[Vaimo\ComposerPatches\Exceptions\PackageResetException]
Package reset halted due to encountering local changes

patch: unrecognized option `--verbose' (FreeBSD)

A clear and concise description of what the bug is.

Pre-requisites

  1. Have a project with patches
  2. have patch applier at version 'patch 2.0-12u11 FreeBSD'

To Reproduce
Steps to reproduce the behavior:

  1. composer patch:apply -vvv

Expected
No errors

Actual
Executing command (content/plugins/autoptimize/): /usr/bin/patch -t --verbose -p'1' --no-backup-if-mismatch --dry-run < '[site-path]/patches/autoptimize/2.5.1/html-fix-no-style-in-footer.patch'
patch: unrecognized option `--verbose'
usage: patch [-bCcEeflNnRstuv] [-B backup-prefix] [-D symbol] [-d directory]
[-F max-fuzz] [-i patchfile] [-o out-file] [-p strip-count]
[-r rej-name] [-V t | nil | never | none] [-x number]
[-z backup-ext] [--posix] [origfile [patchfile]]
patch <patchfile

Notes
Works fine with 'GNU patch 2.7.6', that i have on my local machine, but not on the FreeBSD version at the server.

Use drupol/phposinfo

It seems that tivie/php-os-detector is a dependency and it can produces false results, see the corresponding issue: tivie/php-os-detector#3

Based on this, I've created my own package: drupol/phposinfo that fixes the issue.

This issue is to propose the replacement of tivie/php-os-detector with drupol/phposinfo.

"patches applied" field removes after composer update --lock

Hi,

After composer update we have in composer.lock file changes with adding "patches applied" field that shows status of applied patches.
However if we'll remove vendor directory and run composer update --lock (just update hash) - these changes will be reverted in composer.lock file, but patches will be applied.

How to patch a package from another?

I have a root composer.json which requires two packages, and package B depends on (requires) package A. In order to be able to use package B properly, package A needs to be patched.

How to instruct vaimo/composer-patches from package B's composer.json to patch package A? It would be the best if the root composer.json wouldn't contain these instructions.

patches-search not working as documented?

patches-search seems to not be functional

Pre-requisites

  1. Using laravel framework (with laravel-enso on top)

To Reproduce
Steps to reproduce the behavior:

  1. create patches_composer folder
  2. create a laravel-compile-unique.patch inside
    contents:
pre-support unique indexes on nullable fields

@package laravel/framework

--- src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php.org
+++ src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
@@ -105,10 +105,11 @@
      */
     public function compileUnique(Blueprint $blueprint, Fluent $command)
     {
-        return sprintf('create unique index %s on %s (%s)',
+        return sprintf('create unique index %s on %s (%s) where %s is not null',
             $this->wrap($command->index),
             $this->wrapTable($blueprint),
-            $this->columnize($command->columns)
+            $this->columnize($command->columns),
+            implode(' is not null and ', $this->wrapArray($command->columns))
         );
     }
  1. ensure "patches-search": "patches_composer" is part of the extra key in composer.json

Expected

laravel/framework
  ~ my-package: patches_composer/laravel-compile-unique.patch [NEW]
    pre-support unique indexes on nullable fields

Actual
A clear and concise description of what actually happened.
No patches appearing at all

Notes
(Optional) Add any other context about the problem here.
Tested both on my local (windows 10-based) dev machine with PHP 7.1 and on the deployment CentOs server with PHP 7.2.

 composer patch:list --from-source -vvv
Reading ./composer.json
Loading config file ./composer.json
Checked CA file C:\<redacted>.tmp: valid
Executing command (C:\<redacted>): git branch --no-color --no-abbrev -v
Reading C:/Users/<redacted>/AppData/Roaming/Composer/composer.json
Loading config file C:/Users/<redacted>/AppData/Roaming/Composer/composer.json
Reading C:\Users\<redacted>/vendor/composer/installed.json
Reading C:/Users/<redacted>/AppData/Roaming/Composer/vendor/composer/installed.json
Loading plugin PackageVersions\Installer
Loading plugin Vaimo\ComposerPatches\Plugin
Running 1.8.0 (2018-12-03 10:31:16) with PHP 7.1.20 on Windows NT / 10.0

and

$ composer patch:list --from-source -vvv
Reading ./composer.json
Loading config file ./composer.json
Checked CA file /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem: valid
Executing command (/home/gitlab-runner/builds/f67e7d46/1/<redacted>): git branch --no-color --no-abbrev -v
Executing command (/home/gitlab-runner/builds/f67e7d46/1/<redacted>): git describe --exact-match --tags
Reading /home/gitlab-runner/.config/composer/composer.json
Loading config file /home/gitlab-runner/.config/composer/composer.json
Reading /home/gitlab-runner/builds/f67e7d46/1/<redacted>/vendor/composer/installed.json
Reading /home/gitlab-runner/.config/composer/vendor/composer/installed.json
Loading plugin PackageVersions\Installer
Loading plugin Vaimo\ComposerPatches\Plugin
Running 1.6.5 (2018-05-04 11:44:59) with PHP 7.2.16 on Linux / 3.10.0-957.5.1.el7.x86_64

Using

        "patches": {
            "laravel/framework": {
                "pre-support unique indexes on nullable fields": "patches_composer/laravel-compile-unique.patch"
            }
        }

does seem to work as expected.

I assume I'm doing something wrong, but I can't figure out what.

Remote patches are not able to be installed on Windows

While trying to apply the following patch, the composer patch:apply command throws Vaimo\ComposerPatches\Exceptions\PatchFailureException. When I switch the WSL (Windows Subsystem for Linux) and run the command via bash the command passes perfectly.

Pre-requisites

  1. Windows 10
  2. WSL
  3. vaimo/composer-patches with either version 4.11.1 or 4.16.1

To Reproduce
Steps to reproduce the behavior:

  1. Add an externally hosted patch to the composer.json
    "extra": {
        "patches": {
            "drupal/webform_composite": {
                "example": "https://www.drupal.org/files/issues/2019-05-04/add-webform-composite-schema-to-make-fields-translatable-2979305-11.patch"
            }
        }
    }
  2. Run composer install or composer patch:apply in either Powershell or CMD
  3. Run composer install or composer patch:apply in WSL bash

Expected
The patch will be applied to the drupal/webform_composite package

Actual
Vaimo\ComposerPatches\Exceptions\PatchFailureException is thrown with the error message of Cannot apply patch C:\Users\TMCHAT~1\AppData\Local\Temp/composer-patches-9b6502bc15546a96fb461dbcc4363d53.patch

Notes
I believe this may be caused by the paths not being normalized for the OS the command is run on. This is my current assumption as the error message seems to be using a linux directory separator between the Temp directory and the filename.

Unclear how bundle patches work for Magento 2

I'm trying to apply this patch: https://github.com/magento/magento2/commit/79a13b483db3bf066cda6bcb69737cec02f78d47.patch

This commit has changes in two files:

  • app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php
  • lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php

I'm trying to patch that with this config:

"patches": {
            "*": {
                "Patch title": {
                    "source": "https://github.com/magento/magento2/commit/79a13b483db3bf066cda6bcb69737cec02f78d47.patch",
                    "level": 5,
                    "targets": [
                        "magento/module-catalog",
                        "magento/framework"
                    ]
                }
            }
        }

This will generate the following response:

Hmm...  Looks like a unified diff to me...
      can't find file to patch at input line 15
      Perhaps you used the wrong -p or --strip option?
      The text leading up to this was:
      --------------------------
      |From 79a13b483db3bf066cda6bcb69737cec02f78d47 Mon Sep 17 00:00:00 2001
      |From: roman <[email protected]>
      |Date: Mon, 24 Dec 2018 18:58:43 +0200
      |Subject: [PATCH] MAGETWO-97081: Fixed incorrect behaviour of sync actions
      |
      |---
      | .../ProductFrontendAction/Synchronizer.php    | 62 ++++++++++---------
      | .../Framework/DB/Adapter/Pdo/Mysql.php        |  4 +-
      | 2 files changed, 37 insertions(+), 29 deletions(-)
      |
      |diff --git a/app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php b/app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php
      |index 7a1926cf642e..3c8d49cbdd74 100644
      |--- a/app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php
      |+++ b/app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php
      --------------------------
      No file to patch.  Skipping patch.
      Hunk #1 ignored at 138.
      Hunk #2 ignored at 159.
      2 out of 2 hunks ignored
      Hmm...  The next patch looks like a unified diff to me...
      can't find file to patch at input line 95
      Perhaps you used the wrong -p or --strip option?
      The text leading up to this was:
      --------------------------
      |diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
      |index 3d06e27542f0..acdc2b0f01f7 100644
      |--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
      |+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
      --------------------------
      No file to patch.  Skipping patch.
      Hunk #1 ignored at 2904.
      1 out of 1 hunk ignored
      done

Is it possible to apply such patches with this module?

Defining conflicts in patch entries

Is your feature request related to a problem? Please describe.
Maintaining a central patch list for Magento is challenging due to some conflicts with other packages, for example Magento's ECE Tools. For example, the critical PRODSECBUG-2198 patch is included in ECE Tools starting from a specific version, but would need to be applied on all projects using an older version of ECE tools or that are not on Magento Cloud (i.e. ECE tools is not installed at all). While it is possible to add the patch to the exclusion list at the project level, this has to be done manually for every project that has been updated to a version of ECE tools that includes the patch, even though this condition is known in advance.

Describe the solution you'd like
Just like it's possible to define a conflict node in a Composer file to prevent a package to be installed if another package is installed and fitting the version definition, it would be useful to have a similar node at the patch entry level to skip patches if certain conditions are met.

Describe alternatives you've considered
Alternatively, a special value in the depends node that matches if the module is not present. E.g.

"depends": {
    "magento/ece-tools": "!installed || <=1.12"
}

Windows path quoting broken

under windows its necessary to double quote paths which have spaces. installing the plugin in the project and running composer patch:apply --from-source -vvv leads to:

      CHECK (type=PATCH) failed with p=0
      (using cached result for: < where = 1)
            C:\Program Files\Git\mingw64\bin\git.exe
      C:\Program Files\Git\cmd\git.exe
Executing command (....\src\vendor/easycorp/easyadmin-bundle): cd .. && C:\Program Files\Git\mingw64\bin\git.exe rev-parse --is-inside-work-tree
      *** The expected result to execution is a failure***
      Executing command (....\src\vendor/easycorp/easyadmin-bundle): C:\Program Files\Git\mingw64\bin\git.exe apply -p"0" --check ".....\src\patches/easyadmin.doctrine-embeddables.patch"
      'C:\Program' is not recognized as an internal or external command,

Failed to apply the patch. Halting execution!

composer patch:apply --from-source -vvv

I tried 3 patches via git cli, git extensions, phpstorm ide. And in all cases i get errors:

Processing patches configuration
  - Installing laravel-notification-channels/smsc-ru (v3.0.2): Reading /home/app/.composer/cache/files/laravel-notification-channels/smsc-ru/442d9f84df57a2ecdb849db87253f85b4d432980.zip from cache
Loading from cache
 Extracting archiveExecuting command (CWD): unzip -qq  '/var/www/app/vendor/laravel-notification-channels/smsc-ru/d034a8b24041e341be34720bc33c1ad7' -d '/var/www/app/vendor/composer/6685f1b5'
  - Applying patches for laravel-notification-channels/smsc-ru (1)
    ~ laravel/laravel: patches/laravel-notification-channels/smsc-ru/forward_call_and_voice_params.patch [NEW]
      Executing command (/var/www/app/vendor/laravel-notification-channels/smsc-ru): which patch
      which: no patch in (/var/www/app/vendor/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
      BIN (type=PATCH) failed with p=
      (using cached result for: < which = 1)
      Executing command (/var/www/app/vendor/laravel-notification-channels/smsc-ru): which git
      /usr/bin/git
      (using cached result for: < which = 1)
      (using cached result for: which patch = )
      BIN (type=PATCH) failed with p=0
      (using cached result for: < which = 1)
      (using cached result for: which git = 1)
      *** The expected result to execution is a failure***
      Executing command (/var/www/app/vendor/laravel-notification-channels/smsc-ru): cd .. && /usr/bin/git rev-parse --is-inside-work-tree
      true
      PING (type=GIT) failed with p=0
      (using cached result for: < which = 1)
      (using cached result for: which patch = )
      BIN (type=PATCH) failed with p=1
      (using cached result for: < which = 1)
      (using cached result for: which git = 1)
      *** The expected result to execution is a failure***
      (using cached result for: cd .. && /usr/bin/git rev-parse --is-inside-work-tree = 1)
      PING (type=GIT) failed with p=1
      (using cached result for: < which = 1)
      (using cached result for: which patch = )
      BIN (type=PATCH) failed with p=2
      (using cached result for: < which = 1)
      (using cached result for: which git = 1)
      *** The expected result to execution is a failure***
      (using cached result for: cd .. && /usr/bin/git rev-parse --is-inside-work-tree = 1)
      PING (type=GIT) failed with p=2
      Cannot apply patch /var/www/app/patches/laravel-notification-channels/smsc-ru/forward_call_and_voice_params.patch

patch via git extensions

@package laravel-notification-channels/smsc-ru

---
 src/SmscRuChannel.php |  8 +++++++
 src/SmscRuMessage.php | 50 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/src/SmscRuChannel.php b/src/SmscRuChannel.php
index dcfd14f..a7bd3b7 100644
--- a/src/SmscRuChannel.php
+++ b/src/SmscRuChannel.php
@@ -75,6 +75,14 @@ class SmscRuChannel
             $params['time'] = '0'.$message->sendAt->getTimestamp();
         }

+        if ($message->call) {
+            $params['call'] = $message->call ? 1 : 0;
+        }
+
+        if ($message->voice) {
+            $params['voice'] = $message->voice;
+        }
+
         return $this->smsc->send($params);
     }
 }
diff --git a/src/SmscRuMessage.php b/src/SmscRuMessage.php
index a0c6153..8c98e9d 100644
--- a/src/SmscRuMessage.php
+++ b/src/SmscRuMessage.php
@@ -25,6 +25,28 @@ class SmscRuMessage
      */
     public $sendAt;

+    /**
+     * Sign of a voice message.
+     * When forming a voice message, you can transfer both text and attach files.
+     * Files added to the message must be transferred using the POST method in the body of the http request.
+     * 0 (default) is a regular message.
+     * 1 - voice message.
+     *
+     * @var bool
+     */
+    public $call;
+
+    /**
+     * Voice used to read text (for voice messages only).
+     * m (default) - male voice.
+     * m2 is a male alternative voice.
+     * w is a female voice.
+     * w2 is a female alternative voice.
+     *
+     * @var string
+     */
+    public $voice;
+
     /**
      * Create a new message instance.
      *
@@ -86,4 +108,32 @@ class SmscRuMessage

         return $this;
     }
+
+    /**
+     * Set the sign of a voice message.
+     *
+     * @param  bool|null  $call
+     *
+     * @return $this
+     */
+    public function call($call = null)
+    {
+        $this->call = filter_var($call, FILTER_VALIDATE_BOOLEAN);
+
+        return $this;
+    }
+
+    /**
+     * Set the voice used to read text (for voice messages only).
+     *
+     * @param  string  $call
+     *
+     * @return $this
+     */
+    public function voice($voice = null)
+    {
+        $this->voice = $voice;
+
+        return $this;
+    }
 }
--
2.21.0.windows.1

patch via git cli

@package laravel-notification-channels/smsc-ru

diff --git a/src/SmscRuChannel.php b/src/SmscRuChannel.php
index dcfd14f..a7bd3b7 100644
--- a/src/SmscRuChannel.php
+++ b/src/SmscRuChannel.php
@@ -75,6 +75,14 @@ class SmscRuChannel
             $params['time'] = '0'.$message->sendAt->getTimestamp();
         }

+        if ($message->call) {
+            $params['call'] = $message->call ? 1 : 0;
+        }
+
+        if ($message->voice) {
+            $params['voice'] = $message->voice;
+        }
+
         return $this->smsc->send($params);
     }
 }
diff --git a/src/SmscRuMessage.php b/src/SmscRuMessage.php
index a0c6153..8c98e9d 100644
--- a/src/SmscRuMessage.php
+++ b/src/SmscRuMessage.php
@@ -25,6 +25,28 @@ class SmscRuMessage
      */
     public $sendAt;

+    /**
+     * Sign of a voice message.
+     * When forming a voice message, you can transfer both text and attach files.
+     * Files added to the message must be transferred using the POST method in the body of the http request.
+     * 0 (default) is a regular message.
+     * 1 - voice message.
+     *
+     * @var bool
+     */
+    public $call;
+
+    /**
+     * Voice used to read text (for voice messages only).
+     * m (default) - male voice.
+     * m2 is a male alternative voice.
+     * w is a female voice.
+     * w2 is a female alternative voice.
+     *
+     * @var string
+     */
+    public $voice;
+
     /**
      * Create a new message instance.
      *
@@ -86,4 +108,32 @@ class SmscRuMessage

         return $this;
     }
+
+    /**
+     * Set the sign of a voice message.
+     *
+     * @param  bool|null  $call
+     *
+     * @return $this
+     */
+    public function call($call = null)
+    {
+        $this->call = filter_var($call, FILTER_VALIDATE_BOOLEAN);
+
+        return $this;
+    }
+
+    /**
+     * Set the voice used to read text (for voice messages only).
+     *
+     * @param  string  $call
+     *
+     * @return $this
+     */
+    public function voice($voice = null)
+    {
+        $this->voice = $voice;
+
+        return $this;
+    }
 }

patch via phpstorm

@package laravel-notification-channels/smsc-ru

Index: vendor/laravel-notification-channels/smsc-ru/src/SmscRuChannel.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- vendor/laravel-notification-channels/smsc-ru/src/SmscRuChannel.php	(date 1574259257208)
+++ vendor/laravel-notification-channels/smsc-ru/src/SmscRuChannel.php	(date 1574259257208)
@@ -75,6 +75,14 @@
             $params['time'] = '0'.$message->sendAt->getTimestamp();
         }

+        if ($message->call) {
+            $params['call'] = $message->call ? 1 : 0;
+        }
+
+        if ($message->voice) {
+            $params['voice'] = $message->voice;
+        }
+
         return $this->smsc->send($params);
     }
 }
Index: vendor/laravel-notification-channels/smsc-ru/src/SmscRuMessage.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- vendor/laravel-notification-channels/smsc-ru/src/SmscRuMessage.php	(date 1574259356150)
+++ vendor/laravel-notification-channels/smsc-ru/src/SmscRuMessage.php	(date 1574259356150)
@@ -25,6 +25,28 @@
      */
     public $sendAt;

+    /**
+     * Sign of a voice message.
+     * When forming a voice message, you can transfer both text and attach files.
+     * Files added to the message must be transferred using the POST method in the body of the http request.
+     * 0 (default) is a regular message.
+     * 1 - voice message.
+     *
+     * @var boolean
+     */
+    public $call;
+
+    /**
+     * Voice used to read text (for voice messages only).
+     * m (default) - male voice.
+     * m2 is a male alternative voice.
+     * w is a female voice.
+     * w2 is a female alternative voice.
+     *
+     * @var string
+     */
+    public $voice;
+
     /**
      * Create a new message instance.
      *
@@ -84,6 +106,34 @@
     {
         $this->sendAt = $sendAt;

+        return $this;
+    }
+
+    /**
+     * Set the sign of a voice message.
+     *
+     * @param  boolean|null  $call
+     *
+     * @return $this
+     */
+    public function call($call = null)
+    {
+        $this->call = $call;
+
+        return $this;
+    }
+
+    /**
+     * Set the voice used to read text (for voice messages only).
+     *
+     * @param  string  $call
+     *
+     * @return $this
+     */
+    public function voice($voice = null)
+    {
+        $this->voice = $voice;
+
         return $this;
     }
 }

Patch error on large composer update

Sometimes on large scale composer updates I get following error when the patches are supposed to be applied:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function Vaimo\ComposerPatches\Package\InfoResolver::__construct(), 1 passed in /builds/.../vendor/vaimo/composer-patches/src/Factories/PatchesLoaderFactory.php on line 48 and exactly 2 expected in /builds/.../vendor/vaimo/composer-patches/src/Package/InfoResolver.php:36
Stack trace:
#0 /builds/.../vendor/vaimo/composer-patches/src/Factories/PatchesLoaderFactory.php(48): Vaimo\ComposerPatches\Package\InfoResolver->__construct(Object(Composer\Installer\InstallationManager))
#1 /builds/.../vendor/vaimo/composer-patches/src/Bootstrap.php(122): Vaimo\ComposerPatches\Factories\PatchesLoaderFactory->create(Object(Vaimo\ComposerPatches\Patch\DefinitionList\Loader\ComponentPool), Object(Vaimo\ComposerPatches\Config), true)
#2 /builds/.../vendor/vaimo/composer-patches/src/Bootstrap.php(102): Vaimo\ComposerPatches\Boo in /builds/.../vendor/vaimo/composer-patches/src/Package/InfoResolver.php on line 36
PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function Vaimo\ComposerPatches\Package\InfoResolver::__construct(), 1 passed in /builds/.../vendor/vaimo/composer-patches/src/Factories/PatchesLoaderFactory.php on line 48 and exactly 2 expected in /builds/.../vendor/vaimo/composer-patches/src/Package/InfoResolver.php:36
Stack trace:
#0 /builds/.../vendor/vaimo/composer-patches/src/Factories/PatchesLoaderFactory.php(48): Vaimo\ComposerPatches\Package\InfoResolver->__construct(Object(Composer\Installer\InstallationManager))
#1 /builds/.../vendor/vaimo/composer-patches/src/Bootstrap.php(122): Vaimo\ComposerPatches\Factories\PatchesLoaderFactory->create(Object(Vaimo\ComposerPatches\Patch\DefinitionList\Loader\ComponentPool), Object(Vaimo\ComposerPatches\Config), true)
#2 /builds/.../vendor/vaimo/composer-patches/src/Bootstrap.php(102): Vaimo\ComposerPatches\Boo in /builds/.../vendor/vaimo/composer-patches/src/Package/InfoResolver.php on line 36`

Did anyone see this before? I am not quite sure how to reproduce it.

Lost compatibility with composer 1.7.0

After upgrading composer to 1.7.0, I get this error message:

root@82d8004a6dc2:/var/www/html# composer install -vvv
Reading ./composer.json
Loading config file /root/.composer/config.json
Loading config file /root/.composer/auth.json
Loading config file ./composer.json
Checked CA file /etc/ssl/certs/ca-certificates.crt: valid
Executing command (/var/www/html): git branch --no-color --no-abbrev -v
Executing command (/var/www/html): git describe --exact-match --tags
Executing command (/var/www/html): git log --pretty="%H" -n1 HEAD
Executing command (/var/www/html): hg branch
Failed to initialize global composer: Composer could not find the config file: /root/.composer/composer.json
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
Reading /var/www/html/vendor/composer/installed.json
Loading plugin MagentoHackathon\Composer\Magento\Plugin
activate magento plugin
Loading plugin Vaimo\ComposerPatches\Plugin
PHP Fatal error:  Uncaught Error: Class 'Tivie\OS\Detector' not found in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php:19
Stack trace:
#0 /var/www/html/vendor/vaimo/composer-patches/src/Factories/ConfigFactory.php(31): Vaimo\ComposerPatches\Config\Context->__construct()
#1 /var/www/html/vendor/vaimo/composer-patches/src/Bootstrap.php(60): Vaimo\ComposerPatches\Factories\ConfigFactory->__construct()
#2 /var/www/html/vendor/vaimo/composer-patches/src/Plugin.php(31): Vaimo\ComposerPatches\Bootstrap->__construct(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): Vaimo\ComposerPatches\Plugin->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#4 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(Vaimo\ComposerPatches\Plugin))
#5 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(261): Composer\Plugin\PluginManager->register in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php on line 19

Fatal error: Uncaught Error: Class 'Tivie\OS\Detector' not found in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php:19
Stack trace:
#0 /var/www/html/vendor/vaimo/composer-patches/src/Factories/ConfigFactory.php(31): Vaimo\ComposerPatches\Config\Context->__construct()
#1 /var/www/html/vendor/vaimo/composer-patches/src/Bootstrap.php(60): Vaimo\ComposerPatches\Factories\ConfigFactory->__construct()
#2 /var/www/html/vendor/vaimo/composer-patches/src/Plugin.php(31): Vaimo\ComposerPatches\Bootstrap->__construct(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): Vaimo\ComposerPatches\Plugin->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#4 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(Vaimo\ComposerPatches\Plugin))
#5 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(261): Composer\Plugin\PluginManager->register in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php on line 19

After deleting the vendor folder and trying again:

root@82d8004a6dc2:/var/www/html# composer install -vvv
Reading ./composer.json
Loading config file /root/.composer/config.json
Loading config file /root/.composer/auth.json
Loading config file ./composer.json
Checked CA file /etc/ssl/certs/ca-certificates.crt: valid
Executing command (/var/www/html): git branch --no-color --no-abbrev -v
Executing command (/var/www/html): git describe --exact-match --tags
Executing command (/var/www/html): git log --pretty="%H" -n1 HEAD
Executing command (/var/www/html): hg branch
Failed to initialize global composer: Composer could not find the config file: /root/.composer/composer.json
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
Running 1.7.0 (2018-08-03 15:39:07) with PHP 7.0.30-1+ubuntu16.04.1+deb.sury.org+1 on Linux / 4.9.93-linuxkit-aufs
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Reading ./composer.lock
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Reading ./composer.lock
Resolving dependencies through SAT
Looking at all rules.

[...]

  - Installing tivie/php-os-detector (1.1.0): Reading /root/.composer/cache/files/tivie/php-os-detector/3070e4f6c3d4c6ce53a8fd95019b01c10c30e8b6.zip from cache
Loading from cache
 Extracting archive    REASON: Required by the root package: Install command rule (install tivie/php-os-detector 1.1.0)

  - Installing vaimo/magento-composer-plugin (2.4.3): Reading /root/.composer/cache/files/vaimo/magento-composer-plugin/6f672e4a165b4e0ccf08de1913b254b0a42f1f50.zip from cache
Loading from cache
 Extracting archiveLoading plugin Vaimo\Magento\Plugin\Plugin
    REASON: Required by the root package: Install command rule (install vaimo/magento-composer-plugin 2.4.3)

  - Installing vaimo/composer-patches (3.27.0): Reading /root/.composer/cache/files/vaimo/composer-patches/de47e94f9956fa095e90bf2b3a7ae7278cd8148d.zip from cache
Loading from cache
 Extracting archiveLoading plugin Vaimo\ComposerPatches\Plugin
PHP Fatal error:  Uncaught Error: Class 'Tivie\OS\Detector' not found in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php:19
Stack trace:
#0 /var/www/html/vendor/vaimo/composer-patches/src/Factories/ConfigFactory.php(31): Vaimo\ComposerPatches\Config\Context->__construct()
#1 /var/www/html/vendor/vaimo/composer-patches/src/Bootstrap.php(60): Vaimo\ComposerPatches\Factories\ConfigFactory->__construct()
#2 /var/www/html/vendor/vaimo/composer-patches/src/Plugin.php(31): Vaimo\ComposerPatches\Bootstrap->__construct(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): Vaimo\ComposerPatches\Plugin->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#4 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(Vaimo\ComposerPatches\Plugin))
#5 phar:///usr/local/bin/composer/src/Composer/Installer/PluginInstaller.php(62): Composer\Plugin\PluginManager->regi in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php on line 19

Fatal error: Uncaught Error: Class 'Tivie\OS\Detector' not found in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php:19
Stack trace:
#0 /var/www/html/vendor/vaimo/composer-patches/src/Factories/ConfigFactory.php(31): Vaimo\ComposerPatches\Config\Context->__construct()
#1 /var/www/html/vendor/vaimo/composer-patches/src/Bootstrap.php(60): Vaimo\ComposerPatches\Factories\ConfigFactory->__construct()
#2 /var/www/html/vendor/vaimo/composer-patches/src/Plugin.php(31): Vaimo\ComposerPatches\Bootstrap->__construct(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(236): Vaimo\ComposerPatches\Plugin->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#4 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(Vaimo\ComposerPatches\Plugin))
#5 phar:///usr/local/bin/composer/src/Composer/Installer/PluginInstaller.php(62): Composer\Plugin\PluginManager->regi in /var/www/html/vendor/vaimo/composer-patches/src/Config/Context.php on line 19

Weirdly, the class is available in vendor/tivie/php-os-detector/src/Detector.php, but I believe at this point the Plugin is not able to load a dependency that was just installed.

Patch:* commands not available if plugin installed globally and composer.phar is run in project context

using a global installed composer.phar (c:\bin\composer.phar, which is in the PATH) i used composer global require hirak/prestissimo and it is also loaded for my projects. so there was no need to install it with the projects dependencies.

Plugin packages are automatically loaded as soon as they are installed and will be loaded when composer starts up if they are found in the current project's list of installed packages. Additionally all plugin packages installed in the COMPOSER_HOME directory using the composer global command are loaded before local project plugins are loaded.

https://getcomposer.org/doc/articles/plugins.md#using-plugins

the composer docs let me assume that this is the intended behavior.

i installed vaimo/composer-patches the same way with composer global require vaimo/composer-patches but running php composer.phar in my projects dir, does not list the patch:* commands. shouldn't they be there even if its installed globally?

λ composer patch:list --from-source -vvv                                                                                           
converting composer.yaml to json                                                                                                   
Reading ./composer.json                                                                                                            
Loading config file C:/Users/username/AppData/Roaming/Composer/config.json                                                         
Loading config file C:/Users/username/AppData/Roaming/Composer/auth.json                                                           
Loading config file ./composer.json                                                                                                
Checked CA file xxxxx.pem: valid                                      
Executing command (C:\home\projects\project\src): git branch --no-color --no-abbrev -v                             
Reading C:/Users/username/AppData/Roaming/Composer/composer.json                                                                   
Loading config file C:/Users/username/AppData/Roaming/Composer/config.json                                                         
Loading config file C:/Users/username/AppData/Roaming/Composer/auth.json                                                           
Loading config file C:/Users/username/AppData/Roaming/Composer/composer.json                                                       
Reading C:\home\projects\project\src/vendor/composer/installed.json                                                
Reading C:/Users/username/AppData/Roaming/Composer/vendor/composer/installed.json                                                  
Loading plugin PackageVersions\Installer                                                                                           
Loading plugin Symfony\Flex\Flex                                                                                                   
Loading plugin Bamarni\Composer\Bin\Plugin                                                                                         
Loading plugin Studio\Composer\StudioPlugin                                                                                        
Loading plugin Fxp\Composer\AssetPlugin\FxpAssetPlugin                                                                             
Loading plugin Hirak\Prestissimo\Plugin                                                                                            
Loading plugin Pyrech\ComposerChangelogs\ChangelogsPlugin                                                                          
Loading plugin Rubenrua\SymfonyCleanTagsComposerPlugin\Plugin                                                                      
symfony/flex is active: Skip the activation                                                                                        
Loading plugin Vaimo\ComposerPatches\Plugin                                                                                        
Running 1.8.4 (2019-02-11 10:52:10) with PHP 7.3.9 on Windows NT / 6.1                                                             
                                                                                                                                   
                                                                                                                                   
  [Symfony\Component\Console\Exception\CommandNotFoundException]                                                                   
  There are no commands defined in the "patch" namespace.                                                                          

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.