diff --git a/src/Configurator/ComposerScriptsConfigurator.php b/src/Configurator/ComposerScriptsConfigurator.php index a230eda5..a635d300 100644 --- a/src/Configurator/ComposerScriptsConfigurator.php +++ b/src/Configurator/ComposerScriptsConfigurator.php @@ -74,6 +74,31 @@ private function configureScripts(array $scripts, JsonFile $json): string $manipulator = new JsonManipulator(file_get_contents($json->getPath())); $manipulator->addSubNode('scripts', 'auto-scripts', $autoScripts); + foreach (['post-install-cmd', 'post-update-cmd'] as $hook) { + $current = $jsonContents['scripts'][$hook] ?? null; + $wired = $this->ensureAutoScriptsHook($current); + if ($wired !== $current) { + $manipulator->addSubNode('scripts', $hook, $wired); + } + } + return $manipulator->getContents(); } + + private function ensureAutoScriptsHook($current): array + { + if (null === $current) { + return ['@auto-scripts']; + } + + if (!\is_array($current)) { + $current = [$current]; + } + + if (!\in_array('@auto-scripts', $current, true)) { + $current[] = '@auto-scripts'; + } + + return $current; + } } diff --git a/tests/Configurator/ComposerScriptsConfiguratorTest.php b/tests/Configurator/ComposerScriptsConfiguratorTest.php index 32e9d883..df6df066 100644 --- a/tests/Configurator/ComposerScriptsConfiguratorTest.php +++ b/tests/Configurator/ComposerScriptsConfiguratorTest.php @@ -91,6 +91,159 @@ public function testConfigure() ); } + public function testConfigureAddsHooksWhenMissing() + { + file_put_contents(FLEX_TEST_DIR.'/composer.json', json_encode([ + 'scripts' => [ + 'auto-scripts' => [ + 'cache:clear' => 'symfony-cmd', + ], + ], + ], \JSON_PRETTY_PRINT)); + + $configurator = new ComposerScriptsConfigurator( + $this->createMock(Composer::class), + $this->createMock(IOInterface::class), + new Options(['root-dir' => FLEX_TEST_DIR]) + ); + + $recipe = $this->getMockBuilder(Recipe::class)->disableOriginalConstructor()->getMock(); + $lock = $this->getMockBuilder(Lock::class)->disableOriginalConstructor()->getMock(); + + $configurator->configure($recipe, [ + 'do:cool-stuff' => 'symfony-cmd', + ], $lock); + $this->assertEquals(<< [ + 'auto-scripts' => [ + 'cache:clear' => 'symfony-cmd', + ], + 'post-install-cmd' => ['@some-other'], + 'post-update-cmd' => ['@some-other'], + ], + ], \JSON_PRETTY_PRINT)); + + $configurator = new ComposerScriptsConfigurator( + $this->createMock(Composer::class), + $this->createMock(IOInterface::class), + new Options(['root-dir' => FLEX_TEST_DIR]) + ); + + $recipe = $this->getMockBuilder(Recipe::class)->disableOriginalConstructor()->getMock(); + $lock = $this->getMockBuilder(Lock::class)->disableOriginalConstructor()->getMock(); + + $configurator->configure($recipe, [ + 'do:cool-stuff' => 'symfony-cmd', + ], $lock); + $this->assertEquals(<< [ + 'auto-scripts' => [ + 'cache:clear' => 'symfony-cmd', + ], + 'post-install-cmd' => '@some-other', + 'post-update-cmd' => '@some-other', + ], + ], \JSON_PRETTY_PRINT)); + + $configurator = new ComposerScriptsConfigurator( + $this->createMock(Composer::class), + $this->createMock(IOInterface::class), + new Options(['root-dir' => FLEX_TEST_DIR]) + ); + + $recipe = $this->getMockBuilder(Recipe::class)->disableOriginalConstructor()->getMock(); + $lock = $this->getMockBuilder(Lock::class)->disableOriginalConstructor()->getMock(); + + $configurator->configure($recipe, [ + 'do:cool-stuff' => 'symfony-cmd', + ], $lock); + $this->assertEquals(<< [ + 'auto-scripts' => [ + 'do:cool-stuff' => 'symfony-cmd', + ], + 'post-install-cmd' => ['@auto-scripts'], + 'post-update-cmd' => ['@auto-scripts'], + ], + ], \JSON_PRETTY_PRINT)); + + $configurator = new ComposerScriptsConfigurator( + $this->createMock(Composer::class), + $this->createMock(IOInterface::class), + new Options(['root-dir' => FLEX_TEST_DIR]) + ); + + $recipe = $this->getMockBuilder(Recipe::class)->disableOriginalConstructor()->getMock(); + $lock = $this->getMockBuilder(Lock::class)->disableOriginalConstructor()->getMock(); + + $configurator->configure($recipe, [ + 'do:cool-stuff' => 'symfony-cmd', + ], $lock); + $afterFirst = file_get_contents(FLEX_TEST_DIR.'/composer.json'); + + $configurator->configure($recipe, [ + 'do:cool-stuff' => 'symfony-cmd', + ], $lock); + $this->assertSame($afterFirst, file_get_contents(FLEX_TEST_DIR.'/composer.json')); + } + public function testUnconfigure() { file_put_contents(FLEX_TEST_DIR.'/composer.json', json_encode([