From 623a9a01412606e0ec5a035dfe05d4bc4b9103b5 Mon Sep 17 00:00:00 2001 From: Ion Bazan Date: Thu, 6 Feb 2025 15:23:48 +0800 Subject: [PATCH] Allow specifying direct dependencies (#40) --- .github/workflows/test.yml | 7 +- README.md | 1 + src/Command/DiffCommand.php | 10 ++- src/Diff/DiffEntry.php | 17 ++++- src/Formatter/JsonFormatter.php | 7 +- src/PackageDiff.php | 96 +++++++++++++++++++++++---- tests/Command/DiffCommandTest.php | 7 ++ tests/Formatter/JsonFormatterTest.php | 25 +++++++ tests/Integration/DiffCommandTest.php | 44 ++++++++++++ tests/PackageDiffTest.php | 76 ++++++++++++++++----- 10 files changed, 253 insertions(+), 37 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 69207a0..8bfd7be 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,7 @@ jobs: - '8.2' - '8.3' - '8.4' + - '8.5' include: - php-versions: '5.3' dependencies: 'lowest' @@ -52,7 +53,7 @@ jobs: with: dependency-versions: ${{ matrix.dependencies }} - name: Check PSR-4 mapping - if: ${{ matrix.php-versions == 8.3 && matrix.composer == 'v2' }} + if: ${{ matrix.php-versions == 8.4 && matrix.composer == 'v2' }} run: composer dump-autoload --dev --optimize --strict-psr - name: Set default branch for tests run: git config --global init.defaultBranch main @@ -63,7 +64,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} - name: Run mutation tests - if: ${{ matrix.php-versions == 8.3 && matrix.operating-system == 'ubuntu-latest' }} + if: ${{ matrix.php-versions == 8.4 && matrix.operating-system == 'ubuntu-latest' }} env: STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }} run: | @@ -71,7 +72,7 @@ jobs: composer require infection/infection --update-with-all-dependencies vendor/bin/infection --ignore-msi-with-no-mutations --min-covered-msi=100 --min-msi=100 -s -j4 --only-covered - name: Run phpstan - if: ${{ matrix.php-versions == 8.3 && matrix.operating-system == 'ubuntu-latest' }} + if: ${{ matrix.php-versions == 8.4 && matrix.operating-system == 'ubuntu-latest' }} run: | composer require phpstan/phpstan --dev vendor/bin/phpstan diff --git a/README.md b/README.md index 666dc5a..897660e 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ composer diff --help # Display detailed usage instructions - `--target` (`-t`) - path, URL or git ref to modified `composer.lock` file - `--no-dev` - ignore dev dependencies (`require-dev`) - `--no-prod` - ignore prod dependencies (`require`) + - `--direct` (`-D`) - only show direct dependencies - `--with-platform` (`-p`) - include platform dependencies (PHP, extensions, etc.) - `--with-links` (`-l`) - include compare/release URLs - `--with-licenses` (`-c`) - include license information diff --git a/src/Command/DiffCommand.php b/src/Command/DiffCommand.php index 4c2ce83..8b58920 100644 --- a/src/Command/DiffCommand.php +++ b/src/Command/DiffCommand.php @@ -63,6 +63,7 @@ protected function configure() ->addOption('target', 't', InputOption::VALUE_REQUIRED, 'Target (modified) composer.lock file path or git ref', 'composer.lock') ->addOption('no-dev', null, InputOption::VALUE_NONE, 'Ignore dev dependencies') ->addOption('no-prod', null, InputOption::VALUE_NONE, 'Ignore prod dependencies') + ->addOption('direct', 'D', InputOption::VALUE_NONE, 'Restricts the list of packages to your direct dependencies') ->addOption('with-platform', 'p', InputOption::VALUE_NONE, 'Include platform dependencies (PHP version, extensions, etc.)') ->addOption('with-links', 'l', InputOption::VALUE_NONE, 'Include compare/release URLs') ->addOption('with-licenses', 'c', InputOption::VALUE_NONE, 'Include licenses') @@ -95,6 +96,10 @@ protected function configure() By default, platform dependencies are hidden. Add --with-platform option to include them in the report: %command.full_name% --with-platform + +By default, transient dependencies are displayed. Add --direct option to only show direct dependencies: + +%command.full_name% --direct Use --with-links to include release and compare URLs in the report: @@ -135,6 +140,7 @@ protected function handle(InputInterface $input, OutputInterface $output) { $base = null !== $input->getArgument('base') ? $input->getArgument('base') : $input->getOption('base'); $target = null !== $input->getArgument('target') ? $input->getArgument('target') : $input->getOption('target'); + $onlyDirect = $input->getOption('direct'); $withPlatform = $input->getOption('with-platform'); $withUrls = $input->getOption('with-links'); $withLicenses = $input->getOption('with-licenses'); @@ -148,11 +154,11 @@ protected function handle(InputInterface $input, OutputInterface $output) $devOperations = new DiffEntries(array()); if (!$input->getOption('no-prod')) { - $prodOperations = $this->packageDiff->getPackageDiff($base, $target, false, $withPlatform); + $prodOperations = $this->packageDiff->getPackageDiff($base, $target, false, $withPlatform, $onlyDirect); } if (!$input->getOption('no-dev')) { - $devOperations = $this->packageDiff->getPackageDiff($base, $target, true, $withPlatform); + $devOperations = $this->packageDiff->getPackageDiff($base, $target, true, $withPlatform, $onlyDirect); } $formatter->render($prodOperations, $devOperations, $withUrls, $withLicenses); diff --git a/src/Diff/DiffEntry.php b/src/Diff/DiffEntry.php index 2e6f26d..35d64f3 100644 --- a/src/Diff/DiffEntry.php +++ b/src/Diff/DiffEntry.php @@ -19,12 +19,19 @@ class DiffEntry /** @var OperationInterface */ private $operation; + /** @var bool */ + private $direct; + /** @var string */ private $type; - public function __construct(OperationInterface $operation) + /** + * @param bool $direct + */ + public function __construct(OperationInterface $operation, $direct = false) { $this->operation = $operation; + $this->direct = $direct; $this->type = $this->determineType(); } @@ -44,6 +51,14 @@ public function getType() return $this->type; } + /** + * @return bool + */ + public function isDirect() + { + return $this->direct; + } + /** * @return bool */ diff --git a/src/Formatter/JsonFormatter.php b/src/Formatter/JsonFormatter.php index 4924f5f..788659d 100644 --- a/src/Formatter/JsonFormatter.php +++ b/src/Formatter/JsonFormatter.php @@ -44,7 +44,7 @@ private function format(array $data) * @param bool $withUrls * @param bool $withLicenses * - * @return array> + * @return array> */ private function transformEntries(DiffEntries $entries, $withUrls, $withLicenses) { @@ -69,7 +69,7 @@ private function transformEntries(DiffEntries $entries, $withUrls, $withLicenses } /** - * @return array + * @return array */ private function transformEntry(DiffEntry $entry) { @@ -78,6 +78,7 @@ private function transformEntry(DiffEntry $entry) if ($operation instanceof InstallOperation) { return array( 'name' => $operation->getPackage()->getName(), + 'direct' => $entry->isDirect(), 'operation' => $entry->getType(), 'version_base' => null, 'version_target' => $operation->getPackage()->getFullPrettyVersion(), @@ -87,6 +88,7 @@ private function transformEntry(DiffEntry $entry) if ($operation instanceof UpdateOperation) { return array( 'name' => $operation->getInitialPackage()->getName(), + 'direct' => $entry->isDirect(), 'operation' => $entry->getType(), 'version_base' => $operation->getInitialPackage()->getFullPrettyVersion(), 'version_target' => $operation->getTargetPackage()->getFullPrettyVersion(), @@ -96,6 +98,7 @@ private function transformEntry(DiffEntry $entry) if ($operation instanceof UninstallOperation) { return array( 'name' => $operation->getPackage()->getName(), + 'direct' => $entry->isDirect(), 'operation' => $entry->getType(), 'version_base' => $operation->getPackage()->getFullPrettyVersion(), 'version_target' => null, diff --git a/src/PackageDiff.php b/src/PackageDiff.php index 4acf657..5a64913 100644 --- a/src/PackageDiff.php +++ b/src/PackageDiff.php @@ -16,12 +16,18 @@ class PackageDiff { - const LOCKFILE = 'composer.lock'; + const COMPOSER = 'composer'; + const EXTENSION_LOCK = '.lock'; + const EXTENSION_JSON = '.json'; + const GIT_SEPARATOR = ':'; /** + * @param string[] $directPackages + * @param bool $onlyDirect + * * @return DiffEntries */ - public function getDiff(RepositoryInterface $oldPackages, RepositoryInterface $targetPackages) + public function getDiff(RepositoryInterface $oldPackages, RepositoryInterface $targetPackages, array $directPackages = array(), $onlyDirect = false) { $operations = array(); @@ -59,9 +65,19 @@ public function getDiff(RepositoryInterface $oldPackages, RepositoryInterface $t } } - return new DiffEntries(array_map(function (OperationInterface $operation) { - return new DiffEntry($operation); - }, $operations)); + $entries = array_map(function (OperationInterface $operation) use ($directPackages) { + $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage(); + + return new DiffEntry($operation, in_array($package->getName(), $directPackages, true)); + }, $operations); + + if ($onlyDirect) { + $entries = array_values(array_filter($entries, function (DiffEntry $entry) { + return $entry->isDirect(); + })); + } + + return new DiffEntries($entries); } /** @@ -69,14 +85,17 @@ public function getDiff(RepositoryInterface $oldPackages, RepositoryInterface $t * @param string $to * @param bool $dev * @param bool $withPlatform + * @param bool $onlyDirect * * @return DiffEntries */ - public function getPackageDiff($from, $to, $dev, $withPlatform) + public function getPackageDiff($from, $to, $dev, $withPlatform, $onlyDirect = false) { return $this->getDiff( $this->loadPackages($from, $dev, $withPlatform), - $this->loadPackages($to, $dev, $withPlatform) + $this->loadPackages($to, $dev, $withPlatform), + array_merge($this->getDirectPackages($from), $this->getDirectPackages($to)), + $onlyDirect ); } @@ -110,23 +129,54 @@ private function loadPackages($path, $dev, $withPlatform) /** * @param string $path * + * @return string[] + */ + private function getDirectPackages($path) + { + $data = \json_decode($this->getFileContents($path, false), true); + + $packages = array(); + + foreach (array('require', 'require-dev') as $key) { + if (isset($data[$key])) { + $packages = array_merge($packages, array_keys($data[$key])); + } + } + + return $packages; // @phpstan-ignore return.type + } + + /** + * @param string $path + * @param bool $lockFile + * * @return string */ - private function getFileContents($path) + private function getFileContents($path, $lockFile = true) { $originalPath = $path; if (empty($path)) { - $path = self::LOCKFILE; + $path = self::COMPOSER.($lockFile ? self::EXTENSION_LOCK : self::EXTENSION_JSON); } - if (filter_var($path, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) || file_exists($path)) { + $localPath = $path; + + if (!$lockFile) { + $localPath = $this->getJsonPath($localPath); + } + + if (filter_var($localPath, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) || file_exists($localPath)) { // @phpstan-ignore return.type - return file_get_contents($path); + return file_get_contents($localPath); + } + + if (false === strpos($originalPath, self::GIT_SEPARATOR)) { + $path .= self::GIT_SEPARATOR.self::COMPOSER.($lockFile ? self::EXTENSION_LOCK : self::EXTENSION_JSON); } - if (false === strpos($originalPath, ':')) { - $path .= ':'.self::LOCKFILE; + if (!$lockFile) { + $path = $this->getJsonPath($path); } $output = array(); @@ -134,9 +184,27 @@ private function getFileContents($path) $outputString = implode("\n", $output); if (0 !== $exit) { - throw new \RuntimeException(sprintf('Could not open file %s or find it in git as %s: %s', $originalPath, $path, $outputString)); + if ($lockFile) { + throw new \RuntimeException(sprintf('Could not open file %s or find it in git as %s: %s', $originalPath, $path, $outputString)); + } + + return '{}'; // Do not throw exception for composer.json as it might not exist and that's fine } return $outputString; } + + /** + * @param string $path + * + * @return string + */ + private function getJsonPath($path) + { + if (self::EXTENSION_LOCK === substr($path, -strlen(self::EXTENSION_LOCK))) { + return substr($path, 0, -strlen(self::EXTENSION_LOCK)).self::EXTENSION_JSON; + } + + return $path; + } } diff --git a/tests/Command/DiffCommandTest.php b/tests/Command/DiffCommandTest.php index 55032a7..0af2c36 100644 --- a/tests/Command/DiffCommandTest.php +++ b/tests/Command/DiffCommandTest.php @@ -207,42 +207,49 @@ public function outputDataProvider() 'packages' => array( 'a/package-1' => array( 'name' => 'a/package-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', ), 'a/package-2' => array( 'name' => 'a/package-2', + 'direct' => false, 'operation' => 'upgrade', 'version_base' => '1.0.0', 'version_target' => '1.2.0', ), 'a/package-3' => array( 'name' => 'a/package-3', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, ), 'a/package-4' => array( 'name' => 'a/package-4', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, ), 'a/package-5' => array( 'name' => 'a/package-5', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, ), 'a/package-6' => array( 'name' => 'a/package-6', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, ), 'a/package-7' => array( 'name' => 'a/package-7', + 'direct' => false, 'operation' => 'downgrade', 'version_base' => '1.2.0', 'version_target' => '1.0.0', diff --git a/tests/Formatter/JsonFormatterTest.php b/tests/Formatter/JsonFormatterTest.php index c9f779f..94c1937 100644 --- a/tests/Formatter/JsonFormatterTest.php +++ b/tests/Formatter/JsonFormatterTest.php @@ -31,6 +31,7 @@ public function testRenderSingle() $this->assertSame(self::formatOutput(array( 'a/package-1' => array( 'name' => 'a/package-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', @@ -39,6 +40,7 @@ public function testRenderSingle() ), 'a/no-link-1' => array( 'name' => 'a/no-link-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', @@ -47,6 +49,7 @@ public function testRenderSingle() ), 'a/package-2' => array( 'name' => 'a/package-2', + 'direct' => false, 'operation' => 'upgrade', 'version_base' => '1.0.0', 'version_target' => '1.2.0', @@ -55,6 +58,7 @@ public function testRenderSingle() ), 'a/package-3' => array( 'name' => 'a/package-3', + 'direct' => false, 'operation' => 'downgrade', 'version_base' => '2.0.0', 'version_target' => '1.1.1', @@ -63,6 +67,7 @@ public function testRenderSingle() ), 'a/no-link-2' => array( 'name' => 'a/no-link-2', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, @@ -71,6 +76,7 @@ public function testRenderSingle() ), 'a/package-5' => array( 'name' => 'a/package-5', + 'direct' => false, 'operation' => 'change', 'version_base' => 'dev-master 1234567', 'version_target' => '1.1.1', @@ -79,6 +85,7 @@ public function testRenderSingle() ), 'a/package-4' => array( 'name' => 'a/package-4', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, @@ -105,6 +112,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) 'packages' => array( 'a/package-1' => array( 'name' => 'a/package-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', @@ -113,6 +121,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $nullLicense, 'a/no-link-1' => array( 'name' => 'a/no-link-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', @@ -121,6 +130,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $nullLicense, 'a/package-2' => array( 'name' => 'a/package-2', + 'direct' => false, 'operation' => 'upgrade', 'version_base' => '1.0.0', 'version_target' => '1.2.0', @@ -129,6 +139,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $nullLicense, 'a/package-3' => array( 'name' => 'a/package-3', + 'direct' => false, 'operation' => 'downgrade', 'version_base' => '2.0.0', 'version_target' => '1.1.1', @@ -137,6 +148,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $nullLicense, 'a/no-link-2' => array( 'name' => 'a/no-link-2', + 'direct' => false, 'operation' => 'downgrade', 'version_base' => '2.0.0', 'version_target' => '1.1.1', @@ -145,6 +157,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $nullLicense, 'php' => array( 'name' => 'php', + 'direct' => false, 'operation' => 'change', 'version_base' => '>=7.4.6', 'version_target' => '^8.0', @@ -155,6 +168,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) 'packages-dev' => array( 'a/package-5' => array( 'name' => 'a/package-5', + 'direct' => false, 'operation' => 'change', 'version_base' => 'dev-master 1234567', 'version_target' => '1.1.1', @@ -163,6 +177,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $nullLicense, 'a/package-4' => array( 'name' => 'a/package-4', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, @@ -171,6 +186,7 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) ) + $package4License, 'a/no-link-2' => array( 'name' => 'a/no-link-2', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, @@ -185,36 +201,42 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) 'packages' => array( 'a/package-1' => array( 'name' => 'a/package-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', ) + $nullLicense, 'a/no-link-1' => array( 'name' => 'a/no-link-1', + 'direct' => false, 'operation' => 'install', 'version_base' => null, 'version_target' => '1.0.0', ) + $nullLicense, 'a/package-2' => array( 'name' => 'a/package-2', + 'direct' => false, 'operation' => 'upgrade', 'version_base' => '1.0.0', 'version_target' => '1.2.0', ) + $nullLicense, 'a/package-3' => array( 'name' => 'a/package-3', + 'direct' => false, 'operation' => 'downgrade', 'version_base' => '2.0.0', 'version_target' => '1.1.1', ) + $nullLicense, 'a/no-link-2' => array( 'name' => 'a/no-link-2', + 'direct' => false, 'operation' => 'downgrade', 'version_base' => '2.0.0', 'version_target' => '1.1.1', ) + $nullLicense, 'php' => array( 'name' => 'php', + 'direct' => false, 'operation' => 'change', 'version_base' => '>=7.4.6', 'version_target' => '^8.0', @@ -223,18 +245,21 @@ protected function getSampleOutput($withUrls, $withLicenses, $decorated) 'packages-dev' => array( 'a/package-5' => array( 'name' => 'a/package-5', + 'direct' => false, 'operation' => 'change', 'version_base' => 'dev-master 1234567', 'version_target' => '1.1.1', ) + $nullLicense, 'a/package-4' => array( 'name' => 'a/package-4', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, ) + $package4License, 'a/no-link-2' => array( 'name' => 'a/no-link-2', + 'direct' => false, 'operation' => 'remove', 'version_base' => '0.1.1', 'version_target' => null, diff --git a/tests/Integration/DiffCommandTest.php b/tests/Integration/DiffCommandTest.php index fc641bf..2510536 100644 --- a/tests/Integration/DiffCommandTest.php +++ b/tests/Integration/DiffCommandTest.php @@ -103,6 +103,50 @@ public function commandArgumentsDataProvider() '-p' => null, ), ), + 'only direct, with platform' => array( + <<=5.3 | + +| Dev Packages | Operation | Base | Target | +|-----------------|------------|-------|--------| +| phpunit/phpunit | Downgraded | 9.2.5 | 8.5.8 | + + +OUTPUT + , + array( + '--base' => __DIR__.'/../fixtures/base/composer.lock', + '--target' => __DIR__.'/../fixtures/target/composer.lock', + '--direct' => null, + '-p' => null, + ), + ), + 'only direct, with platform reversed' => array( + <<=5.3 | - | + +| Dev Packages | Operation | Base | Target | +|-----------------|-----------|-------|--------| +| phpunit/phpunit | Upgraded | 8.5.8 | 9.2.5 | + + +OUTPUT + , + array( + '--base' => __DIR__.'/../fixtures/target/composer.lock', + '--target' => __DIR__.'/../fixtures/base/composer.lock', + '--direct' => null, + '-p' => null, + ), + ), 'no-dev' => array( <<getPackageDiff( __DIR__.'/fixtures/base/composer.lock', __DIR__.'/fixtures/target/composer.lock', $dev, - $withPlatform + $withPlatform, + $onlyDirect ); $this->assertSame($expected, array_map(array($this, 'entryToString'), $operations->getArrayCopy())); @@ -64,14 +66,36 @@ public function testDiff(array $expected, RepositoryInterface $oldRepository, Re * @param string[] $expected * @param bool $dev * @param bool $withPlatform + * @param bool $onlyDirect * * @dataProvider operationsProvider */ - public function testGitUsage(array $expected, $dev, $withPlatform) + public function testGitUsage(array $expected, $dev, $withPlatform, $onlyDirect = false) { $diff = new PackageDiff(); $this->prepareGit(); - $operations = $diff->getPackageDiff('HEAD', '', $dev, $withPlatform); + $operations = $diff->getPackageDiff('HEAD', '', $dev, $withPlatform, $onlyDirect); + + $this->assertSame($expected, array_map(array($this, 'entryToString'), $operations->getArrayCopy())); + } + + /** + * @param string[] $expected + * @param bool $dev + * @param bool $withPlatform + * @param bool $onlyDirect + * + * @dataProvider operationsProvider + */ + public function testGitUsageWithoutJson(array $expected, $dev, $withPlatform, $onlyDirect = false) + { + $diff = new PackageDiff(); + $this->prepareGit(true); + $operations = $diff->getPackageDiff('HEAD', '', $dev, $withPlatform, $onlyDirect); + + if ($onlyDirect) { + $expected = array(); // if there is no json file, we can't determine direct dependencies + } $this->assertSame($expected, array_map(array($this, 'entryToString'), $operations->getArrayCopy())); } @@ -133,7 +157,7 @@ public function operationsProvider() { return array( 'prod, with platform' => array( - array( + 'expected' => array( 'install psr/event-dispatcher 1.0.0', 'update roave/security-advisories from dev-master to dev-master', 'install symfony/deprecation-contracts v2.1.2', @@ -142,11 +166,11 @@ public function operationsProvider() 'install symfony/polyfill-php80 v1.17.1', 'install php >=5.3', ), - false, - true, + 'dev' => false, + 'withPlatform' => true, ), 'prod, no platform' => array( - array( + 'expected' => array( 'install psr/event-dispatcher 1.0.0', 'update roave/security-advisories from dev-master to dev-master', 'install symfony/deprecation-contracts v2.1.2', @@ -154,11 +178,11 @@ public function operationsProvider() 'install symfony/event-dispatcher-contracts v2.1.2', 'install symfony/polyfill-php80 v1.17.1', ), - false, - false, + 'dev' => false, + 'withPlatform' => false, ), 'dev, no platform' => array( - array( + 'expected' => array( 'update phpunit/php-code-coverage from 8.0.2 to 7.0.10', 'update phpunit/php-file-iterator from 3.0.2 to 2.0.2', 'update phpunit/php-text-template from 2.0.1 to 1.2.1', @@ -180,24 +204,46 @@ public function operationsProvider() 'uninstall phpunit/php-invoker 3.0.1', 'uninstall sebastian/code-unit 1.0.3', ), - true, - false, + 'dev' => true, + 'withPlatform' => false, + ), + 'prod, only direct' => array( + 'expected' => array( + 'update roave/security-advisories from dev-master to dev-master', + 'update symfony/event-dispatcher from v2.8.52 to v5.1.2', + ), + 'dev' => false, + 'withPlatform' => false, + 'onlyDirect' => true, + ), + 'dev, only direct' => array( + 'expected' => array( + 'update phpunit/phpunit from 9.2.5 to 8.5.8', + ), + 'dev' => true, + 'withPlatform' => false, + 'onlyDirect' => true, ), ); } - private function prepareGit() + private function prepareGit($onlyLock = false) { $gitDir = __DIR__.'/test-git'; @mkdir($gitDir); chdir($gitDir); + @unlink($gitDir.'/composer.json'); + @unlink($gitDir.'/composer.lock'); + @unlink($gitDir.'/.git/index'); exec('git config init.defaultBranch main'); exec('git init'); exec('git config user.name test'); exec('git config user.email test@example.com'); file_put_contents($gitDir.'/composer.lock', file_get_contents(__DIR__.'/fixtures/base/composer.lock')); - exec('git add composer.lock && git commit -m "init"'); + !$onlyLock && file_put_contents($gitDir.'/composer.json', file_get_contents(__DIR__.'/fixtures/base/composer.json')); + exec('git add composer.* && git commit -m "init"'); file_put_contents($gitDir.'/composer.lock', file_get_contents(__DIR__.'/fixtures/target/composer.lock')); + !$onlyLock && file_put_contents($gitDir.'/composer.json', file_get_contents(__DIR__.'/fixtures/target/composer.json')); } private function entryToString(DiffEntry $entry)