Merge pull request #8803 from Seldaek/installed-php
Add a Composer\Versions class which is available in all projects at runtime to query installed packages/versionspull/8824/head
commit
547a942251
|
@ -277,6 +277,7 @@ EOF;
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$classMap['Composer\\InstalledVersions'] = "\$vendorDir . '/composer/InstalledVersions.php',\n";
|
||||||
ksort($classMap);
|
ksort($classMap);
|
||||||
foreach ($classMap as $class => $code) {
|
foreach ($classMap as $class => $code) {
|
||||||
$classmapFile .= ' '.var_export($class, true).' => '.$code;
|
$classmapFile .= ' '.var_export($class, true).' => '.$code;
|
||||||
|
@ -296,33 +297,33 @@ EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->filePutContentsIfModified($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
$filesystem->filePutContentsIfModified($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
||||||
$this->filePutContentsIfModified($targetDir.'/autoload_psr4.php', $psr4File);
|
$filesystem->filePutContentsIfModified($targetDir.'/autoload_psr4.php', $psr4File);
|
||||||
$this->filePutContentsIfModified($targetDir.'/autoload_classmap.php', $classmapFile);
|
$filesystem->filePutContentsIfModified($targetDir.'/autoload_classmap.php', $classmapFile);
|
||||||
$includePathFilePath = $targetDir.'/include_paths.php';
|
$includePathFilePath = $targetDir.'/include_paths.php';
|
||||||
if ($includePathFileContents = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
if ($includePathFileContents = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
||||||
$this->filePutContentsIfModified($includePathFilePath, $includePathFileContents);
|
$filesystem->filePutContentsIfModified($includePathFilePath, $includePathFileContents);
|
||||||
} elseif (file_exists($includePathFilePath)) {
|
} elseif (file_exists($includePathFilePath)) {
|
||||||
unlink($includePathFilePath);
|
unlink($includePathFilePath);
|
||||||
}
|
}
|
||||||
$includeFilesFilePath = $targetDir.'/autoload_files.php';
|
$includeFilesFilePath = $targetDir.'/autoload_files.php';
|
||||||
if ($includeFilesFileContents = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
if ($includeFilesFileContents = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
||||||
$this->filePutContentsIfModified($includeFilesFilePath, $includeFilesFileContents);
|
$filesystem->filePutContentsIfModified($includeFilesFilePath, $includeFilesFileContents);
|
||||||
} elseif (file_exists($includeFilesFilePath)) {
|
} elseif (file_exists($includeFilesFilePath)) {
|
||||||
unlink($includeFilesFilePath);
|
unlink($includeFilesFilePath);
|
||||||
}
|
}
|
||||||
$this->filePutContentsIfModified($targetDir.'/autoload_static.php', $this->getStaticFile($suffix, $targetDir, $vendorPath, $basePath, $staticPhpVersion));
|
$filesystem->filePutContentsIfModified($targetDir.'/autoload_static.php', $this->getStaticFile($suffix, $targetDir, $vendorPath, $basePath, $staticPhpVersion));
|
||||||
$checkPlatform = $config->get('platform-check');
|
$checkPlatform = $config->get('platform-check');
|
||||||
if ($checkPlatform) {
|
if ($checkPlatform) {
|
||||||
$this->filePutContentsIfModified($targetDir.'/platform_check.php', $this->getPlatformCheck($packageMap));
|
$filesystem->filePutContentsIfModified($targetDir.'/platform_check.php', $this->getPlatformCheck($packageMap));
|
||||||
} elseif (file_exists($targetDir.'/platform_check.php')) {
|
} elseif (file_exists($targetDir.'/platform_check.php')) {
|
||||||
unlink($targetDir.'/platform_check.php');
|
unlink($targetDir.'/platform_check.php');
|
||||||
}
|
}
|
||||||
$this->filePutContentsIfModified($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
|
$filesystem->filePutContentsIfModified($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
|
||||||
$this->filePutContentsIfModified($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion, $checkPlatform));
|
$filesystem->filePutContentsIfModified($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion, $checkPlatform));
|
||||||
|
|
||||||
$this->safeCopy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
|
$filesystem->safeCopy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
|
||||||
$this->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE');
|
$filesystem->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE');
|
||||||
|
|
||||||
if ($this->runScripts) {
|
if ($this->runScripts) {
|
||||||
$this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, array(), array(
|
$this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, array(), array(
|
||||||
|
@ -333,16 +334,6 @@ EOF;
|
||||||
return count($classMap);
|
return count($classMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function filePutContentsIfModified($path, $content)
|
|
||||||
{
|
|
||||||
$currentContent = @file_get_contents($path);
|
|
||||||
if (!$currentContent || ($currentContent != $content)) {
|
|
||||||
return file_put_contents($path, $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist, $namespaceFilter, $autoloadType, array $classMap, array &$ambiguousClasses, array &$scannedFiles)
|
private function addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist, $namespaceFilter, $autoloadType, array $classMap, array &$ambiguousClasses, array &$scannedFiles)
|
||||||
{
|
{
|
||||||
foreach ($this->generateClassMap($dir, $blacklist, $namespaceFilter, $autoloadType, true, $scannedFiles) as $class => $path) {
|
foreach ($this->generateClassMap($dir, $blacklist, $namespaceFilter, $autoloadType, true, $scannedFiles) as $class => $path) {
|
||||||
|
@ -1133,51 +1124,4 @@ INITIALIZER;
|
||||||
|
|
||||||
return $sortedPackageMap;
|
return $sortedPackageMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy file using stream_copy_to_stream to work around https://bugs.php.net/bug.php?id=6463
|
|
||||||
*
|
|
||||||
* @param string $source
|
|
||||||
* @param string $target
|
|
||||||
*/
|
|
||||||
protected function safeCopy($source, $target)
|
|
||||||
{
|
|
||||||
if (!file_exists($target) || !file_exists($source) || !$this->filesAreEqual($source, $target)) {
|
|
||||||
$source = fopen($source, 'r');
|
|
||||||
$target = fopen($target, 'w+');
|
|
||||||
|
|
||||||
stream_copy_to_stream($source, $target);
|
|
||||||
fclose($source);
|
|
||||||
fclose($target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* compare 2 files
|
|
||||||
* https://stackoverflow.com/questions/3060125/can-i-use-file-get-contents-to-compare-two-files
|
|
||||||
*/
|
|
||||||
private function filesAreEqual($a, $b)
|
|
||||||
{
|
|
||||||
// Check if filesize is different
|
|
||||||
if (filesize($a) !== filesize($b)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if content is different
|
|
||||||
$ah = fopen($a, 'rb');
|
|
||||||
$bh = fopen($b, 'rb');
|
|
||||||
|
|
||||||
$result = true;
|
|
||||||
while (!feof($ah)) {
|
|
||||||
if (fread($ah, 8192) != fread($bh, 8192)) {
|
|
||||||
$result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose($ah);
|
|
||||||
fclose($bh);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,8 @@ class Compiler
|
||||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_files.php'));
|
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_files.php'));
|
||||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_real.php'));
|
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_real.php'));
|
||||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_static.php'));
|
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_static.php'));
|
||||||
|
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/installed.php'));
|
||||||
|
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/InstalledVersions.php'));
|
||||||
if (file_exists(__DIR__.'/../../vendor/composer/platform_check.php')) {
|
if (file_exists(__DIR__.'/../../vendor/composer/platform_check.php')) {
|
||||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/platform_check.php'));
|
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/platform_check.php'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,17 @@ class Composer
|
||||||
const RELEASE_DATE = '@release_date@';
|
const RELEASE_DATE = '@release_date@';
|
||||||
const SOURCE_VERSION = '2.0-dev+source';
|
const SOURCE_VERSION = '2.0-dev+source';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version number of the internal composer-runtime-api package
|
||||||
|
*
|
||||||
|
* This is used to version features available to projects at runtime
|
||||||
|
* like the platform-check file, the Composer\InstalledVersions class
|
||||||
|
* and possibly others in the future.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const RUNTIME_API_VERSION = '2.0.0';
|
||||||
|
|
||||||
public static function getVersion()
|
public static function getVersion()
|
||||||
{
|
{
|
||||||
// no replacement done, this must be a source checkout
|
// no replacement done, this must be a source checkout
|
||||||
|
|
|
@ -261,9 +261,9 @@ class Transaction
|
||||||
|
|
||||||
// is this a plugin or a dependency of a plugin?
|
// is this a plugin or a dependency of a plugin?
|
||||||
if ($isPlugin || count(array_intersect($package->getNames(), $pluginRequires))) {
|
if ($isPlugin || count(array_intersect($package->getNames(), $pluginRequires))) {
|
||||||
// get the package's requires, but filter out any platform requirements or 'composer-plugin-api'
|
// get the package's requires, but filter out any platform requirements
|
||||||
$requires = array_filter(array_keys($package->getRequires()), function ($req) {
|
$requires = array_filter(array_keys($package->getRequires()), function ($req) {
|
||||||
return $req !== 'composer-plugin-api' && !preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $req);
|
return !preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $req);
|
||||||
});
|
});
|
||||||
|
|
||||||
// is this a plugin with no meaningful dependencies?
|
// is this a plugin with no meaningful dependencies?
|
||||||
|
|
|
@ -17,6 +17,7 @@ use Composer\Json\JsonFile;
|
||||||
use Composer\IO\IOInterface;
|
use Composer\IO\IOInterface;
|
||||||
use Composer\Package\Archiver;
|
use Composer\Package\Archiver;
|
||||||
use Composer\Package\Version\VersionGuesser;
|
use Composer\Package\Version\VersionGuesser;
|
||||||
|
use Composer\Package\RootPackageInterface;
|
||||||
use Composer\Repository\RepositoryManager;
|
use Composer\Repository\RepositoryManager;
|
||||||
use Composer\Repository\RepositoryFactory;
|
use Composer\Repository\RepositoryFactory;
|
||||||
use Composer\Repository\WritableRepositoryInterface;
|
use Composer\Repository\WritableRepositoryInterface;
|
||||||
|
@ -344,9 +345,6 @@ class Factory
|
||||||
$rm = RepositoryFactory::manager($io, $config, $httpDownloader, $dispatcher);
|
$rm = RepositoryFactory::manager($io, $config, $httpDownloader, $dispatcher);
|
||||||
$composer->setRepositoryManager($rm);
|
$composer->setRepositoryManager($rm);
|
||||||
|
|
||||||
// load local repository
|
|
||||||
$this->addLocalRepository($io, $rm, $vendorDir);
|
|
||||||
|
|
||||||
// force-set the version of the global package if not defined as
|
// force-set the version of the global package if not defined as
|
||||||
// guessing it adds no value and only takes time
|
// guessing it adds no value and only takes time
|
||||||
if (!$fullLoad && !isset($localConfig['version'])) {
|
if (!$fullLoad && !isset($localConfig['version'])) {
|
||||||
|
@ -360,6 +358,9 @@ class Factory
|
||||||
$package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd);
|
$package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd);
|
||||||
$composer->setPackage($package);
|
$composer->setPackage($package);
|
||||||
|
|
||||||
|
// load local repository
|
||||||
|
$this->addLocalRepository($io, $rm, $vendorDir, $package);
|
||||||
|
|
||||||
// initialize installation manager
|
// initialize installation manager
|
||||||
$im = $this->createInstallationManager($loop, $io, $dispatcher);
|
$im = $this->createInstallationManager($loop, $io, $dispatcher);
|
||||||
$composer->setInstallationManager($im);
|
$composer->setInstallationManager($im);
|
||||||
|
@ -431,9 +432,9 @@ class Factory
|
||||||
* @param Repository\RepositoryManager $rm
|
* @param Repository\RepositoryManager $rm
|
||||||
* @param string $vendorDir
|
* @param string $vendorDir
|
||||||
*/
|
*/
|
||||||
protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir)
|
protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir, RootPackageInterface $rootPackage)
|
||||||
{
|
{
|
||||||
$rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed.json', null, $io)));
|
$rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed.json', null, $io), true, $rootPackage));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Composer;
|
||||||
|
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied in every Composer installed project and available to all
|
||||||
|
*
|
||||||
|
* To require it's presence, you can require `composer-runtime-api ^2.0`
|
||||||
|
*/
|
||||||
|
class InstalledVersions
|
||||||
|
{
|
||||||
|
private static $installed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackages()
|
||||||
|
{
|
||||||
|
return array_keys(self::$installed['versions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package is installed
|
||||||
|
*
|
||||||
|
* This also returns true if the package name is provided or replaced by another package
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isInstalled($packageName)
|
||||||
|
{
|
||||||
|
return isset(self::$installed['versions'][$packageName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package satisfies a version constraint
|
||||||
|
*
|
||||||
|
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||||
|
*
|
||||||
|
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||||
|
*
|
||||||
|
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||||
|
* @param string $packageName
|
||||||
|
* @param ?string $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||||
|
{
|
||||||
|
$constraint = $parser->parseConstraints($constraint);
|
||||||
|
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||||
|
|
||||||
|
return $provided->matches($constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||||
|
*
|
||||||
|
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||||
|
* whether a given version of a package is installed, and not just whether it exists
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string Version constraint usable with composer/semver
|
||||||
|
*/
|
||||||
|
public static function getVersionRanges($packageName)
|
||||||
|
{
|
||||||
|
if (!isset(self::$installed['versions'][$packageName])) {
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$ranges = array();
|
||||||
|
if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
$ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' || ', $ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getVersion($packageName)
|
||||||
|
{
|
||||||
|
if (!isset(self::$installed['versions'][$packageName])) {
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset(self::$installed['versions'][$packageName]['version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$installed['versions'][$packageName]['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getPrettyVersion($packageName)
|
||||||
|
{
|
||||||
|
if (!isset(self::$installed['versions'][$packageName])) {
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||||
|
*/
|
||||||
|
public static function getReference($packageName)
|
||||||
|
{
|
||||||
|
if (!isset(self::$installed['versions'][$packageName])) {
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset(self::$installed['versions'][$packageName]['reference'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$installed['versions'][$packageName]['reference'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}
|
||||||
|
*/
|
||||||
|
public static function getRootPackage()
|
||||||
|
{
|
||||||
|
return self::$installed['root'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw installed.php data for custom implementations
|
||||||
|
*
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}, versions: list<string, array{pretty_version: ?string, version: ?string, aliases: ?string[], reference: ?string, replaced: ?string[], provided: ?string[]}>}
|
||||||
|
*/
|
||||||
|
public static function getRawData()
|
||||||
|
{
|
||||||
|
return self::$installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets you reload the static array from another file
|
||||||
|
*
|
||||||
|
* This is only useful for complex integrations in which a project needs to use
|
||||||
|
* this class but then also needs to execute another project's autoloader in process,
|
||||||
|
* and wants to ensure both projects have access to their version of installed.php.
|
||||||
|
*
|
||||||
|
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||||
|
* the data it needs from this class, then call reload() with
|
||||||
|
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||||
|
* the project in which it runs can then also use this class safely, without
|
||||||
|
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||||
|
*
|
||||||
|
* @param array[] $data A vendor/composer/installed.php data set
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}, versions: list<string, array{pretty_version: ?string, version: ?string, aliases: ?string[], reference: ?string, replaced: ?string[], provided: ?string[]}>} $data
|
||||||
|
*/
|
||||||
|
public static function reload($data)
|
||||||
|
{
|
||||||
|
self::$installed = $data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -284,6 +284,11 @@ class InstallationManager
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do a last write so that we write the repository even if nothing changed
|
||||||
|
// as that can trigger an update of some files like InstalledVersions.php if
|
||||||
|
// running a new composer version
|
||||||
|
$repo->write($devMode, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,6 +25,11 @@ interface PluginInterface
|
||||||
/**
|
/**
|
||||||
* Version number of the internal composer-plugin-api package
|
* Version number of the internal composer-plugin-api package
|
||||||
*
|
*
|
||||||
|
* This is used to denote the API version of Plugin specific
|
||||||
|
* features, but is also bumped to a new major if Composer
|
||||||
|
* includes a major break in internal APIs which are susceptible
|
||||||
|
* to be used by plugins.
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const PLUGIN_API_VERSION = '2.0.0';
|
const PLUGIN_API_VERSION = '2.0.0';
|
||||||
|
|
|
@ -134,8 +134,8 @@ class PluginManager
|
||||||
$currentPluginApiVersion = $this->getPluginApiVersion();
|
$currentPluginApiVersion = $this->getPluginApiVersion();
|
||||||
$currentPluginApiConstraint = new Constraint('==', $this->versionParser->normalize($currentPluginApiVersion));
|
$currentPluginApiConstraint = new Constraint('==', $this->versionParser->normalize($currentPluginApiVersion));
|
||||||
|
|
||||||
if ($requiresComposer->getPrettyString() === '1.0.0' && $this->getPluginApiVersion() === '1.0.0') {
|
if ($requiresComposer->getPrettyString() === $this->getPluginApiVersion()) {
|
||||||
$this->io->writeError('<warning>The "' . $package->getName() . '" plugin requires composer-plugin-api 1.0.0, this *WILL* break in the future and it should be fixed ASAP (require ^1.0 for example).</warning>');
|
$this->io->writeError('<warning>The "' . $package->getName() . '" plugin requires composer-plugin-api '.$this->getPluginApiVersion().', this *WILL* break in the future and it should be fixed ASAP (require ^'.$this->getPluginApiVersion().' instead for example).</warning>');
|
||||||
} elseif (!$requiresComposer->matches($currentPluginApiConstraint)) {
|
} elseif (!$requiresComposer->matches($currentPluginApiConstraint)) {
|
||||||
$this->io->writeError('<warning>The "' . $package->getName() . '" plugin was skipped because it requires a Plugin API version ("' . $requiresComposer->getPrettyString() . '") that does not match your Composer installation ("' . $currentPluginApiVersion . '"). You may need to run composer update with the "--no-plugins" option.</warning>');
|
$this->io->writeError('<warning>The "' . $package->getName() . '" plugin was skipped because it requires a Plugin API version ("' . $requiresComposer->getPrettyString() . '") that does not match your Composer installation ("' . $currentPluginApiVersion . '"). You may need to run composer update with the "--no-plugins" option.</warning>');
|
||||||
|
|
||||||
|
|
|
@ -502,7 +502,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
{
|
{
|
||||||
if (!$this->hasPartialPackages() || !isset($this->partialPackagesByName[$name])) {
|
if (!$this->hasPartialPackages() || !isset($this->partialPackagesByName[$name])) {
|
||||||
// skip platform packages, root package and composer-plugin-api
|
// skip platform packages, root package and composer-plugin-api
|
||||||
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
|
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +672,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
|
|
||||||
$realName = preg_replace('{~dev$}', '', $name);
|
$realName = preg_replace('{~dev$}', '', $name);
|
||||||
// skip platform packages, root package and composer-plugin-api
|
// skip platform packages, root package and composer-plugin-api
|
||||||
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $realName) || '__root__' === $realName || 'composer-plugin-api' === $realName) {
|
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $realName) || '__root__' === $realName) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ namespace Composer\Repository;
|
||||||
|
|
||||||
use Composer\Json\JsonFile;
|
use Composer\Json\JsonFile;
|
||||||
use Composer\Package\Loader\ArrayLoader;
|
use Composer\Package\Loader\ArrayLoader;
|
||||||
|
use Composer\Package\RootPackageInterface;
|
||||||
|
use Composer\Package\AliasPackage;
|
||||||
use Composer\Package\Dumper\ArrayDumper;
|
use Composer\Package\Dumper\ArrayDumper;
|
||||||
use Composer\Installer\InstallationManager;
|
use Composer\Installer\InstallationManager;
|
||||||
use Composer\Util\Filesystem;
|
use Composer\Util\Filesystem;
|
||||||
|
@ -27,16 +29,25 @@ use Composer\Util\Filesystem;
|
||||||
class FilesystemRepository extends WritableArrayRepository
|
class FilesystemRepository extends WritableArrayRepository
|
||||||
{
|
{
|
||||||
private $file;
|
private $file;
|
||||||
|
private $dumpVersions;
|
||||||
|
private $rootPackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes filesystem repository.
|
* Initializes filesystem repository.
|
||||||
*
|
*
|
||||||
* @param JsonFile $repositoryFile repository json file
|
* @param JsonFile $repositoryFile repository json file
|
||||||
|
* @param bool $dumpVersions
|
||||||
|
* @param ?RootPackageInterface $rootPackage Must be provided if $dumpVersions is true
|
||||||
*/
|
*/
|
||||||
public function __construct(JsonFile $repositoryFile)
|
public function __construct(JsonFile $repositoryFile, $dumpVersions = false, RootPackageInterface $rootPackage = null)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->file = $repositoryFile;
|
$this->file = $repositoryFile;
|
||||||
|
$this->dumpVersions = $dumpVersions;
|
||||||
|
$this->rootPackage = $rootPackage;
|
||||||
|
if ($dumpVersions && !$rootPackage) {
|
||||||
|
throw new \InvalidArgumentException('Expected a root package instance if $dumpVersions is true');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,5 +116,82 @@ class FilesystemRepository extends WritableArrayRepository
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->file->write($data);
|
$this->file->write($data);
|
||||||
|
|
||||||
|
if ($this->dumpVersions) {
|
||||||
|
$versions = array('versions' => array());
|
||||||
|
$packages = $this->getPackages();
|
||||||
|
$packages[] = $rootPackage = $this->rootPackage;
|
||||||
|
while ($rootPackage instanceof AliasPackage) {
|
||||||
|
$rootPackage = $rootPackage->getAliasOf();
|
||||||
|
$packages[] = $rootPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add real installed packages
|
||||||
|
foreach ($packages as $package) {
|
||||||
|
if ($package instanceof AliasPackage) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reference = null;
|
||||||
|
if ($package->getInstallationSource()) {
|
||||||
|
$reference = $package->getInstallationSource() === 'source' ? $package->getSourceReference() : $package->getDistReference();
|
||||||
|
}
|
||||||
|
if (null === $reference) {
|
||||||
|
$reference = ($package->getSourceReference() ?: $package->getDistReference()) ?: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$versions['versions'][$package->getName()] = array(
|
||||||
|
'pretty_version' => $package->getPrettyVersion(),
|
||||||
|
'version' => $package->getVersion(),
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => $reference,
|
||||||
|
);
|
||||||
|
if ($package instanceof RootPackageInterface) {
|
||||||
|
$versions['root'] = $versions['versions'][$package->getName()];
|
||||||
|
$versions['root']['name'] = $package->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add provided/replaced packages
|
||||||
|
foreach ($packages as $package) {
|
||||||
|
foreach ($package->getReplaces() as $replace) {
|
||||||
|
$replaced = $replace->getPrettyConstraint();
|
||||||
|
if ($replaced === 'self.version') {
|
||||||
|
$replaced = $package->getPrettyVersion();
|
||||||
|
}
|
||||||
|
if (!isset($versions['versions'][$replace->getTarget()]['replaced']) || !in_array($replaced, $versions['versions'][$replace->getTarget()]['replaced'], true)) {
|
||||||
|
$versions['versions'][$replace->getTarget()]['replaced'][] = $replaced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($package->getProvides() as $provide) {
|
||||||
|
$provided = $provide->getPrettyConstraint();
|
||||||
|
if ($provided === 'self.version') {
|
||||||
|
$provided = $package->getPrettyVersion();
|
||||||
|
}
|
||||||
|
if (!isset($versions['versions'][$provide->getTarget()]['provided']) || !in_array($provided, $versions['versions'][$provide->getTarget()]['provided'], true)) {
|
||||||
|
$versions['versions'][$provide->getTarget()]['provided'][] = $provided;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add aliases
|
||||||
|
foreach ($packages as $package) {
|
||||||
|
if (!$package instanceof AliasPackage) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$versions['versions'][$package->getName()]['aliases'][] = $package->getPrettyVersion();
|
||||||
|
if ($package instanceof RootPackageInterface) {
|
||||||
|
$versions['root']['aliases'][] = $package->getPrettyVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($versions['versions']);
|
||||||
|
ksort($versions);
|
||||||
|
|
||||||
|
$fs->filePutContentsIfModified($repoDir.'/installed.php', '<?php return '.var_export($versions, true).';'."\n");
|
||||||
|
$installedVersionsClass = file_get_contents(__DIR__.'/../InstalledVersions.php');
|
||||||
|
$installedVersionsClass = str_replace('private static $installed;', 'private static $installed = '.var_export($versions, true).';', $installedVersionsClass);
|
||||||
|
$fs->filePutContentsIfModified($repoDir.'/InstalledVersions.php', $installedVersionsClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ use Composer\Util\ProcessExecutor;
|
||||||
use Composer\Util\Silencer;
|
use Composer\Util\Silencer;
|
||||||
use Composer\Util\Platform;
|
use Composer\Util\Platform;
|
||||||
use Composer\XdebugHandler\XdebugHandler;
|
use Composer\XdebugHandler\XdebugHandler;
|
||||||
|
use Composer\Composer;
|
||||||
use Symfony\Component\Process\ExecutableFinder;
|
use Symfony\Component\Process\ExecutableFinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +28,7 @@ use Symfony\Component\Process\ExecutableFinder;
|
||||||
*/
|
*/
|
||||||
class PlatformRepository extends ArrayRepository
|
class PlatformRepository extends ArrayRepository
|
||||||
{
|
{
|
||||||
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-plugin-api)$}iD';
|
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-(?:plugin|runtime)-api)$}iD';
|
||||||
|
|
||||||
private $versionParser;
|
private $versionParser;
|
||||||
|
|
||||||
|
@ -79,6 +80,12 @@ class PlatformRepository extends ArrayRepository
|
||||||
$composerPluginApi->setDescription('The Composer Plugin API');
|
$composerPluginApi->setDescription('The Composer Plugin API');
|
||||||
$this->addPackage($composerPluginApi);
|
$this->addPackage($composerPluginApi);
|
||||||
|
|
||||||
|
$prettyVersion = Composer::RUNTIME_API_VERSION;
|
||||||
|
$version = $this->versionParser->normalize($prettyVersion);
|
||||||
|
$composerRuntimeApi = new CompletePackage('composer-runtime-api', $version, $prettyVersion);
|
||||||
|
$composerRuntimeApi->setDescription('The Composer Runtime API');
|
||||||
|
$this->addPackage($composerRuntimeApi);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$prettyVersion = PHP_VERSION;
|
$prettyVersion = PHP_VERSION;
|
||||||
$version = $this->versionParser->normalize($prettyVersion);
|
$version = $this->versionParser->normalize($prettyVersion);
|
||||||
|
|
|
@ -313,7 +313,7 @@ class Filesystem
|
||||||
|
|
||||||
if (!function_exists('proc_open')) {
|
if (!function_exists('proc_open')) {
|
||||||
$this->copyThenRemove($source, $target);
|
$this->copyThenRemove($source, $target);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,4 +721,61 @@ class Filesystem
|
||||||
|
|
||||||
return $this->rmdir($junction);
|
return $this->rmdir($junction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function filePutContentsIfModified($path, $content)
|
||||||
|
{
|
||||||
|
$currentContent = @file_get_contents($path);
|
||||||
|
if (!$currentContent || ($currentContent != $content)) {
|
||||||
|
return file_put_contents($path, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy file using stream_copy_to_stream to work around https://bugs.php.net/bug.php?id=6463
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target
|
||||||
|
*/
|
||||||
|
public function safeCopy($source, $target)
|
||||||
|
{
|
||||||
|
if (!file_exists($target) || !file_exists($source) || !$this->filesAreEqual($source, $target)) {
|
||||||
|
$source = fopen($source, 'r');
|
||||||
|
$target = fopen($target, 'w+');
|
||||||
|
|
||||||
|
stream_copy_to_stream($source, $target);
|
||||||
|
fclose($source);
|
||||||
|
fclose($target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* compare 2 files
|
||||||
|
* https://stackoverflow.com/questions/3060125/can-i-use-file-get-contents-to-compare-two-files
|
||||||
|
*/
|
||||||
|
private function filesAreEqual($a, $b)
|
||||||
|
{
|
||||||
|
// Check if filesize is different
|
||||||
|
if (filesize($a) !== filesize($b)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if content is different
|
||||||
|
$ah = fopen($a, 'rb');
|
||||||
|
$bh = fopen($b, 'rb');
|
||||||
|
|
||||||
|
$result = true;
|
||||||
|
while (!feof($ah)) {
|
||||||
|
if (fread($ah, 8192) != fread($bh, 8192)) {
|
||||||
|
$result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($ah);
|
||||||
|
fclose($bh);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -452,6 +452,7 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'B\\C\\C' => $this->vendorDir.'/b/b/src/C/C.php',
|
'B\\C\\C' => $this->vendorDir.'/b/b/src/C/C.php',
|
||||||
|
'Composer\\InstalledVersions' => $this->vendorDir . '/composer/InstalledVersions.php',
|
||||||
),
|
),
|
||||||
include $this->vendorDir.'/composer/autoload_classmap.php'
|
include $this->vendorDir.'/composer/autoload_classmap.php'
|
||||||
);
|
);
|
||||||
|
@ -599,7 +600,9 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_8');
|
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_8');
|
||||||
$this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated.");
|
$this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated.");
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(),
|
array(
|
||||||
|
'Composer\\InstalledVersions' => $this->vendorDir.'/composer/InstalledVersions.php',
|
||||||
|
),
|
||||||
include $this->vendorDir.'/composer/autoload_classmap.php'
|
include $this->vendorDir.'/composer/autoload_classmap.php'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -636,6 +639,7 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
\$baseDir = dirname(\$vendorDir);
|
\$baseDir = dirname(\$vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'Composer\\\\InstalledVersions' => \$vendorDir . '/composer/InstalledVersions.php',
|
||||||
'psr0_match' => \$baseDir . '/psr0/psr0/match.php',
|
'psr0_match' => \$baseDir . '/psr0/psr0/match.php',
|
||||||
'psr4\\\\match' => \$baseDir . '/psr4/match.php',
|
'psr4\\\\match' => \$baseDir . '/psr4/match.php',
|
||||||
);
|
);
|
||||||
|
@ -677,6 +681,7 @@ EOF;
|
||||||
'ClassMapBar' => $this->vendorDir.'/b/b/src/b.php',
|
'ClassMapBar' => $this->vendorDir.'/b/b/src/b.php',
|
||||||
'ClassMapBaz' => $this->vendorDir.'/b/b/lib/c.php',
|
'ClassMapBaz' => $this->vendorDir.'/b/b/lib/c.php',
|
||||||
'ClassMapFoo' => $this->vendorDir.'/a/a/src/a.php',
|
'ClassMapFoo' => $this->vendorDir.'/a/a/src/a.php',
|
||||||
|
'Composer\\InstalledVersions' => $this->vendorDir.'/composer/InstalledVersions.php',
|
||||||
),
|
),
|
||||||
include $this->vendorDir.'/composer/autoload_classmap.php'
|
include $this->vendorDir.'/composer/autoload_classmap.php'
|
||||||
);
|
);
|
||||||
|
@ -717,6 +722,7 @@ EOF;
|
||||||
'ClassMapBar' => $this->vendorDir.'/a/a/target/lib/b.php',
|
'ClassMapBar' => $this->vendorDir.'/a/a/target/lib/b.php',
|
||||||
'ClassMapBaz' => $this->vendorDir.'/b/b/src/c.php',
|
'ClassMapBaz' => $this->vendorDir.'/b/b/src/c.php',
|
||||||
'ClassMapFoo' => $this->vendorDir.'/a/a/target/src/a.php',
|
'ClassMapFoo' => $this->vendorDir.'/a/a/target/src/a.php',
|
||||||
|
'Composer\\InstalledVersions' => $this->vendorDir.'/composer/InstalledVersions.php',
|
||||||
),
|
),
|
||||||
include $this->vendorDir.'/composer/autoload_classmap.php'
|
include $this->vendorDir.'/composer/autoload_classmap.php'
|
||||||
);
|
);
|
||||||
|
@ -758,6 +764,7 @@ EOF;
|
||||||
'ClassMapBar' => $this->vendorDir.'/b/b/test.php',
|
'ClassMapBar' => $this->vendorDir.'/b/b/test.php',
|
||||||
'ClassMapBaz' => $this->vendorDir.'/c/c/foo/test.php',
|
'ClassMapBaz' => $this->vendorDir.'/c/c/foo/test.php',
|
||||||
'ClassMapFoo' => $this->vendorDir.'/a/a/src/a.php',
|
'ClassMapFoo' => $this->vendorDir.'/a/a/src/a.php',
|
||||||
|
'Composer\\InstalledVersions' => $this->vendorDir.'/composer/InstalledVersions.php',
|
||||||
),
|
),
|
||||||
include $this->vendorDir.'/composer/autoload_classmap.php'
|
include $this->vendorDir.'/composer/autoload_classmap.php'
|
||||||
);
|
);
|
||||||
|
@ -805,6 +812,7 @@ EOF;
|
||||||
'ClassMapBar' => $this->vendorDir.'/b/b/ClassMapBar.php',
|
'ClassMapBar' => $this->vendorDir.'/b/b/ClassMapBar.php',
|
||||||
'ClassMapBaz' => $this->vendorDir.'/c/c/foo/ClassMapBaz.php',
|
'ClassMapBaz' => $this->vendorDir.'/c/c/foo/ClassMapBaz.php',
|
||||||
'ClassMapFoo' => $this->vendorDir.'/a/a/src/ClassMapFoo.php',
|
'ClassMapFoo' => $this->vendorDir.'/a/a/src/ClassMapFoo.php',
|
||||||
|
'Composer\\InstalledVersions' => $this->vendorDir.'/composer/InstalledVersions.php',
|
||||||
),
|
),
|
||||||
include $this->vendorDir.'/composer/autoload_classmap.php'
|
include $this->vendorDir.'/composer/autoload_classmap.php'
|
||||||
);
|
);
|
||||||
|
@ -852,7 +860,8 @@ EOF;
|
||||||
$this->assertFileContentEquals(__DIR__.'/Fixtures/autoload_static_functions.php', $this->vendorDir.'/composer/autoload_static.php');
|
$this->assertFileContentEquals(__DIR__.'/Fixtures/autoload_static_functions.php', $this->vendorDir.'/composer/autoload_static.php');
|
||||||
$this->assertFileContentEquals(__DIR__.'/Fixtures/autoload_files_functions.php', $this->vendorDir.'/composer/autoload_files.php');
|
$this->assertFileContentEquals(__DIR__.'/Fixtures/autoload_files_functions.php', $this->vendorDir.'/composer/autoload_files.php');
|
||||||
|
|
||||||
include $this->vendorDir . '/autoload.php';
|
$loader = require $this->vendorDir . '/autoload.php';
|
||||||
|
$loader->unregister();
|
||||||
$this->assertTrue(function_exists('testFilesAutoloadGeneration1'));
|
$this->assertTrue(function_exists('testFilesAutoloadGeneration1'));
|
||||||
$this->assertTrue(function_exists('testFilesAutoloadGeneration2'));
|
$this->assertTrue(function_exists('testFilesAutoloadGeneration2'));
|
||||||
$this->assertTrue(function_exists('testFilesAutoloadGeneration3'));
|
$this->assertTrue(function_exists('testFilesAutoloadGeneration3'));
|
||||||
|
@ -988,7 +997,8 @@ EOF;
|
||||||
$this->assertFileContentEquals(__DIR__ . '/Fixtures/autoload_real_files_by_dependency.php', $this->vendorDir . '/composer/autoload_real.php');
|
$this->assertFileContentEquals(__DIR__ . '/Fixtures/autoload_real_files_by_dependency.php', $this->vendorDir . '/composer/autoload_real.php');
|
||||||
$this->assertFileContentEquals(__DIR__ . '/Fixtures/autoload_static_files_by_dependency.php', $this->vendorDir . '/composer/autoload_static.php');
|
$this->assertFileContentEquals(__DIR__ . '/Fixtures/autoload_static_files_by_dependency.php', $this->vendorDir . '/composer/autoload_static.php');
|
||||||
|
|
||||||
require $this->vendorDir . '/autoload.php';
|
$loader = require $this->vendorDir . '/autoload.php';
|
||||||
|
$loader->unregister();
|
||||||
|
|
||||||
$this->assertTrue(function_exists('testFilesAutoloadOrderByDependency1'));
|
$this->assertTrue(function_exists('testFilesAutoloadOrderByDependency1'));
|
||||||
$this->assertTrue(function_exists('testFilesAutoloadOrderByDependency2'));
|
$this->assertTrue(function_exists('testFilesAutoloadOrderByDependency2'));
|
||||||
|
@ -1087,6 +1097,7 @@ EOF;
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'A\\\\B\\\\C' => \$baseDir . '/lib/A/B/C.php',
|
'A\\\\B\\\\C' => \$baseDir . '/lib/A/B/C.php',
|
||||||
|
'Composer\\\\InstalledVersions' => \$vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Foo\\\\Bar' => \$baseDir . '/src/classes.php',
|
'Foo\\\\Bar' => \$baseDir . '/src/classes.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1155,7 +1166,8 @@ EOF;
|
||||||
|
|
||||||
$oldIncludePath = get_include_path();
|
$oldIncludePath = get_include_path();
|
||||||
|
|
||||||
require $this->vendorDir."/autoload.php";
|
$loader = require $this->vendorDir."/autoload.php";
|
||||||
|
$loader->unregister();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$this->vendorDir."/a/a/lib".PATH_SEPARATOR.$oldIncludePath,
|
$this->vendorDir."/a/a/lib".PATH_SEPARATOR.$oldIncludePath,
|
||||||
|
@ -1183,7 +1195,8 @@ EOF;
|
||||||
|
|
||||||
$oldIncludePath = get_include_path();
|
$oldIncludePath = get_include_path();
|
||||||
|
|
||||||
require $this->vendorDir."/autoload.php";
|
$loader = require $this->vendorDir."/autoload.php";
|
||||||
|
$loader->unregister();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$this->workingDir."/lib".PATH_SEPARATOR.$this->workingDir."/src".PATH_SEPARATOR.$this->vendorDir."/a/a/lib".PATH_SEPARATOR.$oldIncludePath,
|
$this->workingDir."/lib".PATH_SEPARATOR.$this->workingDir."/src".PATH_SEPARATOR.$this->vendorDir."/a/a/lib".PATH_SEPARATOR.$oldIncludePath,
|
||||||
|
@ -1356,6 +1369,7 @@ $baseDir = dirname($vendorDir).'/working-dir';
|
||||||
return array(
|
return array(
|
||||||
'Bar\\Bar' => $vendorDir . '/b/b/classmaps/classes.php',
|
'Bar\\Bar' => $vendorDir . '/b/b/classmaps/classes.php',
|
||||||
'Bar\\Foo' => $vendorDir . '/b/b/lib/Bar/Foo.php',
|
'Bar\\Foo' => $vendorDir . '/b/b/lib/Bar/Foo.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Foo\\Bar' => $baseDir . '/src/Foo/Bar.php',
|
'Foo\\Bar' => $baseDir . '/src/Foo/Bar.php',
|
||||||
'Foo\\Foo' => $baseDir . '/classmap/classes.php',
|
'Foo\\Foo' => $baseDir . '/classmap/classes.php',
|
||||||
);
|
);
|
||||||
|
@ -1434,6 +1448,7 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir).'/working-dir';
|
$baseDir = dirname($vendorDir).'/working-dir';
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Foo\\Bar' => $baseDir . '/../src/Foo/Bar.php',
|
'Foo\\Bar' => $baseDir . '/../src/Foo/Bar.php',
|
||||||
'Foo\\Foo' => $baseDir . '/../classmap/classes.php',
|
'Foo\\Foo' => $baseDir . '/../classmap/classes.php',
|
||||||
);
|
);
|
||||||
|
@ -1503,6 +1518,7 @@ $baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'Classmap\\Foo' => $baseDir . '/class.php',
|
'Classmap\\Foo' => $baseDir . '/class.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Foo\\Bar' => $baseDir . '/Foo/Bar.php',
|
'Foo\\Bar' => $baseDir . '/Foo/Bar.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ $baseDir = dirname($vendorDir);
|
||||||
return array(
|
return array(
|
||||||
'Acme\\Cake\\ClassMapBar' => $baseDir . '/src-cake/ClassMapBar.php',
|
'Acme\\Cake\\ClassMapBar' => $baseDir . '/src-cake/ClassMapBar.php',
|
||||||
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Lala\\ClassMapMain' => $baseDir . '/src/Lala/ClassMapMain.php',
|
'Lala\\ClassMapMain' => $baseDir . '/src/Lala/ClassMapMain.php',
|
||||||
'Lala\\Test\\ClassMapMainTest' => $baseDir . '/src/Lala/Test/ClassMapMainTest.php',
|
'Lala\\Test\\ClassMapMainTest' => $baseDir . '/src/Lala/Test/ClassMapMainTest.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,4 +7,5 @@ $baseDir = dirname(dirname($vendorDir));
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,5 +7,6 @@ $baseDir = $vendorDir;
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'ClassMapFoo' => $vendorDir . '/composersrc/foo.php',
|
'ClassMapFoo' => $vendorDir . '/composersrc/foo.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Main\\Foo' => $vendorDir . '/src/Main/Foo.php',
|
'Main\\Foo' => $vendorDir . '/src/Main/Foo.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,4 +9,5 @@ return array(
|
||||||
'ClassMapBar' => $vendorDir . '/b/b/src/b.php',
|
'ClassMapBar' => $vendorDir . '/b/b/src/b.php',
|
||||||
'ClassMapBaz' => $vendorDir . '/b/b/lib/c.php',
|
'ClassMapBaz' => $vendorDir . '/b/b/lib/c.php',
|
||||||
'ClassMapFoo' => $vendorDir . '/a/a/src/a.php',
|
'ClassMapFoo' => $vendorDir . '/a/a/src/a.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,4 +9,5 @@ return array(
|
||||||
'ClassMapBar' => $vendorDir . '/b/b/test.php',
|
'ClassMapBar' => $vendorDir . '/b/b/test.php',
|
||||||
'ClassMapBaz' => $vendorDir . '/c/c/foo/test.php',
|
'ClassMapBaz' => $vendorDir . '/c/c/foo/test.php',
|
||||||
'ClassMapFoo' => $vendorDir . '/a/a/src/a.php',
|
'ClassMapFoo' => $vendorDir . '/a/a/src/a.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,4 +8,5 @@ $baseDir = dirname($vendorDir);
|
||||||
return array(
|
return array(
|
||||||
'ClassMapBar' => $baseDir . '/lib/rootbar.php',
|
'ClassMapBar' => $baseDir . '/lib/rootbar.php',
|
||||||
'ClassMapFoo' => $baseDir . '/src/rootfoo.php',
|
'ClassMapFoo' => $baseDir . '/src/rootfoo.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Main\\ClassMain' => $baseDir . '/src/Main/ClassMain.php',
|
'Main\\ClassMain' => $baseDir . '/src/Main/ClassMain.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,4 +9,5 @@ return array(
|
||||||
'ClassMapBar' => $vendorDir . '/b/b/ClassMapBar.php',
|
'ClassMapBar' => $vendorDir . '/b/b/ClassMapBar.php',
|
||||||
'ClassMapBaz' => $vendorDir . '/c/c/foo/ClassMapBaz.php',
|
'ClassMapBaz' => $vendorDir . '/c/c/foo/ClassMapBaz.php',
|
||||||
'ClassMapFoo' => $vendorDir . '/a/a/src/ClassMapFoo.php',
|
'ClassMapFoo' => $vendorDir . '/a/a/src/ClassMapFoo.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,5 +8,6 @@ $baseDir = dirname($vendorDir);
|
||||||
return array(
|
return array(
|
||||||
'A' => $vendorDir . '/a/a/src/A.php',
|
'A' => $vendorDir . '/a/a/src/A.php',
|
||||||
'C' => $vendorDir . '/c/c/src/C.php',
|
'C' => $vendorDir . '/c/c/src/C.php',
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'D' => $vendorDir . '/d/d/src/D.php',
|
'D' => $vendorDir . '/d/d/src/D.php',
|
||||||
);
|
);
|
||||||
|
|
|
@ -75,12 +75,17 @@ class ComposerStaticInitPhar
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
{
|
{
|
||||||
return \Closure::bind(function () use ($loader) {
|
return \Closure::bind(function () use ($loader) {
|
||||||
$loader->prefixLengthsPsr4 = ComposerStaticInitPhar::$prefixLengthsPsr4;
|
$loader->prefixLengthsPsr4 = ComposerStaticInitPhar::$prefixLengthsPsr4;
|
||||||
$loader->prefixDirsPsr4 = ComposerStaticInitPhar::$prefixDirsPsr4;
|
$loader->prefixDirsPsr4 = ComposerStaticInitPhar::$prefixDirsPsr4;
|
||||||
$loader->prefixesPsr0 = ComposerStaticInitPhar::$prefixesPsr0;
|
$loader->prefixesPsr0 = ComposerStaticInitPhar::$prefixesPsr0;
|
||||||
|
$loader->classMap = ComposerStaticInitPhar::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,14 @@ class ComposerStaticInitFilesAutoloadOrder
|
||||||
'334307692417e52db5a08c3271700a7e' => __DIR__ . '/../..' . '/root2.php',
|
'334307692417e52db5a08c3271700a7e' => __DIR__ . '/../..' . '/root2.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
{
|
{
|
||||||
return \Closure::bind(function () use ($loader) {
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->classMap = ComposerStaticInitFilesAutoloadOrder::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,14 @@ class ComposerStaticInitFilesAutoload
|
||||||
'61b776fd0ee84fb7d7d958ae46118ded' => __DIR__ . '/../..' . '/root.php',
|
'61b776fd0ee84fb7d7d958ae46118ded' => __DIR__ . '/../..' . '/root.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
{
|
{
|
||||||
return \Closure::bind(function () use ($loader) {
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->classMap = ComposerStaticInitFilesAutoload::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,14 @@ class ComposerStaticInitFilesAutoload
|
||||||
'61b776fd0ee84fb7d7d958ae46118ded' => __DIR__ . '/../..' . '/root.php',
|
'61b776fd0ee84fb7d7d958ae46118ded' => __DIR__ . '/../..' . '/root.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
{
|
{
|
||||||
return \Closure::bind(function () use ($loader) {
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->classMap = ComposerStaticInitFilesAutoload::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,14 @@ namespace Composer\Autoload;
|
||||||
|
|
||||||
class ComposerStaticInitFilesAutoload
|
class ComposerStaticInitFilesAutoload
|
||||||
{
|
{
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
{
|
{
|
||||||
return \Closure::bind(function () use ($loader) {
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->classMap = ComposerStaticInitFilesAutoload::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,15 @@ class ComposerStaticInitIncludePath
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
{
|
{
|
||||||
return \Closure::bind(function () use ($loader) {
|
return \Closure::bind(function () use ($loader) {
|
||||||
$loader->prefixesPsr0 = ComposerStaticInitIncludePath::$prefixesPsr0;
|
$loader->prefixesPsr0 = ComposerStaticInitIncludePath::$prefixesPsr0;
|
||||||
|
$loader->classMap = ComposerStaticInitIncludePath::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class ComposerStaticInitTargetDir
|
||||||
public static $classMap = array (
|
public static $classMap = array (
|
||||||
'ClassMapBar' => __DIR__ . '/../..' . '/lib/rootbar.php',
|
'ClassMapBar' => __DIR__ . '/../..' . '/lib/rootbar.php',
|
||||||
'ClassMapFoo' => __DIR__ . '/../..' . '/src/rootfoo.php',
|
'ClassMapFoo' => __DIR__ . '/../..' . '/src/rootfoo.php',
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Test;
|
||||||
|
|
||||||
|
use Composer\Test\TestCase;
|
||||||
|
use Composer\InstalledVersions;
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
|
||||||
|
class InstalledVersionsTest extends TestCase
|
||||||
|
{
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
InstalledVersions::reload(require __DIR__.'/Repository/Fixtures/installed.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetInstalledPackages()
|
||||||
|
{
|
||||||
|
$names = array(
|
||||||
|
'__root__',
|
||||||
|
'a/provider',
|
||||||
|
'a/provider2',
|
||||||
|
'b/replacer',
|
||||||
|
'c/c',
|
||||||
|
'foo/impl',
|
||||||
|
'foo/impl2',
|
||||||
|
'foo/replaced',
|
||||||
|
);
|
||||||
|
$this->assertSame($names, InstalledVersions::getInstalledPackages());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider isInstalledProvider
|
||||||
|
*/
|
||||||
|
public function testIsInstalled($expected, $name, $constraint = null)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, InstalledVersions::isInstalled($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isInstalledProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(true, 'foo/impl'),
|
||||||
|
array(true, 'foo/replaced'),
|
||||||
|
array(true, 'c/c'),
|
||||||
|
array(true, '__root__'),
|
||||||
|
array(true, 'b/replacer'),
|
||||||
|
array(false, 'not/there'),
|
||||||
|
array(false, 'not/there', '^1.0'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider satisfiesProvider
|
||||||
|
*/
|
||||||
|
public function testSatisfies($expected, $name, $constraint)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, InstalledVersions::satisfies(new VersionParser, $name, $constraint));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function satisfiesProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(true, 'foo/impl', '1.5'),
|
||||||
|
array(true, 'foo/impl', '1.2'),
|
||||||
|
array(true, 'foo/impl', '^1.0'),
|
||||||
|
array(true, 'foo/impl', '^3 || ^2'),
|
||||||
|
array(false, 'foo/impl', '^3'),
|
||||||
|
|
||||||
|
array(true, 'foo/replaced', '3.5'),
|
||||||
|
array(true, 'foo/replaced', '^3.2'),
|
||||||
|
array(false, 'foo/replaced', '4.0'),
|
||||||
|
|
||||||
|
array(true, 'c/c', '3.0.0'),
|
||||||
|
array(true, 'c/c', '^3'),
|
||||||
|
array(false, 'c/c', '^3.1'),
|
||||||
|
|
||||||
|
array(true, '__root__', 'dev-master'),
|
||||||
|
array(true, '__root__', '^1.10'),
|
||||||
|
array(false, '__root__', '^2'),
|
||||||
|
|
||||||
|
array(true, 'b/replacer', '^2.1'),
|
||||||
|
array(false, 'b/replacer', '^2.3'),
|
||||||
|
|
||||||
|
array(true, 'a/provider2', '^1.2'),
|
||||||
|
array(true, 'a/provider2', '^1.4'),
|
||||||
|
array(false, 'a/provider2', '^1.5'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getVersionRangesProvider
|
||||||
|
*/
|
||||||
|
public function testGetVersionRanges($expected, $name)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, InstalledVersions::getVersionRanges($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getVersionRangesProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('dev-master || 1.10.x-dev', '__root__'),
|
||||||
|
array('^1.1 || 1.2 || 1.4 || 2.0', 'foo/impl'),
|
||||||
|
array('2.2 || 2.0', 'foo/impl2'),
|
||||||
|
array('^3.0', 'foo/replaced'),
|
||||||
|
array('1.1', 'a/provider'),
|
||||||
|
array('1.2 || 1.4', 'a/provider2'),
|
||||||
|
array('2.2', 'b/replacer'),
|
||||||
|
array('3.0', 'c/c'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getVersionProvider
|
||||||
|
*/
|
||||||
|
public function testGetVersion($expected, $name)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, InstalledVersions::getVersion($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getVersionProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('dev-master', '__root__'),
|
||||||
|
array(null, 'foo/impl'),
|
||||||
|
array(null, 'foo/impl2'),
|
||||||
|
array(null, 'foo/replaced'),
|
||||||
|
array('1.1.0.0', 'a/provider'),
|
||||||
|
array('1.2.0.0', 'a/provider2'),
|
||||||
|
array('2.2.0.0', 'b/replacer'),
|
||||||
|
array('3.0.0.0', 'c/c'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getPrettyVersionProvider
|
||||||
|
*/
|
||||||
|
public function testGetPrettyVersion($expected, $name)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, InstalledVersions::getPrettyVersion($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPrettyVersionProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('dev-master', '__root__'),
|
||||||
|
array(null, 'foo/impl'),
|
||||||
|
array(null, 'foo/impl2'),
|
||||||
|
array(null, 'foo/replaced'),
|
||||||
|
array('1.1', 'a/provider'),
|
||||||
|
array('1.2', 'a/provider2'),
|
||||||
|
array('2.2', 'b/replacer'),
|
||||||
|
array('3.0', 'c/c'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetVersionOutOfBounds()
|
||||||
|
{
|
||||||
|
$this->setExpectedException('OutOfBoundsException');
|
||||||
|
InstalledVersions::getVersion('not/installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetRootPackage()
|
||||||
|
{
|
||||||
|
$this->assertSame(array(
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'aliases' => array(
|
||||||
|
'1.10.x-dev',
|
||||||
|
),
|
||||||
|
'reference' => 'sourceref-by-default',
|
||||||
|
'name' => '__root__',
|
||||||
|
), InstalledVersions::getRootPackage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetRawData()
|
||||||
|
{
|
||||||
|
$this->assertSame(require __DIR__.'/Repository/Fixtures/installed.php', InstalledVersions::getRawData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getReferenceProvider
|
||||||
|
*/
|
||||||
|
public function testGetReference($expected, $name)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, InstalledVersions::getReference($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getReferenceProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('sourceref-by-default', '__root__'),
|
||||||
|
array(null, 'foo/impl'),
|
||||||
|
array(null, 'foo/impl2'),
|
||||||
|
array(null, 'foo/replaced'),
|
||||||
|
array('distref-as-no-source', 'a/provider'),
|
||||||
|
array('distref-as-installed-from-dist', 'a/provider2'),
|
||||||
|
array(null, 'b/replacer'),
|
||||||
|
array(null, 'c/c'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ use Composer\Config;
|
||||||
use Composer\Factory;
|
use Composer\Factory;
|
||||||
use Composer\Repository\RepositoryManager;
|
use Composer\Repository\RepositoryManager;
|
||||||
use Composer\Repository\WritableRepositoryInterface;
|
use Composer\Repository\WritableRepositoryInterface;
|
||||||
|
use Composer\Package\RootPackageInterface;
|
||||||
use Composer\Installer;
|
use Composer\Installer;
|
||||||
use Composer\EventDispatcher\EventDispatcher;
|
use Composer\EventDispatcher\EventDispatcher;
|
||||||
use Composer\IO\IOInterface;
|
use Composer\IO\IOInterface;
|
||||||
|
@ -37,7 +38,7 @@ class FactoryMock extends Factory
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir)
|
protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir, RootPackageInterface $rootPackage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace Composer\Test\Repository;
|
||||||
|
|
||||||
use Composer\Repository\FilesystemRepository;
|
use Composer\Repository\FilesystemRepository;
|
||||||
use Composer\Test\TestCase;
|
use Composer\Test\TestCase;
|
||||||
|
use Composer\Json\JsonFile;
|
||||||
|
|
||||||
class FilesystemRepositoryTest extends TestCase
|
class FilesystemRepositoryTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -113,6 +114,50 @@ class FilesystemRepositoryTest extends TestCase
|
||||||
$repository->write(true, $im);
|
$repository->write(true, $im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRepositoryWritesInstalledPhp()
|
||||||
|
{
|
||||||
|
$dir = $this->getUniqueTmpDirectory();
|
||||||
|
$json = new JsonFile($dir.'/installed.json');
|
||||||
|
|
||||||
|
$rootPackage = $this->getPackage('__root__', 'dev-master', 'Composer\Package\RootPackage');
|
||||||
|
$rootPackage->setSourceReference('sourceref-by-default');
|
||||||
|
$rootPackage->setDistReference('distref');
|
||||||
|
$this->configureLinks($rootPackage, array('provide' => array('foo/impl' => '2.0')));
|
||||||
|
$rootPackage = $this->getAliasPackage($rootPackage, '1.10.x-dev');
|
||||||
|
|
||||||
|
$repository = new FilesystemRepository($json, true, $rootPackage);
|
||||||
|
$pkg = $this->getPackage('a/provider', '1.1');
|
||||||
|
$this->configureLinks($pkg, array('provide' => array('foo/impl' => '^1.1', 'foo/impl2' => '2.0')));
|
||||||
|
$pkg->setDistReference('distref-as-no-source');
|
||||||
|
$repository->addPackage($pkg);
|
||||||
|
|
||||||
|
$pkg = $this->getPackage('a/provider2', '1.2');
|
||||||
|
$this->configureLinks($pkg, array('provide' => array('foo/impl' => 'self.version', 'foo/impl2' => '2.0')));
|
||||||
|
$pkg->setSourceReference('sourceref');
|
||||||
|
$pkg->setDistReference('distref-as-installed-from-dist');
|
||||||
|
$pkg->setInstallationSource('dist');
|
||||||
|
$repository->addPackage($pkg);
|
||||||
|
|
||||||
|
$repository->addPackage($this->getAliasPackage($pkg, '1.4'));
|
||||||
|
|
||||||
|
$pkg = $this->getPackage('b/replacer', '2.2');
|
||||||
|
$this->configureLinks($pkg, array('replace' => array('foo/impl2' => 'self.version', 'foo/replaced' => '^3.0')));
|
||||||
|
$repository->addPackage($pkg);
|
||||||
|
|
||||||
|
$pkg = $this->getPackage('c/c', '3.0');
|
||||||
|
$repository->addPackage($pkg);
|
||||||
|
|
||||||
|
$im = $this->getMockBuilder('Composer\Installer\InstallationManager')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$im->expects($this->any())
|
||||||
|
->method('getInstallPath')
|
||||||
|
->will($this->returnValue('/foo/bar/vendor/woop/woop'));
|
||||||
|
|
||||||
|
$repository->write(true, $im);
|
||||||
|
$this->assertSame(require __DIR__.'/Fixtures/installed.php', require $dir.'/installed.php');
|
||||||
|
}
|
||||||
|
|
||||||
private function createJsonFileMock()
|
private function createJsonFileMock()
|
||||||
{
|
{
|
||||||
return $this->getMockBuilder('Composer\Json\JsonFile')
|
return $this->getMockBuilder('Composer\Json\JsonFile')
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php return array(
|
||||||
|
'root' => array(
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'aliases' => array(
|
||||||
|
'1.10.x-dev',
|
||||||
|
),
|
||||||
|
'reference' => 'sourceref-by-default',
|
||||||
|
'name' => '__root__',
|
||||||
|
),
|
||||||
|
'versions' => array(
|
||||||
|
'__root__' => array(
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'aliases' => array(
|
||||||
|
'1.10.x-dev',
|
||||||
|
),
|
||||||
|
'reference' => 'sourceref-by-default',
|
||||||
|
),
|
||||||
|
'a/provider' => array(
|
||||||
|
'pretty_version' => '1.1',
|
||||||
|
'version' => '1.1.0.0',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => 'distref-as-no-source',
|
||||||
|
),
|
||||||
|
'a/provider2' => array(
|
||||||
|
'pretty_version' => '1.2',
|
||||||
|
'version' => '1.2.0.0',
|
||||||
|
'aliases' => array(
|
||||||
|
'1.4',
|
||||||
|
),
|
||||||
|
'reference' => 'distref-as-installed-from-dist',
|
||||||
|
),
|
||||||
|
'b/replacer' => array(
|
||||||
|
'pretty_version' => '2.2',
|
||||||
|
'version' => '2.2.0.0',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => NULL,
|
||||||
|
),
|
||||||
|
'c/c' => array(
|
||||||
|
'pretty_version' => '3.0',
|
||||||
|
'version' => '3.0.0.0',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => NULL,
|
||||||
|
),
|
||||||
|
'foo/impl' => array(
|
||||||
|
'provided' => array(
|
||||||
|
'^1.1',
|
||||||
|
'1.2',
|
||||||
|
'1.4',
|
||||||
|
'2.0',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'foo/impl2' => array(
|
||||||
|
'provided' => array(
|
||||||
|
'2.0',
|
||||||
|
),
|
||||||
|
'replaced' => array(
|
||||||
|
'2.2',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'foo/replaced' => array(
|
||||||
|
'replaced' => array(
|
||||||
|
'^3.0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
|
@ -14,11 +14,15 @@ namespace Composer\Test;
|
||||||
|
|
||||||
use Composer\Semver\VersionParser;
|
use Composer\Semver\VersionParser;
|
||||||
use Composer\Package\AliasPackage;
|
use Composer\Package\AliasPackage;
|
||||||
|
use Composer\Package\RootPackageInterface;
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
use Composer\Semver\Constraint\Constraint;
|
use Composer\Semver\Constraint\Constraint;
|
||||||
use Composer\Util\Filesystem;
|
use Composer\Util\Filesystem;
|
||||||
use Composer\Util\Silencer;
|
use Composer\Util\Silencer;
|
||||||
use PHPUnit\Framework\TestCase as BaseTestCase;
|
use PHPUnit\Framework\TestCase as BaseTestCase;
|
||||||
use Symfony\Component\Process\ExecutableFinder;
|
use Symfony\Component\Process\ExecutableFinder;
|
||||||
|
use Composer\Package\Loader\ArrayLoader;
|
||||||
|
use Composer\Package\BasePackage;
|
||||||
|
|
||||||
abstract class TestCase extends BaseTestCase
|
abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
|
@ -73,7 +77,31 @@ abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
$normVersion = self::getVersionParser()->normalize($version);
|
$normVersion = self::getVersionParser()->normalize($version);
|
||||||
|
|
||||||
return new AliasPackage($package, $normVersion, $version);
|
$class = 'Composer\Package\AliasPackage';
|
||||||
|
if ($package instanceof RootPackageInterface) {
|
||||||
|
$class = 'Composer\Package\RootAliasPackage';
|
||||||
|
}
|
||||||
|
|
||||||
|
return new $class($package, $normVersion, $version);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configureLinks(PackageInterface $package, array $config)
|
||||||
|
{
|
||||||
|
$arrayLoader = new ArrayLoader();
|
||||||
|
|
||||||
|
foreach (BasePackage::$supportedLinkTypes as $type => $opts) {
|
||||||
|
if (isset($config[$type])) {
|
||||||
|
$method = 'set'.ucfirst($opts['method']);
|
||||||
|
$package->{$method}(
|
||||||
|
$arrayLoader->parseLinks(
|
||||||
|
$package->getName(),
|
||||||
|
$package->getPrettyVersion(),
|
||||||
|
$opts['description'],
|
||||||
|
$config[$type]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function ensureDirectoryExistsAndClear($directory)
|
protected static function ensureDirectoryExistsAndClear($directory)
|
||||||
|
|
Loading…
Reference in New Issue