diff --git a/CHANGELOG.md b/CHANGELOG.md index 54a9d391..9c26471a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ For a full diff see [`0.9.0...1.0.0`](https://github.com/localheinz/composer-nor * Added this changelog ([#94](https://github.com/localheinz/composer-normalize/pull/94)), by [@localheinz](https://github.com/localheinz) +#### Fixed + +* Force reading `composer.json` and `composer.lock` after normalization to ensure `composer.lock` is updated when not fresh after normalization ([#139](https://github.com/localheinz/composer-normalize/pull/139)), by [@localheinz](https://github.com/localheinz) + #### Removed * Removed normalizers after extracting package [`localheinz/composer-json-normalizer`](https://github.com/localheinz/composer-json-normalizer) ([#106](https://github.com/localheinz/composer-normalize/pull/106)), by [@localheinz](https://github.com/localheinz) diff --git a/src/Command/NormalizeCommand.php b/src/Command/NormalizeCommand.php index 0eb55aa6..69ea6e7e 100644 --- a/src/Command/NormalizeCommand.php +++ b/src/Command/NormalizeCommand.php @@ -238,6 +238,17 @@ protected function execute(Console\Input\InputInterface $input, Console\Output\O if (false === $noUpdateLock && true === $locker->isLocked()) { $io->write('Updating lock file.'); + $this->resetComposer(); + + $file = $input->getArgument('file'); + + if (\is_string($file)) { + return $this->updateLockerInWorkingDirectory( + $output, + \dirname($file) + ); + } + return $this->updateLocker($output); } @@ -380,4 +391,30 @@ private function updateLocker(Console\Output\OutputInterface $output): int $output ); } + + /** + * @see https://getcomposer.org/doc/03-cli.md#update + * + * @param Console\Output\OutputInterface $output + * @param string $workingDirectory + * + * @throws \Exception + * + * @return int + */ + private function updateLockerInWorkingDirectory(Console\Output\OutputInterface $output, string $workingDirectory): int + { + return $this->getApplication()->run( + new Console\Input\ArrayInput([ + 'command' => 'update', + '--lock' => true, + '--no-autoloader' => true, + '--no-plugins' => true, + '--no-scripts' => true, + '--no-suggest' => true, + '--working-dir' => $workingDirectory, + ]), + $output + ); + } } diff --git a/test/Integration/NormalizeTest.php b/test/Integration/NormalizeTest.php index 66eb1e70..a0d7798f 100644 --- a/test/Integration/NormalizeTest.php +++ b/test/Integration/NormalizeTest.php @@ -709,6 +709,56 @@ public function testSucceedsWhenComposerJsonIsPresentAndValidAndComposerLockIsPr self::assertComposerLockFileNotModified($initialState, $currentState); } + /** + * @dataProvider providerCommandInvocation + * + * @param CommandInvocation $commandInvocation + */ + public function testSucceedsWhenComposerJsonIsPresentAndValidAndComposerLockIsPresentAndFreshBeforeAndComposerJsonIsNotYetNormalizedAndComposerLockIsNotFreshAfter(CommandInvocation $commandInvocation): void + { + $scenario = $this->createScenario( + $commandInvocation, + __DIR__ . '/../Fixture/json/valid/lock/present/lock/fresh-before/json/not-yet-normalized/lock/not-fresh-after' + ); + + $initialState = $scenario->initialState(); + + self::assertComposerJsonFileExists($initialState); + self::assertComposerLockFileExists($initialState); + self::assertComposerLockFileFresh($initialState); + + $application = $this->createApplication(new NormalizeCommand( + new Factory(), + new ComposerJsonNormalizer(), + new Formatter(), + new Differ() + )); + + $input = new Console\Input\ArrayInput($scenario->consoleParameters()); + + $output = new Console\Output\BufferedOutput(); + + $exitCode = $application->run( + $input, + $output + ); + + self::assertExitCodeSame(0, $exitCode); + + $expected = \sprintf( + 'Successfully normalized %s.', + $scenario->composerJsonFileReference() + ); + + self::assertContains($expected, $output->fetch()); + + $currentState = $scenario->currentState(); + + self::assertComposerJsonFileModified($initialState, $currentState); + self::assertComposerLockFileModified($initialState, $currentState); + self::assertComposerLockFileFresh($currentState); + } + /** * @dataProvider providerCommandInvocation * @@ -989,6 +1039,17 @@ private static function assertComposerLockFileNotFresh(State $state): void )); } + private static function assertComposerLockFileModified(State $expected, State $actual): void + { + self::assertComposerLockFileExists($actual); + + self::assertJsonStringNotEqualsJsonString( + $expected->composerLockFile()->contents(), + $actual->composerLockFile()->contents(), + 'Failed asserting that initial composer.lock has been modified.' + ); + } + private static function assertComposerLockFileNotModified(State $expected, State $actual): void { self::assertComposerLockFileExists($actual);