diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php
index 78a418a33..cac98e97d 100644
--- a/src/Composer/Command/ShowCommand.php
+++ b/src/Composer/Command/ShowCommand.php
@@ -238,18 +238,12 @@ EOT
return $exitCode;
}
- $this->printMeta($package, $versions, $installedRepo, $latestPackage ?: null);
- $this->printLinks($package, 'requires');
- $this->printLinks($package, 'devRequires', 'requires (dev)');
- if ($package->getSuggests()) {
- $io->write("\nsuggests");
- foreach ($package->getSuggests() as $suggested => $reason) {
- $io->write($suggested . ' ' . $reason . '');
- }
+
+ if ('json' === $format) {
+ $this->printPackageInfoAsJson($package, $versions, $installedRepo, $latestPackage ?: null);
+ } else {
+ $this->printPackageInfo($package, $versions, $installedRepo, $latestPackage ?: null);
}
- $this->printLinks($package, 'provides');
- $this->printLinks($package, 'conflicts');
- $this->printLinks($package, 'replaces');
}
return $exitCode;
@@ -577,12 +571,41 @@ EOT
return array($matchedPackage, $versions);
}
+ /**
+ * Prints package info.
+ *
+ * @param CompletePackageInterface $package
+ * @param array $versions
+ * @param RepositoryInterface $installedRepo
+ * @param PackageInterface|null $latestPackage
+ */
+ protected function printPackageInfo(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null)
+ {
+ $io = $this->getIO();
+
+ $this->printMeta($package, $versions, $installedRepo, $latestPackage ?: null);
+ $this->printLinks($package, 'requires');
+ $this->printLinks($package, 'devRequires', 'requires (dev)');
+
+ if ($package->getSuggests()) {
+ $io->write("\nsuggests");
+ foreach ($package->getSuggests() as $suggested => $reason) {
+ $io->write($suggested . ' ' . $reason . '');
+ }
+ }
+
+ $this->printLinks($package, 'provides');
+ $this->printLinks($package, 'conflicts');
+ $this->printLinks($package, 'replaces');
+ }
+
/**
* Prints package metadata.
*
* @param CompletePackageInterface $package
* @param array $versions
* @param RepositoryInterface $installedRepo
+ * @param PackageInterface|null $latestPackage
*/
protected function printMeta(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null)
{
@@ -724,6 +747,152 @@ EOT
}
}
+ /**
+ * Prints package info in JSON format.
+ *
+ * @param CompletePackageInterface $package
+ * @param array $versions
+ * @param RepositoryInterface $installedRepo
+ * @param PackageInterface|null $latestPackage
+ */
+ protected function printPackageInfoAsJson(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null)
+ {
+ $json = array(
+ 'name' => $package->getPrettyName(),
+ 'description' => $package->getDescription(),
+ 'keywords' => $package->getKeywords() ?: array(),
+ 'type' => $package->getType(),
+ 'homepage' => $package->getHomepage(),
+ 'names' => $package->getNames()
+ );
+
+ $this->appendVersions($json, $versions);
+ $this->appendLicenses($json, $package);
+
+ if ($latestPackage) {
+ $json['latest'] = $latestPackage->getPrettyVersion();
+ } else {
+ $latestPackage = $package;
+ }
+
+ if ($package->getSourceType()) {
+ $json['source'] = array(
+ 'type' => $package->getSourceType(),
+ 'url' => $package->getSourceUrl(),
+ 'reference' => $package->getSourceReference()
+ );
+ }
+
+ if ($package->getDistType()) {
+ $json['dist'] = array(
+ 'type' => $package->getDistType(),
+ 'url' => $package->getDistUrl(),
+ 'reference' => $package->getDistReference()
+ );
+ }
+
+ if ($installedRepo->hasPackage($package)) {
+ $json['path'] = realpath($this->getComposer()->getInstallationManager()->getInstallPath($package));
+ }
+
+ if ($latestPackage->isAbandoned()) {
+ $json['replacement'] = $latestPackage->getReplacementPackage();
+ }
+
+ if ($package->getSuggests()) {
+ $json['suggests'] = $package->getSuggests();
+ }
+
+ if ($package->getSupport()) {
+ $json['support'] = $package->getSupport();
+ }
+
+ $this->appendAutoload($json, $package);
+
+ if ($package->getIncludePaths()) {
+ $json['include_path'] = $package->getIncludePaths();
+ }
+
+ $this->appendLinks($json, $package);
+
+ $this->getIO()->write(JsonFile::encode($json));
+ }
+
+ protected function appendVersions(&$json, array $versions)
+ {
+ uasort($versions, 'version_compare');
+ $versions = array_keys(array_reverse($versions));
+ $json['versions'] = $versions;
+ }
+
+ protected function appendLicenses(&$json, CompletePackageInterface $package)
+ {
+ if ($licenses = $package->getLicense()) {
+ $spdxLicenses = new SpdxLicenses();
+
+ $json['licenses'] = array_map(function ($licenseId) use ($spdxLicenses) {
+ $license = $spdxLicenses->getLicenseByIdentifier($licenseId); // keys: 0 fullname, 1 osi, 2 url
+
+ if (!$license) {
+ return $licenseId;
+ }
+
+ return array(
+ 'name' => $license[0],
+ 'osi' => $licenseId,
+ 'url' => $license[2]
+ );
+ }, $licenses);
+ }
+ }
+
+ protected function appendAutoload(&$json, CompletePackageInterface $package)
+ {
+ if ($package->getAutoload()) {
+ $autoload = array();
+
+ foreach ($package->getAutoload() as $type => $autoloads) {
+ if ($type === 'psr-0' || $type === 'psr-4') {
+ $psr = array();
+
+ foreach ($autoloads as $name => $path) {
+ if (!$path) {
+ $path = '.';
+ }
+
+ $psr[$name ?: '*'] = $path;
+ }
+
+ $autoload[$type] = $psr;
+ } elseif ($type === 'classmap') {
+ $autoload['classmap'] = $autoloads;
+ }
+ }
+
+ $json['autoload'] = $autoload;
+ }
+ }
+
+ protected function appendLinks(&$json, CompletePackageInterface $package)
+ {
+ foreach (array('requires', 'devRequires', 'provides', 'conflicts', 'replaces') as $linkType) {
+ $this->appendLink($json, $package, $linkType);
+ }
+ }
+
+ protected function appendLink(&$json, CompletePackageInterface $package, $linkType)
+ {
+ $links = $package->{'get' . ucfirst($linkType)}();
+
+ if ($links) {
+ $json[$linkType] = array();
+
+ foreach ($links as $link) {
+ $json[$linkType][$link->getTarget()] = $link->getPrettyConstraint();
+ }
+ }
+ }
+
/**
* Init styles for tree
*