diff --git a/CHANGELOG.md b/CHANGELOG.md index 6abb36e4..163de935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ For a full diff see [`2.7.0...main`][2.7.0...main]. For a full diff see [`2.6.1...2.7.0`][2.6.1...2.7.0]. +### Added + +* Added `--no-check-lock` option which allows skipping validation of `composer.lock` ([#515]), by [@localheinz] + ### Changed * Updated `schema.json` ([#512]), by [@ergebnis-bot] @@ -521,6 +525,7 @@ For a full diff see [`81bc3a8...0.1.0`][81bc3a8...0.1.0]. [#485]: https://github.com/ergebnis/composer-normalize/pull/485 [#487]: https://github.com/ergebnis/composer-normalize/pull/487 [#512]: https://github.com/ergebnis/composer-normalize/pull/512 +[#515]: https://github.com/ergebnis/composer-normalize/pull/515 [@core23]: https://github.com/core23 [@dependabot]: https://github.com/dependabot diff --git a/README.md b/README.md index 7f64e312..f60f8353 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ to normalize `composer.json` in the working directory. The `NormalizeCommand` provided by the `NormalizePlugin` within this package will * determine whether a `composer.json` exists -* determine whether a `composer.lock` exists, and if so, whether it is up to date +* determine whether a `composer.lock` exists, and if so, whether it is up to date (unless the `--no-check-lock` option is used) * use the `ComposerJsonNormalizer` from [`ergebnis/composer-json-normalizer`](https://github.com/ergebnis/composer-json-normalizer) to normalize the content of `composer.json` * format the normalized content (either as sniffed, or as specified using the `--indent-size` and `--indent-style` options) * write the normalized and formatted content of `composer.json` back to the file @@ -128,6 +128,7 @@ The `NormalizeCommand` provided by the `NormalizePlugin` within this package wil * `--dry-run`: Show the results of normalizing, but do not modify any files * `--indent-size`: Indent size (an integer greater than 0); should be used with the `--indent-style` option * `--indent-style`: Indent style (one of "space", "tab"); should be used with the `--indent-size` option +* `--no-check-lock`: Do not check if lock file is up to date * `--no-update-lock`: Do not update lock file if it exists ### Continuous Integration diff --git a/src/Command/NormalizeCommand.php b/src/Command/NormalizeCommand.php index 051c94f6..b101be3c 100644 --- a/src/Command/NormalizeCommand.php +++ b/src/Command/NormalizeCommand.php @@ -93,6 +93,12 @@ protected function configure(): void \implode('", "', \array_keys(self::$indentStyles)) ) ), + new Console\Input\InputOption( + 'no-check-lock', + null, + Console\Input\InputOption::VALUE_NONE, + 'Do not check if lock file is up to date' + ), new Console\Input\InputOption( 'no-update-lock', null, @@ -139,7 +145,7 @@ protected function execute(Console\Input\InputInterface $input, Console\Output\O $locker = $composer->getLocker(); - if ($locker->isLocked() && !$locker->isFresh()) { + if (false === $input->getOption('no-check-lock') && $locker->isLocked() && !$locker->isFresh()) { $io->writeError('The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update --lock`.'); return 1; diff --git a/test/Fixture/json/valid/lock/present/lock/not-fresh-before/composer.json b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/false/composer.json similarity index 100% rename from test/Fixture/json/valid/lock/present/lock/not-fresh-before/composer.json rename to test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/false/composer.json diff --git a/test/Fixture/json/valid/lock/present/lock/not-fresh-before/composer.lock b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/false/composer.lock similarity index 100% rename from test/Fixture/json/valid/lock/present/lock/not-fresh-before/composer.lock rename to test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/false/composer.lock diff --git a/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized/composer.json b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized/composer.json new file mode 100644 index 00000000..39f0d4bf --- /dev/null +++ b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized/composer.json @@ -0,0 +1,19 @@ +{ + "type": "library", + "keywords": [ + "foo", + "bar" + ], + "license": "MIT", + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com" + } + ], + "require": { + "php": "^5.6", + "ext-json": "*" + }, + "_comment": "This composer.json is valid according to a lax validation, a composer.lock is present, but not fresh before invoking the command with the --no-check-lock option, and already normalized." +} diff --git a/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized/composer.lock b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized/composer.lock new file mode 100644 index 00000000..15f57b15 --- /dev/null +++ b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized/composer.lock @@ -0,0 +1,21 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "e02bb041c58876f82f19080ccf708473", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^5.6", + "ext-json": "*" + }, + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized/composer.json b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized/composer.json new file mode 100644 index 00000000..ab8317a1 --- /dev/null +++ b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized/composer.json @@ -0,0 +1,19 @@ +{ + "type": "library", + "_comment": "This composer.json is valid according to a lax validation, a composer.lock is present, but not fresh before invoking the command with the --no-check-lock option, and not yet normalized.", + "keywords": [ + "foo", + "bar" + ], + "license": "MIT", + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com" + } + ], + "require": { + "ext-json": "*", + "php": "^5.6" + } +} diff --git a/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized/composer.lock b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized/composer.lock new file mode 100644 index 00000000..15f57b15 --- /dev/null +++ b/test/Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized/composer.lock @@ -0,0 +1,21 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "e02bb041c58876f82f19080ccf708473", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^5.6", + "ext-json": "*" + }, + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/test/Integration/Command/NormalizeCommandTest.php b/test/Integration/Command/NormalizeCommandTest.php index f832c260..3b93480e 100644 --- a/test/Integration/Command/NormalizeCommandTest.php +++ b/test/Integration/Command/NormalizeCommandTest.php @@ -590,7 +590,7 @@ public function testFailsWhenComposerJsonIsPresentAndValidAccordingToLaxValidati { $scenario = self::createScenario( $commandInvocation, - __DIR__ . '/../../Fixture/json/valid/lock/present/lock/not-fresh-before' + __DIR__ . '/../../Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/false' ); $initialState = $scenario->initialState(); @@ -615,6 +615,95 @@ public function testFailsWhenComposerJsonIsPresentAndValidAccordingToLaxValidati self::assertEquals($initialState, $scenario->currentState()); } + /** + * @dataProvider providerCommandInvocation + * + * @param CommandInvocation $commandInvocation + */ + public function testSucceedsWhenComposerJsonIsPresentAndValidAccordingToLaxValidationAndComposerLockIsPresentButNotFreshBeforeNoCheckLockOptionIsUsedAndComposerJsonIsAlreadyNormalized(CommandInvocation $commandInvocation): void + { + $scenario = self::createScenario( + $commandInvocation, + __DIR__ . '/../../Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/already-normalized' + ); + + $initialState = $scenario->initialState(); + + self::assertComposerJsonFileExists($initialState); + self::assertComposerLockFileExists($initialState); + self::assertComposerLockFileNotFresh($initialState); + + $application = self::createApplicationWithNormalizeCommandAsProvidedByNormalizePlugin(); + + $input = new Console\Input\ArrayInput($scenario->consoleParametersWith([ + '--no-check-lock' => true, + ])); + + $output = new Console\Output\BufferedOutput(); + + $exitCode = $application->run( + $input, + $output + ); + + self::assertExitCodeSame(0, $exitCode); + + $expected = \sprintf( + '%s is already normalized.', + $scenario->composerJsonFileReference() + ); + + self::assertStringContainsString($expected, $output->fetch()); + self::assertEquals($initialState, $scenario->currentState()); + } + + /** + * @dataProvider providerCommandInvocation + * + * @param CommandInvocation $commandInvocation + */ + public function testSucceedsWhenComposerJsonIsPresentAndValidAccordingToLaxValidationAndComposerLockIsPresentButNotFreshBeforeNoCheckLockOptionIsUsedAndComposerJsonIsNotYetNormalized(CommandInvocation $commandInvocation): void + { + $scenario = self::createScenario( + $commandInvocation, + __DIR__ . '/../../Fixture/json/valid/lock/present/lock/not-fresh-before/no-check-lock/true/json/not-yet-normalized' + ); + + $initialState = $scenario->initialState(); + + self::assertComposerJsonFileExists($initialState); + self::assertComposerLockFileExists($initialState); + self::assertComposerLockFileNotFresh($initialState); + + $application = self::createApplicationWithNormalizeCommandAsProvidedByNormalizePlugin(); + + $input = new Console\Input\ArrayInput($scenario->consoleParametersWith([ + '--no-check-lock' => true, + ])); + + $output = new Console\Output\BufferedOutput(); + + $exitCode = $application->run( + $input, + $output + ); + + self::assertExitCodeSame(0, $exitCode); + + $expected = \sprintf( + 'Successfully normalized %s.', + $scenario->composerJsonFileReference() + ); + + self::assertStringContainsString($expected, $output->fetch()); + + $currentState = $scenario->currentState(); + + self::assertComposerJsonFileModified($initialState, $currentState); + self::assertComposerLockFileModified($initialState, $currentState); + self::assertComposerLockFileFresh($currentState); + } + /** * @dataProvider providerCommandInvocation *