Skip to content

Commit 4e28eba

Browse files
committed
feat: uninstall recipe when removing a package
1 parent 1cb33b8 commit 4e28eba

30 files changed

+714
-313
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
test:
2-
@vendor/bin/grumphp run
2+
@vendor/bin/grumphp run --no-interaction
33

44
fix:
55
@vendor/bin/ecs check --fix

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ It can be used alongside with Flex, or in any other PHP project, as long as Comp
4040
* Supports PHP arrays, JSON, YAML, text files
4141
* Output post install instructions
4242
* Process only required packages in the root project
43+
* Uninstall recipe when a package is removed
44+
* CLI commands to install or uninstall recipes
4345

4446
## Installation
4547

@@ -354,6 +356,13 @@ It won't overwrite your configuration if it already exists. To overwrite everyth
354356
composer cook --overwrite
355357
```
356358

359+
Additionally, you can uninstall a recipe with this command:
360+
361+
```bash
362+
composer cook:uninstall <package> [--all]
363+
```
364+
Use either `<package>` for individual package uninstallation or `--all` for all packages.
365+
357366
## License
358367

359368
[MIT](LICENSE)

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"kubawerlos/php-cs-fixer-custom-fixers": "^3.11",
2424
"mockery/mockery": "^1.5",
2525
"nikic/php-parser": "^4.15",
26-
"php-mock/php-mock-phpunit": "^2.6",
2726
"php-parallel-lint/php-parallel-lint": "^1.3",
2827
"phpro/grumphp": "^1.13",
2928
"phpunit/phpunit": "^9.5.22",

composer.lock

Lines changed: 1 addition & 200 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ecs.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
$ecsConfig->skip([
3232
__DIR__ . '/ecs.php',
33+
__DIR__ . '/tests/Dummy/',
3334
]);
3435

3536
$ecsConfig->sets([

src/Command/CookUninstallCommand.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Williarin\Cook\Command;
6+
7+
use Composer\Command\BaseCommand;
8+
use Symfony\Component\Console\Command\Command;
9+
use Symfony\Component\Console\Input\InputArgument;
10+
use Symfony\Component\Console\Input\InputInterface;
11+
use Symfony\Component\Console\Input\InputOption;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
use Williarin\Cook\Oven;
14+
use Williarin\Cook\ServiceContainer;
15+
16+
final class CookUninstallCommand extends BaseCommand
17+
{
18+
protected function configure(): void
19+
{
20+
$this
21+
->setName('cook:uninstall')
22+
->addArgument('package', InputArgument::OPTIONAL, 'Name of the package to uninstall recipe from')
23+
->addOption('all', null, InputOption::VALUE_NONE, 'Uninstall all')
24+
;
25+
}
26+
27+
protected function execute(InputInterface $input, OutputInterface $output): int
28+
{
29+
$package = $input->getArgument('package');
30+
$all = $input->getOption('all');
31+
32+
if (!$package && !$all) {
33+
$this->getIO()
34+
->writeError('You must either specify a package name or --all to remove all recipes.');
35+
36+
return Command::FAILURE;
37+
}
38+
39+
$packagesToRemove = $package ? [$package] : $this->getRequiredPackages();
40+
41+
(new ServiceContainer($this->requireComposer(), $this->getIO()))
42+
->get(Oven::class)
43+
?->uninstallRecipes($packagesToRemove);
44+
45+
return Command::SUCCESS;
46+
}
47+
48+
private function getRequiredPackages(): array
49+
{
50+
$rootPackage = $this->requireComposer()
51+
->getPackage();
52+
53+
return array_keys($rootPackage->getRequires() + $rootPackage->getDevRequires());
54+
}
55+
}

src/Cook.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
use Composer\Plugin\PluginInterface;
1515
use Composer\Script\ScriptEvents;
1616
use Williarin\Cook\Command\CookCommand;
17+
use Williarin\Cook\Command\CookUninstallCommand;
1718

1819
final class Cook implements PluginInterface, Capable, EventSubscriberInterface, CommandProvider
1920
{
2021
private array $newPackages = [];
22+
private array $packagesToRemove = [];
2123
private ?ServiceContainer $serviceContainer = null;
2224
private Composer $composer;
2325
private IOInterface $io;
@@ -45,14 +47,15 @@ public function getCapabilities(): array
4547

4648
public function getCommands(): array
4749
{
48-
return [new CookCommand()];
50+
return [new CookCommand(), new CookUninstallCommand()];
4951
}
5052

5153
public static function getSubscribedEvents(): array
5254
{
5355
return [
5456
PackageEvents::POST_PACKAGE_INSTALL => ['addNewPackage'],
5557
PackageEvents::POST_PACKAGE_UPDATE => ['addNewPackage'],
58+
PackageEvents::PRE_PACKAGE_UNINSTALL => ['removePackage'],
5659
ScriptEvents::POST_INSTALL_CMD => ['postUpdate'],
5760
ScriptEvents::POST_UPDATE_CMD => ['postUpdate'],
5861
];
@@ -69,9 +72,17 @@ public function addNewPackage(PackageEvent $event): void
6972
$this->newPackages[] = $package->getName();
7073
}
7174

75+
public function removePackage(PackageEvent $event): void
76+
{
77+
$this->packagesToRemove[] = $event->getOperation()
78+
->getPackage()
79+
->getName();
80+
}
81+
7282
public function postUpdate(): void
7383
{
7484
$this->executeRecipes();
85+
$this->uninstallRecipes();
7586
$this->displayPostInstallOutput();
7687
}
7788

@@ -91,6 +102,13 @@ private function executeRecipes(): void
91102
?->cookRecipes($this->newPackages);
92103
}
93104

105+
private function uninstallRecipes(): void
106+
{
107+
$this->getServiceContainer()
108+
->get(Oven::class)
109+
?->uninstallRecipes($this->packagesToRemove);
110+
}
111+
94112
private function displayPostInstallOutput(): void
95113
{
96114
$this->getServiceContainer()

src/Merger/AbstractMerger.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protected function getSourceContent(array $file): ?string
5757
if (\array_key_exists('source', $file)) {
5858
$sourcePathname = sprintf('%s/%s', $this->state->getCurrentPackageDirectory(), $file['source']);
5959

60-
if (!file_exists($sourcePathname)) {
60+
if (!$this->filesystem->exists($sourcePathname)) {
6161
$this->io->write(sprintf(
6262
'<error>Error found in %s recipe: file "%s" not found.</>',
6363
$this->state->getCurrentPackage(),

0 commit comments

Comments
 (0)