Skip to content

Commit

Permalink
Merge pull request #465 from cweagans/docs-4
Browse files Browse the repository at this point in the history
Docs 4
  • Loading branch information
cweagans authored Feb 12, 2023
2 parents 9f6c8e1 + 5d8e193 commit 5a4dacf
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 24 deletions.
5 changes: 2 additions & 3 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ body:
required: true
- label: I have searched existing issues _and_ discussions for my problem.
required: true
# TODO: Write troubleshooting guide.
# - label: My problem is _not_ addressed in the troubleshooting guide
# required: true
- label: My problem is _not_ addressed in the [troubleshooting guide](https://docs.cweagans.net/composer-patches/troubleshooting/guide).
required: true
- type: textarea
attributes:
label: "What were you trying to do (and why)?"
Expand Down
4 changes: 2 additions & 2 deletions docs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ quicklinks:
icon: installation
description: "Get up-and-running with Composer Patches in your project"
href: /composer-patches/getting-started/installation
- title: "Workflow"
- title: "Recommended workflows"
icon: plugins
description: "Learn how to use Composer Patches with a group of engineers."
href: /composer-patches/usage/workflow
href: /composer-patches/usage/recommended-workflows
- title: "Troubleshooting"
icon: architecture
description: "Figure out how to solve any problems that you run into."
Expand Down
4 changes: 0 additions & 4 deletions docs/troubleshooting/fixing-your-patch.md

This file was deleted.

27 changes: 27 additions & 0 deletions docs/troubleshooting/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,30 @@
title: Guide
weight: 10
---

{{< lead text="Common problems that people have run into and how to fix them." >}}

## System readiness

If you've encountered a problem, a good first step is to run [`composer patches-doctor`]({{< relref "../usage/commands.md#composer-patches-doctor" >}}). This will run a few checks against your system and look for common configuration errors.


## Upgrade system software

See the [system requirements]({{< relref "../getting-started/system-requirements.md" >}}) page for the minimum supported versions of PHP, Composer, and other software. Upgrade your software using the method appropriate for your operating system.


## Install patching software

Composer Patches requires at least _some_ mechanism for applying patches. If you don't have any installed, you'll see a fair number of errors. You should install some combination of GNU `patch`, BSD `patch`, `git`, or other applicable software. macOS users commonly need to `brew install gpatch` to get a modern version of `patch` on their system.


## Set `preferred-install` to `source`

The Git patcher included with this plugin is the most reliable method of applying patches. However, the Git patcher won't even _attempt_ to apply a patch if the target directory isn't cloned from Git. To avoid this situation, you should either set `"preferred-install": "source"` or set specific packages to be installed from source in your Composer configuration. Patches may still be successfully applied without this setting, but if you're working on a team, you'll have much more consistent results with the Git patcher.


## Download patches securely

If you've been referred here, you're trying to download patches over HTTP without explicitly telling Composer that you want to do that. See the [`secure-http`]({{< relref "../usage/configuration.md#secure-http" >}}) documentation for more information.

37 changes: 37 additions & 0 deletions docs/troubleshooting/non-patchable-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,40 @@
title: Non-patchable targets
weight: 20
---

{{< lead text="There are some things that this plugin cannot patch." >}}

## Changes to `composer.json`

Attempting to use a patch to change `composer.json` in a dependency will _never_ work like you want it to. By the time you're running `composer install`, the metadata from your dependencies' composer.json has already been aggregated by packagist (or whatever metadata repo you're using). Therefore, changes to `composer.json` in a dependency will have _no effect_ on installed packages.

This means that you cannot e.g. patch a dependency to be compatible with an earlier version of PHP or change the framework version that a plugin depends on.

If you need to modify a dependency's `composer.json` or its underlying dependencies, you must do one of the following:

- Work to get the underlying issue resolved in the upstream package.
- Fork the package and [specify your fork as the package repository](https://getcomposer.org/doc/05-repositories.md#vcs) in your root `composer.json`
- Specify compatible package version requirements in your root `composer.json`

@anotherjames over at @computerminds wrote an article about how to work around
that particular problem for a Drupal 8 -> Drupal 9 upgrade:

[James Williams](https://github.com/anotherjames) wrote an article about how to work around this problem for a Drupal 8 -> Drupal 9 upgrade: [Apply Drupal 9 compatibility patches with Composer](https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer) ([archive](https://web.archive.org/web/20210124171010/https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer)). Although it is specific to Drupal, you may be able to use the information to do something more specific to your project/ecosystem.

## Specific dependencies

Some dependencies cannot be patched by this plugin.

### `composer/composer` (installed globally)

Because Composer is typically installed and running on a system long before this plugin is available in a particular project, it is not possible for this plugin to modify Composer itself.

If you have installed Composer locally in your project (by requiring it in the `composer.json` for your project), you _can_ patch the project-level Composer. I'm not entirely sure why you'd want to do this, but it would technically work.

### `cweagans/composer-patches`

Composer Patches applies patches to dependencies as they are installed. If Composer Patches isn't installed, it cannot apply patches to itself as it is installed by Composer. There is no supported workaround for this limitation, as most behavior can be changed via [configuration]({{< relref "../usage/configuration.md" >}}) or through the [API]({{< relref "../api/overview.md" >}}).

### `cweagans/composer-configurable-plugin`

Similarly, because Composer Configurable Plugin is a dependency of Composer Patches (and is therefore installed _before_ Composer Patches), Composer Configurable Plugin cannot be patched. There is no supported workaround for this limitation. If you run into problems with this dependency, open an issue upstream and it will be addressed promptly.
19 changes: 19 additions & 0 deletions docs/usage/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,22 @@
title: Commands
weight: 40
---

## `composer patches-relock`
**Alias**: `composer prl`

`patches-relock` causes the plugin to re-discover all available patches and then write them to the `patches.lock` file for your project. This command should be used when changing the list of patches in your project. See the [recommended workflows]({{< relref "recommended-workflows.md" >}}) page for details.

---

## `composer patches-repatch`
**Alias**: `composer prp`

`patches-repatch` causes all patched dependencies to be deleted and re-installed, which causes patches to be re-applied to those dependencies. This command should be used when changing the list of patches in your project. See the [recommended workflows]({{< relref "recommended-workflows.md" >}}) page for details.

---

## `composer patches-doctor`
**Alias**: `composer pd`

`patches-doctor` runs a few checks against your system in an attempt to find common issues that people run into when using Composer Patches. A report will be emitted along with a handful of suggestions that may help you. The output of this command is required when submitting a bug report.
47 changes: 47 additions & 0 deletions docs/usage/recommended-workflows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Recommended Workflows
weight: 30
---

{{< lead text="Common workflows for working with Composer Patches on a team." >}}

## Initial setup

The plugin can safely be [installed]({{< relref "../getting-started/installation.md" >}}) as part of initial project setup, even if you don't have any patches to apply right away. A `patches.lock` will still be written, but it will be empty.

## Add a patch to your project

1. [Define a patch]({{< relref "defining-patches.md" >}}) in your `composer.json` or your external patches file (either will work by default, but choose the appropriate place based on how your project is configured).
2. Run [`composer patches-relock`]({{< relref "commands.md#composer-patches-relock" >}}) to regenerate `patches.lock` with your new patch.
3. Run [`composer patches-repatch`]({{< relref "commands.md#composer-patches-repatch" >}}) to delete patched dependencies and reinstall them with any defined patches {{< warning title="Running `composer patches-repatch` will delete data" >}}
Ensure that you don't have any unsaved changes in any patched dependencies in your project.
{{< /warning >}}
4. If your patch definition was added to `composer.json`, run `composer update --lock` to update the content hash in `composer.lock`.
5. Commit any related changes to your external patches file (if configured), `composer.json`, `composer.lock`, and `patches.lock`.

## Apply patches added to the project by someone else

If you have an existing copy of the project and you're updating it to include someone else's changes:

1. Pull changes from your project's version control system.
2. Run [`composer patches-repatch`]({{< relref "commands.md#composer-patches-repatch" >}}) {{< warning title="Running `composer patches-repatch` will delete data" >}}
Ensure that you don't have any unsaved changes in any patched dependencies in your project.
{{< /warning >}}

If you're installing the project from scratch:

1. Clone the project
2. Run `composer install`

## Remove a patch

1. Delete the patch definition from your `composer.json` or external patches file.
2. Run [`composer patches-relock`]({{< relref "commands.md#composer-patches-relock" >}}) to regenerate `patches.lock` with your new patch.
3. Manually delete the dependency that you removed a patch from (the location of the dependency will vary by project, but a good starting point is to look in the `vendor/` directory).
4. Run [`composer patches-repatch`]({{< relref "commands.md#composer-patches-repatch" >}}) to delete patched dependencies and reinstall them with any defined patches {{< warning title="Running `composer patches-repatch` will delete data" >}}
Ensure that you don't have any unsaved changes in any patched dependencies in your project.
{{< /warning >}}
5. If your patch definition was removed from `composer.json`, run `composer update --lock` to update the content hash in `composer.lock`.
6. Commit any related changes to your external patches file (if configured), `composer.json`, `composer.lock`, and `patches.lock`.


4 changes: 0 additions & 4 deletions docs/usage/workflow.md

This file was deleted.

29 changes: 21 additions & 8 deletions src/Command/DoctorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int

if (!str_starts_with($this->getApplication()->getVersion(), "2")) {
$system_issues = true;
$suggestions[] = "Upgrade Composer to 2.x (ideally to the latest release)";
}

$io->write(str_pad("PHP version: ", 72) . "<info>" . str_pad(PHP_VERSION, 8, " ", STR_PAD_LEFT) . "</info>");
if (PHP_VERSION_ID < 80000) {
$system_issues = true;
$suggestions[] = "Upgrade PHP to a more modern version";
}

if ($system_issues) {
$suggestions[] = "See https://docs.cweagans.net/composer-patches/system-requirements for more information";
$suggestions[] = [
"message" => "Upgrade Composer and/or PHP to a more modern/supported version",
"link" => "https://docs.cweagans.net/composer-patches/troubleshooting/guide#upgrade-system-software"
];
}

$io->write("");
Expand Down Expand Up @@ -98,7 +99,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
);

if (!$has_usable_patcher) {
$suggestions[] = "Install tools for applying patches";
$suggestions[] = [
"message" => "Install software dependencies for applying patches",
"link" => "https://docs.cweagans.net/composer-patches/troubleshooting/guide#install-patching-software"
];
}


Expand Down Expand Up @@ -157,8 +161,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

if ($preferred_install_issues) {
$suggestions[] = "Setting 'preferred-install' to 'source' either globally or for each patched dependency " .
"is highly recommended";
$suggestions[] = [
"message" => "Setting 'preferred-install' to 'source' either globally or for each patched dependency " .
"is highly recommended for consistent results",
"link" =>
"https://docs.cweagans.net/composer-patches/troubleshooting/guide#set-preferred-install-to-source"
];
}

$has_http_urls = false;
Expand All @@ -181,7 +189,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
);

if ($sh) {
$suggestions[] = "Patches must either be downloaded securely or 'secure-http' must be disabled";
$suggestions[] = [
"message" => "Patches must either be downloaded securely or 'secure-http' must be disabled",
"link" =>
"https://docs.cweagans.net/composer-patches/troubleshooting/guide#download-patches-securely"
];
}
}

Expand All @@ -190,7 +202,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$io->write("<info>Suggestions</info>");
$io->write("================================================================================");
foreach ($suggestions as $suggestion) {
$io->write(" - $suggestion");
$io->write(" - " . $suggestion['message']);
$io->write(" More information: " . $suggestion['link']);
}
}

Expand Down
7 changes: 4 additions & 3 deletions tests/unit/CommandProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ public function testGetCommands()
$commandProvider = new CommandProvider();

$commands = $commandProvider->getCommands();
$this->assertCount(2, $commands);
$this->assertInstanceOf(BaseCommand::class, $commands[0]);
$this->assertInstanceOf(BaseCommand::class, $commands[1]);
$this->assertNotEmpty($commands);
foreach ($commands as $command) {
$this->assertInstanceOf(BaseCommand::class, $command);
}
}
}

0 comments on commit 5a4dacf

Please sign in to comment.