From f7e9486d0afaf097dae8e7d2868045dc634910ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 17 Feb 2018 23:00:31 +0100 Subject: [PATCH] Enhancement: Add file argument --- README.md | 4 + src/Command/NormalizeCommand.php | 11 +- test/Unit/Command/NormalizeCommandTest.php | 191 +++++++++++++++++++-- 3 files changed, 188 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 7e7f6a95..2274703a 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,10 @@ The `NormalizeCommand` provided by the `NormalizePlugin` within this package wil * write the normalized and formatted content of `composer.json` back to the file * update the hash in `composer.lock` if it exists and if an update is necessary +### Arguments + +* `file`: Path to composer.json file (optional, defaults to `composer.json` in working directory) + ### Options * `--dry-run`: Show the results of normalizing, but do not modify any files diff --git a/src/Command/NormalizeCommand.php b/src/Command/NormalizeCommand.php index d4b17738..14a980d6 100644 --- a/src/Command/NormalizeCommand.php +++ b/src/Command/NormalizeCommand.php @@ -74,6 +74,11 @@ protected function configure(): void { $this->setDescription('Normalizes composer.json according to its JSON schema (https://getcomposer.org/schema.json).'); $this->setDefinition([ + new Console\Input\InputArgument( + 'file', + Console\Input\InputArgument::OPTIONAL, + 'Path to composer.json file' + ), new Console\Input\InputOption( 'dry-run', null, @@ -121,7 +126,11 @@ protected function execute(Console\Input\InputInterface $input, Console\Output\O return 1; } - $composerFile = Factory::getComposerFile(); + $composerFile = $input->getArgument('file'); + + if (null === $composerFile) { + $composerFile = Factory::getComposerFile(); + } try { $composer = $this->factory->createComposer( diff --git a/test/Unit/Command/NormalizeCommandTest.php b/test/Unit/Command/NormalizeCommandTest.php index b4dfccf5..9f9fc646 100644 --- a/test/Unit/Command/NormalizeCommandTest.php +++ b/test/Unit/Command/NormalizeCommandTest.php @@ -62,7 +62,7 @@ public function testHasNameAndDescription(): void $this->assertSame('Normalizes composer.json according to its JSON schema (https://getcomposer.org/schema.json).', $command->getDescription()); } - public function testHasNoArguments(): void + public function testHasFileArgument(): void { $command = new NormalizeCommand( $this->prophesize(Factory::class)->reveal(), @@ -71,7 +71,13 @@ public function testHasNoArguments(): void $definition = $command->getDefinition(); - $this->assertCount(0, $definition->getArguments()); + $this->assertTrue($definition->hasArgument('file')); + + $argument = $definition->getArgument('file'); + + $this->assertFalse($argument->isRequired()); + $this->assertSame('Path to composer.json file', $argument->getDescription()); + $this->assertNull($argument->getDefault()); } public function testHasDryRunOption(): void @@ -181,6 +187,7 @@ public function testExecuteWithIndentFailsIfIndentStyleOptionIsNotUsed(): void $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--indent-size' => $this->faker()->numberBetween(1), ]); @@ -211,6 +218,7 @@ public function testExecuteWithIndentFailsIfIndentSizeOptionIsNotUsed(): void $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--indent-style' => $this->faker()->randomElement([ 'space', 'tab', @@ -254,6 +262,7 @@ public function testExecuteWithIndentFailsIfIndentSizeIsInvalid($indentSize): vo $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--indent-size' => $indentSize, '--indent-style' => $indentStyle, ]); @@ -309,6 +318,7 @@ public function testExecuteWithIndentFailsIfIndentStyleIsInvalid(): void $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--indent-size' => $indentSize, '--indent-style' => $indentStyle, ]); @@ -352,7 +362,9 @@ public function testExecuteFailsIfCreatingComposerFails(): void $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame(1, $tester->getStatusCode()); } @@ -395,7 +407,9 @@ public function testExecuteFailsIfComposerFileIsNotWritable(): void $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); \chmod($composerFile, 0666); @@ -454,7 +468,9 @@ public function testExecuteFailsIfLockerIsLockedButNotFresh(): void $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame(1, $tester->getStatusCode()); $this->assertFileExists($composerFile); @@ -553,7 +569,9 @@ public function testExecuteFailsIfNormalizerThrowsInvalidArgumentException(): vo $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame($exitCode, $tester->getStatusCode()); $this->assertFileExists($composerFile); @@ -622,7 +640,9 @@ public function testExecuteFailsIfNormalizerThrowsRuntimeException(): void $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame(1, $tester->getStatusCode()); $this->assertFileExists($composerFile); @@ -707,7 +727,9 @@ public function testExecuteSucceedsIfLockerIsNotLockedAndComposerFileIsAlreadyNo $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame(0, $tester->getStatusCode()); $this->assertFileExists($composerFile); @@ -797,7 +819,9 @@ public function testExecuteSucceedsIfLockerIsLockedAndFreshButComposerFileIsAlre $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame(0, $tester->getStatusCode()); $this->assertFileExists($composerFile); @@ -888,6 +912,7 @@ public function testExecuteWithDryRunSucceedsIfLockerIsLockedAndFreshButComposer $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--dry-run' => null, ]); @@ -982,7 +1007,9 @@ public function testExecuteSucceedsIfLockerIsNotLockedAndComposerFileWasNormaliz $tester = new Console\Tester\CommandTester($command); - $tester->execute([]); + $tester->execute([ + 'file' => $composerFile, + ]); $this->assertSame(0, $tester->getStatusCode()); $this->assertFileExists($composerFile); @@ -1094,6 +1121,7 @@ public function testExecuteWithDryRunFailsIfLockerIsNotLockedAndComposerFileWasN $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--dry-run' => null, ]); @@ -1206,6 +1234,7 @@ public function testExecuteWithIndentSucceedsIfLockerIsNotLockedAndComposerFileW $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--indent-size' => $indentSize, '--indent-style' => $indentStyle, ]); @@ -1319,6 +1348,7 @@ public function testExecuteFailsIfLockerIsNotLockedAndComposerFileWasNormalizedS $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--indent-size' => $indentSize, '--indent-style' => $indentStyle, ]); @@ -1449,6 +1479,138 @@ public function testExecuteSucceedsIfLockerIsLockedAndLockerCouldBeUpdatedAfterN $tester = new Console\Tester\CommandTester($command); + $tester->execute([ + 'file' => $composerFile, + ]); + + $this->assertSame(0, $tester->getStatusCode()); + $this->assertFileExists($composerFile); + $this->assertStringEqualsFile($composerFile, $formatted); + } + + public function testExecuteDefaultsToUsingComposerFileFromCurrentDirectory(): void + { + $original = $this->composerFileContent(); + + $normalized = \json_encode(\array_reverse(\json_decode( + $original, + true + ))); + + $formatted = \json_encode( + \json_decode($normalized), + JSON_PRETTY_PRINT + ); + + $composerFile = $this->pathToComposerFileWithContent($original); + + $this->useComposerFile($composerFile); + + $io = $this->prophesize(IO\ConsoleIO::class); + + $io + ->write(Argument::is(\sprintf( + 'Successfully normalized %s.', + $composerFile + ))) + ->shouldBeCalled(); + + $io + ->write(Argument::is('Updating lock file.')) + ->shouldBeCalled(); + + $locker = $this->prophesize(Package\Locker::class); + + $locker + ->isLocked() + ->shouldBeCalled() + ->willReturn(true); + + $locker + ->isFresh() + ->shouldBeCalled() + ->willReturn(true); + + $composer = $this->prophesize(Composer::class); + + $composer + ->getLocker() + ->shouldBeCalled() + ->willReturn($locker); + + $factory = $this->prophesize(Factory::class); + + $factory + ->createComposer( + Argument::is($io->reveal()), + Argument::is($composerFile) + ) + ->shouldBeCalled() + ->willReturn($composer->reveal()); + + $application = $this->prophesize(Application::class); + + $application + ->getHelperSet() + ->shouldBeCalled() + ->willReturn(new Console\Helper\HelperSet()); + + $application + ->getDefinition() + ->shouldBeCalled() + ->willReturn($this->createDefinitionMock()); + + $application + ->run( + Argument::allOf( + Argument::type(Console\Input\StringInput::class), + Argument::that(function (Console\Input\StringInput $input) { + return 'update --lock --no-autoloader --no-plugins --no-scripts --no-suggest' === (string) $input; + }) + ), + Argument::type(Console\Output\OutputInterface::class) + ) + ->shouldBeCalled() + ->willReturn(0); + + $normalizer = $this->prophesize(Normalizer\NormalizerInterface::class); + + $normalizer + ->normalize(Argument::is($original)) + ->shouldBeCalled() + ->willReturn($normalized); + + $format = $this->prophesize(Normalizer\Format\FormatInterface::class); + + $sniffer = $this->prophesize(Normalizer\Format\SnifferInterface::class); + + $sniffer + ->sniff(Argument::is($original)) + ->shouldBeCalled() + ->willReturn($format); + + $formatter = $this->prophesize(Normalizer\Format\FormatterInterface::class); + + $formatter + ->format( + Argument::is($normalized), + Argument::is($format->reveal()) + ) + ->shouldBeCalled() + ->willReturn($formatted); + + $command = new NormalizeCommand( + $factory->reveal(), + $normalizer->reveal(), + $sniffer->reveal(), + $formatter->reveal() + ); + + $command->setIO($io->reveal()); + $command->setApplication($application->reveal()); + + $tester = new Console\Tester\CommandTester($command); + $tester->execute([]); $this->assertSame(0, $tester->getStatusCode()); @@ -1565,6 +1727,7 @@ public function testExecuteSucceedsIfLockerIsLockedButSkipsUpdatingLockerIfNoUpd $tester = new Console\Tester\CommandTester($command); $tester->execute([ + 'file' => $composerFile, '--no-update-lock' => null, ]); @@ -1597,8 +1760,6 @@ private function pathToComposerFileWithContent(string $content): string \file_put_contents($composerFile, $content); - $this->useComposerFile($composerFile); - return $composerFile; } @@ -1609,11 +1770,7 @@ private function pathToComposerFileWithContent(string $content): string */ private function pathToNonExistentComposerFile(): string { - $composerFile = $this->pathToComposerFile(); - - $this->useComposerFile($composerFile); - - return $composerFile; + return $this->pathToComposerFile(); } /**