Add install-path and type to installedVersions.php and installed.php, add method to get installed packages by type
Issue https://github.com/composer/composer/issues/9648pull/9699/head
parent
31cc102850
commit
b6c9d34125
|
@ -24,10 +24,15 @@ use Composer\Semver\VersionParser;
|
|||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
private static $installed;
|
||||
private static $installed = array();
|
||||
private static $canGetVendors;
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Initialize $installed array
|
||||
*/
|
||||
public static function initializeInstalled() {}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
|
@ -48,6 +53,28 @@ class InstalledVersions
|
|||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
|
@ -274,3 +301,5 @@ class InstalledVersions
|
|||
return $installed;
|
||||
}
|
||||
}
|
||||
|
||||
InstalledVersions::initializeInstalled();
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Composer\Repository;
|
|||
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Package\Loader\ArrayLoader;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\Dumper\ArrayDumper;
|
||||
|
@ -102,11 +103,15 @@ class FilesystemRepository extends WritableArrayRepository
|
|||
$dumper = new ArrayDumper();
|
||||
$fs = new Filesystem();
|
||||
$repoDir = dirname($fs->normalizePath($this->file->getPath()));
|
||||
$installPaths = array();
|
||||
|
||||
foreach ($this->getCanonicalPackages() as $package) {
|
||||
$pkgArray = $dumper->dump($package);
|
||||
$path = $installationManager->getInstallPath($package);
|
||||
$pkgArray['install-path'] = ('' !== $path && null !== $path) ? $fs->findShortestPath($repoDir, $fs->isAbsolutePath($path) ? $path : getcwd() . '/' . $path, true) : null;
|
||||
$installPath = ('' !== $path && null !== $path) ? $fs->findShortestPath($repoDir, $fs->isAbsolutePath($path) ? $path : getcwd() . '/' . $path, true) : null;
|
||||
$installPaths[$package->getName()] = $installPath;
|
||||
|
||||
$pkgArray['install-path'] = $installPath;
|
||||
$data['packages'][] = $pkgArray;
|
||||
|
||||
// only write to the files the names which are really installed, as we receive the full list
|
||||
|
@ -124,24 +129,56 @@ class FilesystemRepository extends WritableArrayRepository
|
|||
$this->file->write($data);
|
||||
|
||||
if ($this->dumpVersions) {
|
||||
$versions = $this->generateInstalledVersions($installationManager, $devMode);
|
||||
$versions = $this->generateInstalledVersions($installationManager, $installPaths, $devMode, $repoDir);
|
||||
|
||||
$fs->filePutContentsIfModified($repoDir.'/installed.php', '<?php return '.var_export($versions, true).';'."\n");
|
||||
$fs->filePutContentsIfModified($repoDir.'/installed.php', '<?php return ' . $this->dumpVersion($versions) . ';'."\n");
|
||||
$installedVersionsClass = file_get_contents(__DIR__.'/../InstalledVersions.php');
|
||||
// while not strictly needed since https://github.com/composer/composer/pull/9635 - we keep this for BC
|
||||
// and overall broader compatibility with people that may not use Composer's ClassLoader. They can
|
||||
// simply include InstalledVersions.php manually and have it working in a basic way.
|
||||
$installedVersionsClass = str_replace('private static $installed;', 'private static $installed = '.var_export($versions, true).';', $installedVersionsClass);
|
||||
$installedVersionsClass = str_replace('public static function initializeInstalled() {}', 'public static function initializeInstalled() {' . PHP_EOL . 'self::$installed = ' . $this->dumpVersion($versions) . ';' . PHP_EOL . '}', $installedVersionsClass);
|
||||
$fs->filePutContentsIfModified($repoDir.'/InstalledVersions.php', $installedVersionsClass);
|
||||
|
||||
\Composer\InstalledVersions::reload($versions);
|
||||
}
|
||||
}
|
||||
|
||||
private function dumpVersion(array $array = array(), $level = 0)
|
||||
{
|
||||
$lines = "array(\n";
|
||||
$level++;
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
$lines .= str_repeat(' ', $level);
|
||||
$lines .= is_int($key) ? $key . ' => ' : '\'' . $key . '\' => ';
|
||||
|
||||
if (is_array($value)) {
|
||||
if (!empty($value)) {
|
||||
$lines .= self::dumpVersion($value, $level);
|
||||
} else {
|
||||
$lines .= "array(),\n";
|
||||
}
|
||||
} elseif (is_null($value)) {
|
||||
$lines .= 'null';
|
||||
$lines .= ",\n";
|
||||
} elseif (is_bool($value)) {
|
||||
$lines .= $value ? 'true' : 'false';
|
||||
$lines .= ",\n";
|
||||
} else {
|
||||
$stringContent = str_replace(array('\\', '\''), array('\\\\', '\\\''), $value);
|
||||
$folder = $key === 'install_path' ? '__DIR__ . DIRECTORY_SEPARATOR . ' : '';
|
||||
$lines .= $folder . "'" . $stringContent . "',\n";
|
||||
}
|
||||
}
|
||||
|
||||
$lines .= str_repeat(' ', $level - 1) . ')' . ($level - 1 == 0 ? '' : ",\n");
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?array
|
||||
*/
|
||||
private function generateInstalledVersions(InstallationManager $installationManager, $devMode)
|
||||
private function generateInstalledVersions(InstallationManager $installationManager, $installPaths, $devMode, $repoDir)
|
||||
{
|
||||
if (!$this->dumpVersions) {
|
||||
return null;
|
||||
|
@ -170,9 +207,19 @@ class FilesystemRepository extends WritableArrayRepository
|
|||
$reference = ($package->getSourceReference() ?: $package->getDistReference()) ?: null;
|
||||
}
|
||||
|
||||
if($package instanceof RootPackageInterface) {
|
||||
$fs = new Filesystem();
|
||||
$to = getcwd();
|
||||
$installPath = $fs->findShortestPath($repoDir, $to, true);
|
||||
} else {
|
||||
$installPath = $installPaths[$package->getName()];
|
||||
}
|
||||
|
||||
$versions['versions'][$package->getName()] = array(
|
||||
'pretty_version' => $package->getPrettyVersion(),
|
||||
'version' => $package->getVersion(),
|
||||
'type' => $package->getType(),
|
||||
'install_path' => $installPath,
|
||||
'aliases' => array(),
|
||||
'reference' => $reference,
|
||||
'dev-requirement' => isset($devPackages[$package->getName()]),
|
||||
|
|
|
@ -17,6 +17,8 @@ use Composer\Semver\VersionParser;
|
|||
|
||||
class InstalledVersionsTest extends TestCase
|
||||
{
|
||||
private $root;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
// disable multiple-ClassLoader-based checks of InstalledVersions by making it seem like no
|
||||
|
@ -33,6 +35,9 @@ class InstalledVersionsTest extends TestCase
|
|||
|
||||
public function setUp()
|
||||
{
|
||||
$this->root = $this->getUniqueTmpDirectory();
|
||||
|
||||
$dir = $this->root;
|
||||
InstalledVersions::reload(require __DIR__.'/Repository/Fixtures/installed.php');
|
||||
}
|
||||
|
||||
|
@ -187,6 +192,8 @@ class InstalledVersionsTest extends TestCase
|
|||
$this->assertSame(array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'type' => 'library',
|
||||
'install_path' => $this->root . DIRECTORY_SEPARATOR . './',
|
||||
'aliases' => array(
|
||||
'1.10.x-dev',
|
||||
),
|
||||
|
@ -198,6 +205,7 @@ class InstalledVersionsTest extends TestCase
|
|||
|
||||
public function testGetRawData()
|
||||
{
|
||||
$dir = $this->root;
|
||||
$this->assertSame(require __DIR__.'/Repository/Fixtures/installed.php', InstalledVersions::getRawData());
|
||||
}
|
||||
|
||||
|
@ -222,4 +230,17 @@ class InstalledVersionsTest extends TestCase
|
|||
array(null, 'c/c'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetInstalledPackagesByType()
|
||||
{
|
||||
$names = array(
|
||||
'__root__',
|
||||
'a/provider',
|
||||
'a/provider2',
|
||||
'b/replacer',
|
||||
'c/c',
|
||||
);
|
||||
|
||||
$this->assertSame($names, \Composer\InstalledVersions::getInstalledPackagesByType('library'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,4 +119,9 @@ class InstallationManagerMock extends InstallationManager
|
|||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
public function getInstalledPackagesByType()
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ use Composer\Json\JsonFile;
|
|||
|
||||
class FilesystemRepositoryTest extends TestCase
|
||||
{
|
||||
private $root;
|
||||
|
||||
public function testRepositoryRead()
|
||||
{
|
||||
$json = $this->createJsonFileMock();
|
||||
|
@ -121,6 +123,9 @@ class FilesystemRepositoryTest extends TestCase
|
|||
public function testRepositoryWritesInstalledPhp()
|
||||
{
|
||||
$dir = $this->getUniqueTmpDirectory();
|
||||
$this->root = $dir;
|
||||
chdir($dir);
|
||||
|
||||
$json = new JsonFile($dir.'/installed.json');
|
||||
|
||||
$rootPackage = $this->getPackage('__root__', 'dev-master', 'Composer\Package\RootPackage');
|
||||
|
|
|
@ -14,6 +14,9 @@ return array(
|
|||
'root' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'type' => 'library',
|
||||
// @phpstan-ignore-next-line
|
||||
'install_path' => $dir . DIRECTORY_SEPARATOR . './',
|
||||
'aliases' => array(
|
||||
'1.10.x-dev',
|
||||
),
|
||||
|
@ -25,6 +28,9 @@ return array(
|
|||
'__root__' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'type' => 'library',
|
||||
// @phpstan-ignore-next-line
|
||||
'install_path' => $dir . DIRECTORY_SEPARATOR . './',
|
||||
'aliases' => array(
|
||||
'1.10.x-dev',
|
||||
),
|
||||
|
@ -34,6 +40,9 @@ return array(
|
|||
'a/provider' => array(
|
||||
'pretty_version' => '1.1',
|
||||
'version' => '1.1.0.0',
|
||||
'type' => 'library',
|
||||
// @phpstan-ignore-next-line
|
||||
'install_path' => $dir . DIRECTORY_SEPARATOR . '/foo/bar/vendor/woop/woop',
|
||||
'aliases' => array(),
|
||||
'reference' => 'distref-as-no-source',
|
||||
'dev-requirement' => false,
|
||||
|
@ -41,6 +50,9 @@ return array(
|
|||
'a/provider2' => array(
|
||||
'pretty_version' => '1.2',
|
||||
'version' => '1.2.0.0',
|
||||
'type' => 'library',
|
||||
// @phpstan-ignore-next-line
|
||||
'install_path' => $dir . DIRECTORY_SEPARATOR . '/foo/bar/vendor/woop/woop',
|
||||
'aliases' => array(
|
||||
'1.4',
|
||||
),
|
||||
|
@ -50,6 +62,9 @@ return array(
|
|||
'b/replacer' => array(
|
||||
'pretty_version' => '2.2',
|
||||
'version' => '2.2.0.0',
|
||||
'type' => 'library',
|
||||
// @phpstan-ignore-next-line
|
||||
'install_path' => $dir . DIRECTORY_SEPARATOR . '/foo/bar/vendor/woop/woop',
|
||||
'aliases' => array(),
|
||||
'reference' => null,
|
||||
'dev-requirement' => false,
|
||||
|
@ -57,6 +72,9 @@ return array(
|
|||
'c/c' => array(
|
||||
'pretty_version' => '3.0',
|
||||
'version' => '3.0.0.0',
|
||||
'type' => 'library',
|
||||
// @phpstan-ignore-next-line
|
||||
'install_path' => $dir . DIRECTORY_SEPARATOR . '/foo/bar/vendor/woop/woop',
|
||||
'aliases' => array(),
|
||||
'reference' => null,
|
||||
'dev-requirement' => true,
|
||||
|
|
Loading…
Reference in New Issue