slideshare quotation-marks triangle book file-text2 file-picture file-music file-play file-video location calendar search wrench cogs stats-dots hammer2 menu download2 question cross enter google-plus facebook instagram twitter medium linkedin drupal GitHub quotes-close
PHP code

In the world of PHP development, Composer has emerged as the de facto standard for managing dependencies. Its ability to resolve and install libraries from Packagist and other repositories has simplified the workflow for countless developers. However, there are times when the need arises to modify a dependency, whether to fix a bug, add a feature, or customize behavior.

This is where tools like cweagans/composer-patches and the feature patches-ignore come into play, offering powerful solutions for patching dependencies without forking or modifying the original source code.

Understanding the Need for Patching Dependencies

While Composer simplifies dependency management, it doesn't provide built-in support for patching dependencies. This limitation becomes apparent when you encounter situations where you need to apply custom modifications to a dependency. Traditionally, developers might resort to forking the dependency's repository, applying the necessary changes, and then referencing the forked version in their composer.json. However, this approach can quickly become unwieldy, especially when dealing with multiple dependencies or frequent updates.

Patching dependencies offers a cleaner and more maintainable solution. Instead of modifying the original source code, patches are applied during the Composer installation process, allowing you to keep track of your changes separately from the upstream repository. This approach promotes better code organization and makes it easier to manage updates and upstream changes.

Introducing composer-patches

composer-patches is a Composer plugin that enables the application of patches to dependencies listed in your composer.json file. It leverages the popular patch utility to apply changes, offering a simple and efficient mechanism for patch management.

Using composer-patches involves two main steps:

  1. Defining Patches in composer.json: Within your composer.json file, you can specify patches to apply to specific dependencies using the "extra" section. Each patch is defined by the dependency name, the URL or file path of the patch file, and optional additional configuration. You would add something like this to your composer.json file to patch the example/bar-package with a patch file within the repository.
{
  "require": {
    "example/bar-package": "^2.0"
  },
  "extra": {
    "patches": {
      "example/bar-package": {
        "Add new feature to AnotherClass": "patches/add-feature.patch"
      }
    }
  }
}
  1. Running Composer Install or Update: Once the patches are defined, running composer install or composer update will trigger the application of patches during the dependency installation process.

By integrating composer-patches into your Composer workflow, you gain greater flexibility and control over dependency modifications, streamlining the management of custom changes across projects.

The composer-patches tool is also able to pull in remote patches, which means you can automatically patch any package with a diff file from a pull request or similar.

Empowering Patch Management with patches-ignore

While composer-patches offers a robust solution for applying patches, there are scenarios where you may want more granular control over patches. This is where patches-ignore comes into play.

patches-ignore is a feature of composer-patches that allows you to specify patches to be ignored for specific packages or package versions. This capability is particularly useful in situations where patches conflict with upstream changes or when you need to exclude certain modifications under specific conditions.

To utilize patches-ignore, you simply define the patches to ignore in your composer.json file, specifying the package name, version constraint, and patch file to exclude. This feature enhances the flexibility of patch management, enabling you to fine-tune patch application according to your project's requirements.

Example

Excluding patches for specific versions: suppose we want to exclude a specific patch from being applied to certain versions of a dependency. We define the patch in composer.json as usual, but we also specify version constraints in patches-ignore:

{
  "require": {
    "example/bar-package": "^2.0"
  },
  "extra": {
    "patches": {
      "example/bar-package": {
        "Add new feature to AnotherClass": "patches/add-feature.patch"
      }
    },
    "patches-ignore": {
      "example/bar-package": {
        "Add new feature to AnotherClass": "^2.1"
      }
    }
  }
}

This ensures that the patch is only applied to versions below 2.1, providing flexibility and maintaining compatibility within our project.

Benefits

  • Simplified patch management: Streamline the process of applying custom modifications to dependencies.
  • Cleaner codebases: Keep project codebases organized and maintainable by separating custom changes from upstream code.
  • Enhanced collaboration: Facilitate smoother collaboration among team members by standardizing patch management practices.
  • Improved workflow efficiency: Save time and effort by automating the patch application process and avoiding manual intervention.
  • Greater flexibility: Customize dependencies to suit project requirements without the need for extensive forking or modification of upstream repositories.

Conclusion

composer-patches and patches-ignore represent invaluable tools for PHP developers seeking to manage dependencies effectively while accommodating custom modifications. By leveraging these tools, you can streamline the process of patch management, maintain cleaner codebases, and adapt dependencies to suit your project's needs without the overhead of forking or modifying upstream repositories.

Whether you're fixing bugs, adding features, or customizing behaviour, the combination of Composer patches and patch ignoring capabilities empowers you to take control of your dependency management workflow, fostering greater efficiency and maintainability in your PHP projects.

Useful links