diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 63715afae..fc5940b91 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -299,6 +299,12 @@ EOT } elseif (null !== $packageFilter && !str_contains($packageFilter, '*')) { [$package, $versions] = $this->getPackage($installedRepo, $repos, $packageFilter, $input->getArgument('version')); + if (isset($package) && $input->getOption('direct')) { + if (!in_array($package->getName(), $this->getRootRequires(), true)) { + throw new \InvalidArgumentException('Package "' . $package->getName() . '" is installed but not a direct dependent of the root package.'); + } + } + if (!isset($package)) { $options = $input->getOptions(); $hint = ''; diff --git a/tests/Composer/Test/Command/ShowCommandTest.php b/tests/Composer/Test/Command/ShowCommandTest.php index bbafb3d6d..acab3ccc9 100644 --- a/tests/Composer/Test/Command/ShowCommandTest.php +++ b/tests/Composer/Test/Command/ShowCommandTest.php @@ -18,6 +18,7 @@ use Composer\Pcre\Regex; use Composer\Repository\PlatformRepository; use Composer\Test\TestCase; use DateTimeImmutable; +use InvalidArgumentException; class ShowCommandTest extends TestCase { @@ -298,6 +299,23 @@ Transitive dependencies not required in composer.json: vendor/package 1.1.0 ! 1.2.0", trim($appTester->getDisplay(true))); } + public function testShowDirectWithNameOnlyShowsDirectDependents(): void + { + self::expectException(InvalidArgumentException::class); + self::expectExceptionMessage('Package "vendor/package" is installed but not a direct dependent of the root package.'); + + $this->initTempComposer([ + 'repositories' => [], + ]); + + $this->createInstalledJson([ + self::getPackage('vendor/package', '1.0.0'), + ]); + + $appTester = $this->getApplicationTester(); + $appTester->run(['command' => 'show', '--direct' => true, 'package' => 'vendor/package']); + } + public function testShowPlatformOnlyShowsPlatformPackages(): void { $this->initTempComposer([