Merge pull request #1015 from Seldaek/memory
Reduce memory usage by only loading packages that are actually needed, fixes #456pull/1029/head
commit
01593e0628
|
@ -87,7 +87,7 @@ EOT
|
|||
);
|
||||
}
|
||||
|
||||
public function installProject(IOInterface $io, $packageName, $directory = null, $version = null, $preferSource = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false)
|
||||
public function installProject(IOInterface $io, $packageName, $directory = null, $packageVersion = null, $preferSource = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false)
|
||||
{
|
||||
$dm = $this->createDownloadManager($io);
|
||||
if ($preferSource) {
|
||||
|
@ -105,9 +105,29 @@ EOT
|
|||
throw new \InvalidArgumentException("Invalid repository url given. Has to be a .json file or an http url.");
|
||||
}
|
||||
|
||||
$candidates = $sourceRepo->findPackages($packageName, $version);
|
||||
$candidates = array();
|
||||
$name = strtolower($packageName);
|
||||
|
||||
if ($packageVersion === null) {
|
||||
$sourceRepo->filterPackages(function ($package) use (&$candidates, $name) {
|
||||
if ($package->getName() === $name) {
|
||||
$candidates[] = $package;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$parser = new VersionParser();
|
||||
$version = $parser->normalize($packageVersion);
|
||||
$sourceRepo->filterPackages(function ($package) use (&$candidates, $name, $version) {
|
||||
if ($package->getName() === $name && $version === $package->getVersion()) {
|
||||
$candidates[] = $package;
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!$candidates) {
|
||||
throw new \InvalidArgumentException("Could not find package $packageName" . ($version ? " with version $version." : ''));
|
||||
throw new \InvalidArgumentException("Could not find package $packageName" . ($packageVersion ? " with version $packageVersion." : ''));
|
||||
}
|
||||
|
||||
if (null === $directory) {
|
||||
|
@ -122,6 +142,7 @@ EOT
|
|||
$package = $candidate;
|
||||
}
|
||||
}
|
||||
unset($candidates);
|
||||
|
||||
$io->write('<info>Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')</info>', true);
|
||||
|
||||
|
@ -144,6 +165,10 @@ EOT
|
|||
|
||||
putenv('COMPOSER_ROOT_VERSION='.$package->getPrettyVersion());
|
||||
|
||||
// clean up memory
|
||||
unset($dm, $config, $projectInstaller, $sourceRepo, $package);
|
||||
|
||||
// install dependencies of the created project
|
||||
$composer = Factory::create($io);
|
||||
$installer = Installer::create($io, $composer);
|
||||
|
||||
|
|
|
@ -51,69 +51,38 @@ EOT
|
|||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$composer = $this->getComposer();
|
||||
$references = $this->getReferences($input, $output, $composer);
|
||||
|
||||
if ($input->getOption('verbose')) {
|
||||
$this->printReferences($input, $output, $references);
|
||||
} else {
|
||||
$this->printPackages($input, $output, $references);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* finds a list of packages which depend on another package
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @param Composer $composer
|
||||
* @return array
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function getReferences(InputInterface $input, OutputInterface $output, Composer $composer)
|
||||
{
|
||||
$needle = $input->getArgument('package');
|
||||
|
||||
$references = array();
|
||||
$verbose = (bool) $input->getOption('verbose');
|
||||
|
||||
$repos = $composer->getRepositoryManager()->getRepositories();
|
||||
$types = $input->getOption('link-type');
|
||||
|
||||
foreach ($repos as $repository) {
|
||||
foreach ($repository->getPackages() as $package) {
|
||||
$linkTypes = $this->linkTypes;
|
||||
|
||||
$needle = $input->getArgument('package');
|
||||
$verbose = (bool) $input->getOption('verbose');
|
||||
$types = array_map(function ($type) use ($linkTypes) {
|
||||
$type = rtrim($type, 's');
|
||||
if (!isset($linkTypes[$type])) {
|
||||
throw new \InvalidArgumentException('Unexpected link type: '.$type.', valid types: '.implode(', ', array_keys($linkTypes)));
|
||||
}
|
||||
|
||||
return $type;
|
||||
}, $input->getOption('link-type'));
|
||||
|
||||
foreach ($repos as $repo) {
|
||||
$repo->filterPackages(function ($package) use ($needle, $types, $output, $verbose) {
|
||||
static $outputPackages = array();
|
||||
|
||||
foreach ($types as $type) {
|
||||
$type = rtrim($type, 's');
|
||||
if (!isset($this->linkTypes[$type])) {
|
||||
throw new \InvalidArgumentException('Unexpected link type: '.$type.', valid types: '.implode(', ', array_keys($this->linkTypes)));
|
||||
}
|
||||
foreach ($package->{'get'.$this->linkTypes[$type]}() as $link) {
|
||||
if ($link->getTarget() === $needle) {
|
||||
if ($verbose) {
|
||||
$references[] = array($type, $package, $link);
|
||||
} else {
|
||||
$references[$package->getName()] = $package->getPrettyName();
|
||||
$output->writeln($package->getPrettyName() . ' ' . $package->getPrettyVersion() . ' <info>' . $type . '</info> ' . $link->getPrettyConstraint());
|
||||
} elseif (!isset($outputPackages[$package->getName()])) {
|
||||
$output->writeln($package->getPrettyName());
|
||||
$outputPackages[$package->getName()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $references;
|
||||
}
|
||||
|
||||
private function printReferences(InputInterface $input, OutputInterface $output, array $references)
|
||||
{
|
||||
foreach ($references as $ref) {
|
||||
$output->writeln($ref[1]->getPrettyName() . ' ' . $ref[1]->getPrettyVersion() . ' <info>' . $ref[0] . '</info> ' . $ref[2]->getPrettyConstraint());
|
||||
}
|
||||
}
|
||||
|
||||
private function printPackages(InputInterface $input, OutputInterface $output, array $packages)
|
||||
{
|
||||
ksort($packages);
|
||||
foreach ($packages as $package) {
|
||||
$output->writeln($package);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,13 +271,12 @@ EOT
|
|||
}
|
||||
|
||||
$token = strtolower($name);
|
||||
foreach ($this->repos->getPackages() as $package) {
|
||||
if (false === ($pos = strpos($package->getName(), $token))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$packages[] = $package;
|
||||
}
|
||||
$this->repos->filterPackages(function ($package) use ($token, &$packages) {
|
||||
if (false !== strpos($package->getName(), $token)) {
|
||||
$packages[] = $package;
|
||||
}
|
||||
});
|
||||
|
||||
return $packages;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
|||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Composer\Repository\CompositeRepository;
|
||||
use Composer\Repository\PlatformRepository;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\CompletePackageInterface;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Factory;
|
||||
|
||||
|
@ -26,6 +26,11 @@ use Composer\Factory;
|
|||
*/
|
||||
class SearchCommand extends Command
|
||||
{
|
||||
protected $matches;
|
||||
protected $lowMatches;
|
||||
protected $tokens;
|
||||
protected $output;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
|
@ -58,70 +63,63 @@ EOT
|
|||
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
|
||||
}
|
||||
|
||||
$tokens = $input->getArgument('tokens');
|
||||
$packages = array();
|
||||
$this->tokens = $input->getArgument('tokens');
|
||||
$this->output = $output;
|
||||
$repos->filterPackages(array($this, 'processPackage'), 'Composer\Package\CompletePackage');
|
||||
|
||||
$maxPackageLength = 0;
|
||||
foreach ($repos->getPackages() as $package) {
|
||||
if ($package instanceof AliasPackage || isset($packages[$package->getName()])) {
|
||||
foreach ($this->lowMatches as $details) {
|
||||
$output->writeln($details['name'] . '<comment>:</comment> '. $details['description']);
|
||||
}
|
||||
}
|
||||
|
||||
public function processPackage($package)
|
||||
{
|
||||
if ($package instanceof AliasPackage || isset($this->matches[$package->getName()])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->tokens as $token) {
|
||||
if (!$score = $this->matchPackage($package, $token)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
if (!$score = $this->matchPackage($package, $token)) {
|
||||
continue;
|
||||
}
|
||||
if (false !== ($pos = stripos($package->getName(), $token))) {
|
||||
$name = substr($package->getPrettyName(), 0, $pos)
|
||||
. '<highlight>' . substr($package->getPrettyName(), $pos, strlen($token)) . '</highlight>'
|
||||
. substr($package->getPrettyName(), $pos + strlen($token));
|
||||
} else {
|
||||
$name = $package->getPrettyName();
|
||||
}
|
||||
|
||||
if (false !== ($pos = stripos($package->getName(), $token))) {
|
||||
$name = substr($package->getPrettyName(), 0, $pos)
|
||||
. '<highlight>' . substr($package->getPrettyName(), $pos, strlen($token)) . '</highlight>'
|
||||
. substr($package->getPrettyName(), $pos + strlen($token));
|
||||
} else {
|
||||
$name = $package->getPrettyName();
|
||||
}
|
||||
$description = strtok($package->getDescription(), "\r\n");
|
||||
if (false !== ($pos = stripos($description, $token))) {
|
||||
$description = substr($description, 0, $pos)
|
||||
. '<highlight>' . substr($description, $pos, strlen($token)) . '</highlight>'
|
||||
. substr($description, $pos + strlen($token));
|
||||
}
|
||||
|
||||
$description = strtok($package->getDescription(), "\r\n");
|
||||
if (false !== ($pos = stripos($description, $token))) {
|
||||
$description = substr($description, 0, $pos)
|
||||
. '<highlight>' . substr($description, $pos, strlen($token)) . '</highlight>'
|
||||
. substr($description, $pos + strlen($token));
|
||||
}
|
||||
|
||||
$packages[$package->getName()] = array(
|
||||
if ($score >= 3) {
|
||||
$this->output->writeln($name . '<comment>:</comment> '. $description);
|
||||
$this->matches[$package->getName()] = true;
|
||||
} else {
|
||||
$this->lowMatches[$package->getName()] = array(
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'length' => $length = strlen($package->getPrettyName()),
|
||||
'score' => $score,
|
||||
);
|
||||
|
||||
$maxPackageLength = max($maxPackageLength, $length);
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
usort($packages, function ($a, $b) {
|
||||
if ($a['score'] === $b['score']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a['score'] > $b['score'] ? -1 : 1;
|
||||
});
|
||||
|
||||
foreach ($packages as $details) {
|
||||
$extraSpaces = $maxPackageLength - $details['length'];
|
||||
$output->writeln($details['name'] . str_repeat(' ', $extraSpaces) .' <comment>:</comment> '. $details['description']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tries to find a token within the name/keywords/description
|
||||
*
|
||||
* @param PackageInterface $package
|
||||
* @param CompletePackageInterface $package
|
||||
* @param string $token
|
||||
* @return boolean
|
||||
*/
|
||||
private function matchPackage(PackageInterface $package, $token)
|
||||
private function matchPackage(CompletePackageInterface $package, $token)
|
||||
{
|
||||
$score = 0;
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace Composer\Command;
|
|||
|
||||
use Composer\Composer;
|
||||
use Composer\Factory;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\CompletePackageInterface;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
@ -38,9 +39,9 @@ class ShowCommand extends Command
|
|||
->setDefinition(array(
|
||||
new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect'),
|
||||
new InputArgument('version', InputArgument::OPTIONAL, 'Version to inspect'),
|
||||
new InputOption('installed', null, InputOption::VALUE_NONE, 'List installed packages only'),
|
||||
new InputOption('platform', null, InputOption::VALUE_NONE, 'List platform packages only'),
|
||||
new InputOption('self', null, InputOption::VALUE_NONE, 'Show the root package information'),
|
||||
new InputOption('installed', 'i', InputOption::VALUE_NONE, 'List installed packages only'),
|
||||
new InputOption('platform', 'p', InputOption::VALUE_NONE, 'List platform packages only'),
|
||||
new InputOption('self', 's', InputOption::VALUE_NONE, 'Show the root package information'),
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
The show command displays detailed information about a package, or
|
||||
|
@ -77,13 +78,14 @@ EOT
|
|||
// show single package or single version
|
||||
if ($input->getArgument('package') || !empty($package)) {
|
||||
if (empty($package)) {
|
||||
$package = $this->getPackage($input, $output, $installedRepo, $repos);
|
||||
}
|
||||
if (!$package) {
|
||||
throw new \InvalidArgumentException('Package '.$input->getArgument('package').' not found');
|
||||
list($package, $versions) = $this->getPackage($installedRepo, $repos, $input->getArgument('package'), $input->getArgument('version'));
|
||||
|
||||
if (!$package) {
|
||||
throw new \InvalidArgumentException('Package '.$input->getArgument('package').' not found');
|
||||
}
|
||||
}
|
||||
|
||||
$this->printMeta($input, $output, $package, $installedRepo, $repos);
|
||||
$this->printMeta($input, $output, $package, $versions, $installedRepo, $repos);
|
||||
$this->printLinks($input, $output, $package, 'requires');
|
||||
$this->printLinks($input, $output, $package, 'devRequires', 'requires (dev)');
|
||||
if ($package->getSuggests()) {
|
||||
|
@ -101,7 +103,7 @@ EOT
|
|||
|
||||
// list packages
|
||||
$packages = array();
|
||||
foreach ($repos->getPackages() as $package) {
|
||||
$repos->filterPackages(function ($package) use (&$packages, $platformRepo, $installedRepo) {
|
||||
if ($platformRepo->hasPackage($package)) {
|
||||
$type = '<info>platform</info>:';
|
||||
} elseif ($installedRepo->hasPackage($package)) {
|
||||
|
@ -109,13 +111,12 @@ EOT
|
|||
} else {
|
||||
$type = '<comment>available</comment>:';
|
||||
}
|
||||
if (isset($packages[$type][$package->getName()])
|
||||
&& version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '>=')
|
||||
if (!isset($packages[$type][$package->getName()])
|
||||
|| version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')
|
||||
) {
|
||||
continue;
|
||||
$packages[$type][$package->getName()] = $package;
|
||||
}
|
||||
$packages[$type][$package->getName()] = $package;
|
||||
}
|
||||
}, 'Composer\Package\CompletePackage');
|
||||
|
||||
foreach (array('<info>platform</info>:' => true, '<comment>available</comment>:' => false, '<info>installed</info>:' => true) as $type => $showVersion) {
|
||||
if (isset($packages[$type])) {
|
||||
|
@ -132,44 +133,69 @@ EOT
|
|||
/**
|
||||
* finds a package by name and version if provided
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @return PackageInterface
|
||||
* @return array array(CompletePackageInterface, array of versions)
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function getPackage(InputInterface $input, OutputInterface $output, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
||||
protected function getPackage(RepositoryInterface $installedRepo, RepositoryInterface $repos, $name, $version = null)
|
||||
{
|
||||
// we have a name and a version so we can use ::findPackage
|
||||
if ($input->getArgument('version')) {
|
||||
return $repos->findPackage($input->getArgument('package'), $input->getArgument('version'));
|
||||
$name = strtolower($name);
|
||||
if ($version) {
|
||||
$parser = new VersionParser();
|
||||
$version = $parser->normalize($version);
|
||||
}
|
||||
|
||||
// check if we have a local installation so we can grab the right package/version
|
||||
foreach ($installedRepo->getPackages() as $package) {
|
||||
if ($package->getName() === $input->getArgument('package')) {
|
||||
return $package;
|
||||
$match = null;
|
||||
$matches = array();
|
||||
$repos->filterPackages(function ($package) use ($name, $version, &$matches) {
|
||||
if ($package->getName() === $name) {
|
||||
$matches[] = $package;
|
||||
}
|
||||
}, 'Composer\Package\CompletePackage');
|
||||
|
||||
if (null === $version) {
|
||||
// search for a locally installed version
|
||||
foreach ($matches as $package) {
|
||||
if ($installedRepo->hasPackage($package)) {
|
||||
$match = $package;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$match) {
|
||||
// fallback to the highest version
|
||||
foreach ($matches as $package) {
|
||||
if (null === $match || version_compare($package->getVersion(), $match->getVersion(), '>=')) {
|
||||
$match = $package;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// select the specified version
|
||||
foreach ($matches as $package) {
|
||||
if ($package->getVersion() === $version) {
|
||||
$match = $package;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we only have a name, so search for the highest version of the given package
|
||||
$highestVersion = null;
|
||||
foreach ($repos->findPackages($input->getArgument('package')) as $package) {
|
||||
if (null === $highestVersion || version_compare($package->getVersion(), $highestVersion->getVersion(), '>=')) {
|
||||
$highestVersion = $package;
|
||||
}
|
||||
// build versions array
|
||||
$versions = array();
|
||||
foreach ($matches as $package) {
|
||||
$versions[$package->getPrettyVersion()] = $package->getVersion();
|
||||
}
|
||||
|
||||
return $highestVersion;
|
||||
return array($match, $versions);
|
||||
}
|
||||
|
||||
/**
|
||||
* prints package meta data
|
||||
*/
|
||||
protected function printMeta(InputInterface $input, OutputInterface $output, PackageInterface $package, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
||||
protected function printMeta(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
||||
{
|
||||
$output->writeln('<info>name</info> : ' . $package->getPrettyName());
|
||||
$output->writeln('<info>descrip.</info> : ' . $package->getDescription());
|
||||
$output->writeln('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
|
||||
$this->printVersions($input, $output, $package, $installedRepo, $repos);
|
||||
$this->printVersions($input, $output, $package, $versions, $installedRepo, $repos);
|
||||
$output->writeln('<info>type</info> : ' . $package->getType());
|
||||
$output->writeln('<info>license</info> : ' . implode(', ', $package->getLicense()));
|
||||
$output->writeln('<info>source</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
|
||||
|
@ -206,7 +232,7 @@ EOT
|
|||
/**
|
||||
* prints all available versions of this package and highlights the installed one if any
|
||||
*/
|
||||
protected function printVersions(InputInterface $input, OutputInterface $output, PackageInterface $package, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
||||
protected function printVersions(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
||||
{
|
||||
if ($input->getArgument('version')) {
|
||||
$output->writeln('<info>version</info> : ' . $package->getPrettyVersion());
|
||||
|
@ -214,14 +240,7 @@ EOT
|
|||
return;
|
||||
}
|
||||
|
||||
$versions = array();
|
||||
|
||||
foreach ($repos->findPackages($package->getName()) as $version) {
|
||||
$versions[$version->getPrettyVersion()] = $version->getVersion();
|
||||
}
|
||||
|
||||
uasort($versions, 'version_compare');
|
||||
|
||||
$versions = implode(', ', array_keys(array_reverse($versions)));
|
||||
|
||||
// highlight installed version
|
||||
|
@ -237,7 +256,7 @@ EOT
|
|||
*
|
||||
* @param string $linkType
|
||||
*/
|
||||
protected function printLinks(InputInterface $input, OutputInterface $output, PackageInterface $package, $linkType, $title = null)
|
||||
protected function printLinks(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, $linkType, $title = null)
|
||||
{
|
||||
$title = $title ?: $linkType;
|
||||
if ($links = $package->{'get'.ucfirst($linkType)}()) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Package\Locker;
|
||||
use Composer\Repository\RepositoryManager;
|
||||
use Composer\Installer\InstallationManager;
|
||||
|
@ -27,7 +27,7 @@ class Composer
|
|||
const VERSION = '@package_version@';
|
||||
|
||||
/**
|
||||
* @var Package\PackageInterface
|
||||
* @var Package\RootPackageInterface
|
||||
*/
|
||||
private $package;
|
||||
|
||||
|
@ -57,16 +57,16 @@ class Composer
|
|||
private $config;
|
||||
|
||||
/**
|
||||
* @param Package\PackageInterface $package
|
||||
* @param Package\RootPackageInterface $package
|
||||
* @return void
|
||||
*/
|
||||
public function setPackage(PackageInterface $package)
|
||||
public function setPackage(RootPackageInterface $package)
|
||||
{
|
||||
$this->package = $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Package\PackageInterface
|
||||
* @return Package\RootPackageInterface
|
||||
*/
|
||||
public function getPackage()
|
||||
{
|
||||
|
|
|
@ -13,10 +13,15 @@
|
|||
namespace Composer\DependencyResolver;
|
||||
|
||||
use Composer\Package\BasePackage;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\LinkConstraint\LinkConstraintInterface;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\Repository\CompositeRepository;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
use Composer\Repository\StreamableRepositoryInterface;
|
||||
use Composer\Repository\PlatformRepository;
|
||||
|
||||
/**
|
||||
|
@ -27,15 +32,23 @@ use Composer\Repository\PlatformRepository;
|
|||
*/
|
||||
class Pool
|
||||
{
|
||||
const MATCH_NAME = -1;
|
||||
const MATCH_NONE = 0;
|
||||
const MATCH = 1;
|
||||
const MATCH_PROVIDE = 2;
|
||||
const MATCH_REPLACE = 3;
|
||||
|
||||
protected $repositories = array();
|
||||
protected $packages = array();
|
||||
protected $packageByName = array();
|
||||
protected $acceptableStabilities;
|
||||
protected $stabilityFlags;
|
||||
protected $versionParser;
|
||||
|
||||
public function __construct($minimumStability = 'stable', array $stabilityFlags = array())
|
||||
{
|
||||
$stabilities = BasePackage::$stabilities;
|
||||
$this->versionParser = new VersionParser;
|
||||
$this->acceptableStabilities = array();
|
||||
foreach (BasePackage::$stabilities as $stability => $value) {
|
||||
if ($value <= BasePackage::$stabilities[$minimumStability]) {
|
||||
|
@ -48,9 +61,10 @@ class Pool
|
|||
/**
|
||||
* Adds a repository and its packages to this package pool
|
||||
*
|
||||
* @param RepositoryInterface $repo A package repository
|
||||
* @param RepositoryInterface $repo A package repository
|
||||
* @param array $rootAliases
|
||||
*/
|
||||
public function addRepository(RepositoryInterface $repo)
|
||||
public function addRepository(RepositoryInterface $repo, $rootAliases = array())
|
||||
{
|
||||
if ($repo instanceof CompositeRepository) {
|
||||
$repos = $repo->getRepositories();
|
||||
|
@ -63,25 +77,93 @@ class Pool
|
|||
$this->repositories[] = $repo;
|
||||
|
||||
$exempt = $repo instanceof PlatformRepository || $repo instanceof InstalledRepositoryInterface;
|
||||
foreach ($repo->getPackages() as $package) {
|
||||
$name = $package->getName();
|
||||
$stability = $package->getStability();
|
||||
if (
|
||||
// always allow exempt repos
|
||||
$exempt
|
||||
// allow if package matches the global stability requirement and has no exception
|
||||
|| (!isset($this->stabilityFlags[$name])
|
||||
&& isset($this->acceptableStabilities[$stability]))
|
||||
// allow if package matches the package-specific stability flag
|
||||
|| (isset($this->stabilityFlags[$name])
|
||||
&& BasePackage::$stabilities[$stability] <= $this->stabilityFlags[$name]
|
||||
)
|
||||
) {
|
||||
$package->setId($id++);
|
||||
$this->packages[] = $package;
|
||||
if ($repo instanceof StreamableRepositoryInterface) {
|
||||
foreach ($repo->getMinimalPackages() as $package) {
|
||||
$name = $package['name'];
|
||||
$version = $package['version'];
|
||||
$stability = VersionParser::parseStability($version);
|
||||
if ($exempt || $this->isPackageAcceptable($name, $stability)) {
|
||||
$package['id'] = $id++;
|
||||
$this->packages[] = $package;
|
||||
|
||||
foreach ($package->getNames() as $name) {
|
||||
$this->packageByName[$name][] = $package;
|
||||
// collect names
|
||||
$names = array(
|
||||
$name => true,
|
||||
);
|
||||
if (isset($package['provide'])) {
|
||||
foreach ($package['provide'] as $target => $constraint) {
|
||||
$names[$target] = true;
|
||||
}
|
||||
}
|
||||
if (isset($package['replace'])) {
|
||||
foreach ($package['replace'] as $target => $constraint) {
|
||||
$names[$target] = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($names) as $name) {
|
||||
$this->packageByName[$name][] =& $this->packages[$id-2];
|
||||
}
|
||||
|
||||
// handle root package aliases
|
||||
if (isset($rootAliases[$name][$version])) {
|
||||
$alias = $package;
|
||||
unset($alias['raw']);
|
||||
$alias['version'] = $rootAliases[$name][$version]['alias_normalized'];
|
||||
$alias['alias'] = $rootAliases[$name][$version]['alias'];
|
||||
$alias['alias_of'] = $package['id'];
|
||||
$alias['id'] = $id++;
|
||||
$alias['root_alias'] = true;
|
||||
$this->packages[] = $alias;
|
||||
|
||||
foreach (array_keys($names) as $name) {
|
||||
$this->packageByName[$name][] =& $this->packages[$id-2];
|
||||
}
|
||||
}
|
||||
|
||||
// handle normal package aliases
|
||||
if (isset($package['alias'])) {
|
||||
$alias = $package;
|
||||
unset($alias['raw']);
|
||||
$alias['version'] = $package['alias_normalized'];
|
||||
$alias['alias'] = $package['alias'];
|
||||
$alias['alias_of'] = $package['id'];
|
||||
$alias['id'] = $id++;
|
||||
$this->packages[] = $alias;
|
||||
|
||||
foreach (array_keys($names) as $name) {
|
||||
$this->packageByName[$name][] =& $this->packages[$id-2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($repo->getPackages() as $package) {
|
||||
$name = $package->getName();
|
||||
$stability = $package->getStability();
|
||||
if ($exempt || $this->isPackageAcceptable($name, $stability)) {
|
||||
$package->setId($id++);
|
||||
$this->packages[] = $package;
|
||||
|
||||
foreach ($package->getNames() as $name) {
|
||||
$this->packageByName[$name][] = $package;
|
||||
}
|
||||
|
||||
// handle root package aliases
|
||||
if (isset($rootAliases[$name][$package->getVersion()])) {
|
||||
$alias = $rootAliases[$name][$package->getVersion()];
|
||||
$package->setAlias($alias['alias_normalized']);
|
||||
$package->setPrettyAlias($alias['alias']);
|
||||
$package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$aliasPackage->setRootPackageAlias(true);
|
||||
$aliasPackage->setId($id++);
|
||||
|
||||
$this->packages[] = $aliasPackage;
|
||||
|
||||
foreach ($aliasPackage->getNames() as $name) {
|
||||
$this->packageByName[$name][] = $aliasPackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +189,8 @@ class Pool
|
|||
*/
|
||||
public function packageById($id)
|
||||
{
|
||||
$this->ensurePackageIsLoaded($this->packages[$id - 1]);
|
||||
|
||||
return $this->packages[$id - 1];
|
||||
}
|
||||
|
||||
|
@ -137,6 +221,10 @@ class Pool
|
|||
$candidates = $this->packageByName[$name];
|
||||
|
||||
if (null === $constraint) {
|
||||
foreach ($candidates as $key => $candidate) {
|
||||
$candidates[$key] = $this->ensurePackageIsLoaded($candidate);
|
||||
}
|
||||
|
||||
return $candidates;
|
||||
}
|
||||
|
||||
|
@ -144,25 +232,25 @@ class Pool
|
|||
$nameMatch = false;
|
||||
|
||||
foreach ($candidates as $candidate) {
|
||||
switch ($candidate->matches($name, $constraint)) {
|
||||
case BasePackage::MATCH_NONE:
|
||||
switch ($this->match($candidate, $name, $constraint)) {
|
||||
case self::MATCH_NONE:
|
||||
break;
|
||||
|
||||
case BasePackage::MATCH_NAME:
|
||||
case self::MATCH_NAME:
|
||||
$nameMatch = true;
|
||||
break;
|
||||
|
||||
case BasePackage::MATCH:
|
||||
case self::MATCH:
|
||||
$nameMatch = true;
|
||||
$matches[] = $candidate;
|
||||
$matches[] = $this->ensurePackageIsLoaded($candidate);
|
||||
break;
|
||||
|
||||
case BasePackage::MATCH_PROVIDE:
|
||||
$provideMatches[] = $candidate;
|
||||
case self::MATCH_PROVIDE:
|
||||
$provideMatches[] = $this->ensurePackageIsLoaded($candidate);
|
||||
break;
|
||||
|
||||
case BasePackage::MATCH_REPLACE:
|
||||
$matches[] = $candidate;
|
||||
case self::MATCH_REPLACE:
|
||||
$matches[] = $this->ensurePackageIsLoaded($candidate);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -202,4 +290,89 @@ class Pool
|
|||
|
||||
return $prefix.' '.$package->getPrettyString();
|
||||
}
|
||||
|
||||
private function isPackageAcceptable($name, $stability)
|
||||
{
|
||||
// allow if package matches the global stability requirement and has no exception
|
||||
if (!isset($this->stabilityFlags[$name]) && isset($this->acceptableStabilities[$stability])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// allow if package matches the package-specific stability flag
|
||||
if (isset($this->stabilityFlags[$name]) && BasePackage::$stabilities[$stability] <= $this->stabilityFlags[$name]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function ensurePackageIsLoaded($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
if (isset($data['alias_of'])) {
|
||||
$aliasOf = $this->packageById($data['alias_of']);
|
||||
$package = $this->packages[$data['id'] - 1] = $data['repo']->loadAliasPackage($data, $aliasOf);
|
||||
$package->setRootPackageAlias(!empty($data['root_alias']));
|
||||
} else {
|
||||
$package = $this->packages[$data['id'] - 1] = $data['repo']->loadPackage($data);
|
||||
}
|
||||
|
||||
$package->setId($data['id']);
|
||||
$data = $package;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the package matches the given constraint directly or through
|
||||
* provided or replaced packages
|
||||
*
|
||||
* @param array|PackageInterface $candidate
|
||||
* @param string $name Name of the package to be matched
|
||||
* @param LinkConstraintInterface $constraint The constraint to verify
|
||||
* @return int One of the MATCH* constants of this class or 0 if there is no match
|
||||
*/
|
||||
private function match($candidate, $name, LinkConstraintInterface $constraint)
|
||||
{
|
||||
// handle array packages
|
||||
if (is_array($candidate)) {
|
||||
$candidateName = $candidate['name'];
|
||||
$candidateVersion = $candidate['version'];
|
||||
} else {
|
||||
// handle object packages
|
||||
$candidateName = $candidate->getName();
|
||||
$candidateVersion = $candidate->getVersion();
|
||||
}
|
||||
|
||||
if ($candidateName === $name) {
|
||||
return $constraint->matches(new VersionConstraint('==', $candidateVersion)) ? self::MATCH : self::MATCH_NAME;
|
||||
}
|
||||
|
||||
if (is_array($candidate)) {
|
||||
$provides = isset($candidate['provide'])
|
||||
? $this->versionParser->parseLinks($candidateName, $candidateVersion, 'provides', $candidate['provide'])
|
||||
: array();
|
||||
$replaces = isset($candidate['replace'])
|
||||
? $this->versionParser->parseLinks($candidateName, $candidateVersion, 'replaces', $candidate['replace'])
|
||||
: array();
|
||||
} else {
|
||||
$provides = $candidate->getProvides();
|
||||
$replaces = $candidate->getReplaces();
|
||||
}
|
||||
|
||||
foreach ($provides as $link) {
|
||||
if ($link->getTarget() === $name && $constraint->matches($link->getConstraint())) {
|
||||
return self::MATCH_PROVIDE;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($replaces as $link) {
|
||||
if ($link->getTarget() === $name && $constraint->matches($link->getConstraint())) {
|
||||
return self::MATCH_REPLACE;
|
||||
}
|
||||
}
|
||||
|
||||
return self::MATCH_NONE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ use Composer\Package\Link;
|
|||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Package\Locker;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Repository\CompositeRepository;
|
||||
use Composer\Repository\InstalledArrayRepository;
|
||||
use Composer\Repository\PlatformRepository;
|
||||
|
@ -55,7 +56,7 @@ class Installer
|
|||
protected $config;
|
||||
|
||||
/**
|
||||
* @var PackageInterface
|
||||
* @var RootPackageInterface
|
||||
*/
|
||||
protected $package;
|
||||
|
||||
|
@ -112,7 +113,7 @@ class Installer
|
|||
*
|
||||
* @param IOInterface $io
|
||||
* @param Config $config
|
||||
* @param PackageInterface $package
|
||||
* @param RootPackageInterface $package
|
||||
* @param DownloadManager $downloadManager
|
||||
* @param RepositoryManager $repositoryManager
|
||||
* @param Locker $locker
|
||||
|
@ -120,7 +121,7 @@ class Installer
|
|||
* @param EventDispatcher $eventDispatcher
|
||||
* @param AutoloadGenerator $autoloadGenerator
|
||||
*/
|
||||
public function __construct(IOInterface $io, Config $config, PackageInterface $package, DownloadManager $downloadManager, RepositoryManager $repositoryManager, Locker $locker, InstallationManager $installationManager, EventDispatcher $eventDispatcher, AutoloadGenerator $autoloadGenerator)
|
||||
public function __construct(IOInterface $io, Config $config, RootPackageInterface $package, DownloadManager $downloadManager, RepositoryManager $repositoryManager, Locker $locker, InstallationManager $installationManager, EventDispatcher $eventDispatcher, AutoloadGenerator $autoloadGenerator)
|
||||
{
|
||||
$this->io = $io;
|
||||
$this->config = $config;
|
||||
|
@ -166,7 +167,8 @@ class Installer
|
|||
$installedRepo->addRepository($this->additionalInstalledRepository);
|
||||
}
|
||||
|
||||
$aliases = $this->aliasPackages($platformRepo);
|
||||
$aliases = $this->getRootAliases();
|
||||
$this->aliasPlatformPackages($platformRepo, $aliases);
|
||||
|
||||
if ($this->runScripts) {
|
||||
// dispatch pre event
|
||||
|
@ -244,9 +246,10 @@ class Installer
|
|||
|
||||
// creating repository pool
|
||||
$pool = new Pool($minimumStability, $stabilityFlags);
|
||||
$pool->addRepository($installedRepo);
|
||||
foreach ($this->repositoryManager->getRepositories() as $repository) {
|
||||
$pool->addRepository($repository);
|
||||
$pool->addRepository($installedRepo, $aliases);
|
||||
$repositories = $this->repositoryManager->getRepositories();
|
||||
foreach ($repositories as $repository) {
|
||||
$pool->addRepository($repository, $aliases);
|
||||
}
|
||||
|
||||
// creating requirements request
|
||||
|
@ -276,11 +279,8 @@ class Installer
|
|||
|
||||
foreach ($lockedPackages as $package) {
|
||||
$version = $package->getVersion();
|
||||
foreach ($aliases as $alias) {
|
||||
if ($alias['package'] === $package->getName() && $alias['version'] === $package->getVersion()) {
|
||||
$version = $alias['alias_normalized'];
|
||||
break;
|
||||
}
|
||||
if (isset($aliases[$package->getName()][$version])) {
|
||||
$version = $aliases[$package->getName()][$version]['alias_normalized'];
|
||||
}
|
||||
$constraint = new VersionConstraint('=', $version);
|
||||
$request->install($package->getName(), $constraint);
|
||||
|
@ -361,6 +361,10 @@ class Installer
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($package instanceof AliasPackage) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip packages that will be updated/uninstalled
|
||||
foreach ($operations as $operation) {
|
||||
if (('update' === $operation->getJobType() && $operation->getInitialPackage()->equals($package))
|
||||
|
@ -392,7 +396,18 @@ class Installer
|
|||
continue;
|
||||
}
|
||||
|
||||
$newPackage = $this->repositoryManager->findPackage($package->getName(), $package->getVersion());
|
||||
$newPackage = null;
|
||||
$matches = $pool->whatProvides($package->getName(), new VersionConstraint('=', $package->getVersion()));
|
||||
foreach ($matches as $match) {
|
||||
// skip local packages
|
||||
if (!in_array($match->getRepository(), $repositories, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newPackage = $match;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) {
|
||||
$operations[] = new UpdateOperation($package, $newPackage);
|
||||
}
|
||||
|
@ -487,7 +502,7 @@ class Installer
|
|||
return true;
|
||||
}
|
||||
|
||||
private function aliasPackages(PlatformRepository $platformRepo)
|
||||
private function getRootAliases()
|
||||
{
|
||||
if (!$this->update && $this->locker->isLocked()) {
|
||||
$aliases = $this->locker->getAliases();
|
||||
|
@ -495,20 +510,32 @@ class Installer
|
|||
$aliases = $this->package->getAliases();
|
||||
}
|
||||
|
||||
$normalizedAliases = array();
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
$packages = array_merge(
|
||||
$platformRepo->findPackages($alias['package'], $alias['version']),
|
||||
$this->repositoryManager->findPackages($alias['package'], $alias['version'])
|
||||
$normalizedAliases[$alias['package']][$alias['version']] = array(
|
||||
'alias' => $alias['alias'],
|
||||
'alias_normalized' => $alias['alias_normalized']
|
||||
);
|
||||
foreach ($packages as $package) {
|
||||
$package->setAlias($alias['alias_normalized']);
|
||||
$package->setPrettyAlias($alias['alias']);
|
||||
$package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$aliasPackage->setRootPackageAlias(true);
|
||||
}
|
||||
}
|
||||
|
||||
return $aliases;
|
||||
return $normalizedAliases;
|
||||
}
|
||||
|
||||
private function aliasPlatformPackages(PlatformRepository $platformRepo, $aliases)
|
||||
{
|
||||
foreach ($aliases as $package => $versions) {
|
||||
foreach ($versions as $version => $alias) {
|
||||
$packages = $platformRepo->findPackages($package, $version);
|
||||
foreach ($packages as $package) {
|
||||
$package->setAlias($alias['alias_normalized']);
|
||||
$package->setPrettyAlias($alias['alias']);
|
||||
$aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']);
|
||||
$aliasPackage->setRootPackageAlias(true);
|
||||
$platformRepo->addPackage($aliasPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function isUpdateable(PackageInterface $package)
|
||||
|
|
|
@ -18,7 +18,7 @@ use Composer\Package\Version\VersionParser;
|
|||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class AliasPackage extends BasePackage
|
||||
class AliasPackage extends BasePackage implements CompletePackageInterface
|
||||
{
|
||||
protected $version;
|
||||
protected $prettyVersion;
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
namespace Composer\Package;
|
||||
|
||||
use Composer\Package\LinkConstraint\LinkConstraintInterface;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\Repository\PlatformRepository;
|
||||
|
||||
|
@ -38,12 +36,6 @@ abstract class BasePackage implements PackageInterface
|
|||
const STABILITY_ALPHA = 15;
|
||||
const STABILITY_DEV = 20;
|
||||
|
||||
const MATCH_NAME = -1;
|
||||
const MATCH_NONE = 0;
|
||||
const MATCH = 1;
|
||||
const MATCH_PROVIDE = 2;
|
||||
const MATCH_REPLACE = 3;
|
||||
|
||||
public static $stabilities = array(
|
||||
'stable' => self::STABILITY_STABLE,
|
||||
'RC' => self::STABILITY_RC,
|
||||
|
@ -122,35 +114,6 @@ abstract class BasePackage implements PackageInterface
|
|||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the package matches the given constraint directly or through
|
||||
* provided or replaced packages
|
||||
*
|
||||
* @param string $name Name of the package to be matched
|
||||
* @param LinkConstraintInterface $constraint The constraint to verify
|
||||
* @return int One of the MATCH* constants of this class or 0 if there is no match
|
||||
*/
|
||||
public function matches($name, LinkConstraintInterface $constraint)
|
||||
{
|
||||
if ($this->name === $name) {
|
||||
return $constraint->matches(new VersionConstraint('==', $this->getVersion())) ? self::MATCH : self::MATCH_NAME;
|
||||
}
|
||||
|
||||
foreach ($this->getProvides() as $link) {
|
||||
if ($link->getTarget() === $name && $constraint->matches($link->getConstraint())) {
|
||||
return self::MATCH_PROVIDE;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getReplaces() as $link) {
|
||||
if ($link->getTarget() === $name && $constraint->matches($link->getConstraint())) {
|
||||
return self::MATCH_REPLACE;
|
||||
}
|
||||
}
|
||||
|
||||
return self::MATCH_NONE;
|
||||
}
|
||||
|
||||
public function getRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<?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\Package;
|
||||
|
||||
use Composer\Package\Version\VersionParser;
|
||||
|
||||
/**
|
||||
* Package containing additional metadata that is not used by the solver
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
class CompletePackage extends Package implements CompletePackageInterface
|
||||
{
|
||||
protected $repositories;
|
||||
protected $license = array();
|
||||
protected $keywords;
|
||||
protected $authors;
|
||||
protected $description;
|
||||
protected $homepage;
|
||||
protected $scripts = array();
|
||||
protected $support = array();
|
||||
|
||||
/**
|
||||
* @param array $scripts
|
||||
*/
|
||||
public function setScripts(array $scripts)
|
||||
{
|
||||
$this->scripts = $scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getScripts()
|
||||
{
|
||||
return $this->scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the repositories
|
||||
*
|
||||
* @param string $repositories
|
||||
*/
|
||||
public function setRepositories($repositories)
|
||||
{
|
||||
$this->repositories = $repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getRepositories()
|
||||
{
|
||||
return $this->repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the license
|
||||
*
|
||||
* @param array $license
|
||||
*/
|
||||
public function setLicense(array $license)
|
||||
{
|
||||
$this->license = $license;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getLicense()
|
||||
{
|
||||
return $this->license;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the keywords
|
||||
*
|
||||
* @param array $keywords
|
||||
*/
|
||||
public function setKeywords(array $keywords)
|
||||
{
|
||||
$this->keywords = $keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getKeywords()
|
||||
{
|
||||
return $this->keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authors
|
||||
*
|
||||
* @param array $authors
|
||||
*/
|
||||
public function setAuthors(array $authors)
|
||||
{
|
||||
$this->authors = $authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getAuthors()
|
||||
{
|
||||
return $this->authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the description
|
||||
*
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the homepage
|
||||
*
|
||||
* @param string $homepage
|
||||
*/
|
||||
public function setHomepage($homepage)
|
||||
{
|
||||
$this->homepage = $homepage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getHomepage()
|
||||
{
|
||||
return $this->homepage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the support information
|
||||
*
|
||||
* @param array $support
|
||||
*/
|
||||
public function setSupport(array $support)
|
||||
{
|
||||
$this->support = $support;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSupport()
|
||||
{
|
||||
return $this->support;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?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\Package;
|
||||
|
||||
/**
|
||||
* Defines package metadata that is not necessarily needed for solving and installing packages
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
interface CompletePackageInterface extends PackageInterface
|
||||
{
|
||||
/**
|
||||
* Returns the scripts of this package
|
||||
*
|
||||
* @return array array('script name' => array('listeners'))
|
||||
*/
|
||||
public function getScripts();
|
||||
|
||||
/**
|
||||
* Returns an array of repositories
|
||||
*
|
||||
* {"<type>": {<config key/values>}}
|
||||
*
|
||||
* @return array Repositories
|
||||
*/
|
||||
public function getRepositories();
|
||||
|
||||
/**
|
||||
* Returns the package license, e.g. MIT, BSD, GPL
|
||||
*
|
||||
* @return array The package licenses
|
||||
*/
|
||||
public function getLicense();
|
||||
|
||||
/**
|
||||
* Returns an array of keywords relating to the package
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getKeywords();
|
||||
|
||||
/**
|
||||
* Returns the package description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Returns the package homepage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHomepage();
|
||||
|
||||
/**
|
||||
* Returns an array of authors of the package
|
||||
*
|
||||
* Each item can contain name/homepage/email keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthors();
|
||||
|
||||
/**
|
||||
* Returns the support information
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSupport();
|
||||
}
|
|
@ -14,6 +14,7 @@ namespace Composer\Package\Dumper;
|
|||
|
||||
use Composer\Package\BasePackage;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\CompletePackageInterface;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kudryashiv <ever.zet@gmail.com>
|
||||
|
@ -25,19 +26,11 @@ class ArrayDumper
|
|||
{
|
||||
$keys = array(
|
||||
'binaries' => 'bin',
|
||||
'scripts',
|
||||
'type',
|
||||
'extra',
|
||||
'installationSource' => 'installation-source',
|
||||
'license',
|
||||
'authors',
|
||||
'description',
|
||||
'homepage',
|
||||
'keywords',
|
||||
'autoload',
|
||||
'repositories',
|
||||
'includePaths' => 'include-path',
|
||||
'support',
|
||||
);
|
||||
|
||||
$data = array();
|
||||
|
@ -49,10 +42,6 @@ class ArrayDumper
|
|||
$data['target-dir'] = $package->getTargetDir();
|
||||
}
|
||||
|
||||
if ($package->getReleaseDate()) {
|
||||
$data['time'] = $package->getReleaseDate()->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
if ($package->getSourceType()) {
|
||||
$data['source']['type'] = $package->getSourceType();
|
||||
$data['source']['url'] = $package->getSourceUrl();
|
||||
|
@ -78,6 +67,32 @@ class ArrayDumper
|
|||
$data['suggest'] = $packages;
|
||||
}
|
||||
|
||||
if ($package->getReleaseDate()) {
|
||||
$data['time'] = $package->getReleaseDate()->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$data = $this->dumpValues($package, $keys, $data);
|
||||
|
||||
if ($package instanceof CompletePackageInterface) {
|
||||
$keys = array(
|
||||
'scripts',
|
||||
'license',
|
||||
'authors',
|
||||
'description',
|
||||
'homepage',
|
||||
'keywords',
|
||||
'repositories',
|
||||
'support',
|
||||
);
|
||||
|
||||
$data = $this->dumpValues($package, $keys, $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function dumpValues(PackageInterface $package, array $keys, array $data)
|
||||
{
|
||||
foreach ($keys as $method => $key) {
|
||||
if (is_numeric($method)) {
|
||||
$method = $key;
|
||||
|
|
|
@ -31,7 +31,7 @@ class ArrayLoader implements LoaderInterface
|
|||
$this->versionParser = $parser;
|
||||
}
|
||||
|
||||
public function load(array $config)
|
||||
public function load(array $config, $class = 'Composer\Package\CompletePackage')
|
||||
{
|
||||
if (!isset($config['name'])) {
|
||||
throw new \UnexpectedValueException('Unknown package has no name defined ('.json_encode($config).').');
|
||||
|
@ -46,7 +46,7 @@ class ArrayLoader implements LoaderInterface
|
|||
} else {
|
||||
$version = $this->versionParser->normalize($config['version']);
|
||||
}
|
||||
$package = new Package\MemoryPackage($config['name'], $version, $config['version']);
|
||||
$package = new $class($config['name'], $version, $config['version']);
|
||||
$package->setType(isset($config['type']) ? strtolower($config['type']) : 'library');
|
||||
|
||||
if (isset($config['target-dir'])) {
|
||||
|
@ -67,42 +67,6 @@ class ArrayLoader implements LoaderInterface
|
|||
$package->setBinaries($config['bin']);
|
||||
}
|
||||
|
||||
if (isset($config['scripts']) && is_array($config['scripts'])) {
|
||||
foreach ($config['scripts'] as $event => $listeners) {
|
||||
$config['scripts'][$event]= (array) $listeners;
|
||||
}
|
||||
$package->setScripts($config['scripts']);
|
||||
}
|
||||
|
||||
if (!empty($config['description']) && is_string($config['description'])) {
|
||||
$package->setDescription($config['description']);
|
||||
}
|
||||
|
||||
if (!empty($config['homepage']) && is_string($config['homepage'])) {
|
||||
$package->setHomepage($config['homepage']);
|
||||
}
|
||||
|
||||
if (!empty($config['keywords']) && is_array($config['keywords'])) {
|
||||
$package->setKeywords($config['keywords']);
|
||||
}
|
||||
|
||||
if (!empty($config['license'])) {
|
||||
$package->setLicense(is_array($config['license']) ? $config['license'] : array($config['license']));
|
||||
}
|
||||
|
||||
if (!empty($config['time'])) {
|
||||
try {
|
||||
$date = new \DateTime($config['time']);
|
||||
$date->setTimezone(new \DateTimeZone('UTC'));
|
||||
$package->setReleaseDate($date);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($config['authors']) && is_array($config['authors'])) {
|
||||
$package->setAuthors($config['authors']);
|
||||
}
|
||||
|
||||
if (isset($config['installation-source'])) {
|
||||
$package->setInstallationSource($config['installation-source']);
|
||||
}
|
||||
|
@ -134,35 +98,21 @@ class ArrayLoader implements LoaderInterface
|
|||
$package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null);
|
||||
}
|
||||
|
||||
// check for a branch alias (dev-master => 1.0.x-dev for example) if this is a named branch
|
||||
if ('dev-' === substr($package->getPrettyVersion(), 0, 4) && isset($config['extra']['branch-alias']) && is_array($config['extra']['branch-alias'])) {
|
||||
foreach ($config['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
|
||||
// ensure it is an alias to a -dev package
|
||||
if ('-dev' !== substr($targetBranch, -4)) {
|
||||
continue;
|
||||
}
|
||||
// normalize without -dev and ensure it's a numeric branch that is parseable
|
||||
$validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
|
||||
if ('-dev' !== substr($validatedTargetBranch, -4)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ensure that it is the current branch aliasing itself
|
||||
if (strtolower($package->getPrettyVersion()) !== strtolower($sourceBranch)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$package->setAlias($validatedTargetBranch);
|
||||
$package->setPrettyAlias(preg_replace('{(\.9{7})+}', '.x', $validatedTargetBranch));
|
||||
break;
|
||||
}
|
||||
if ($aliasNormalized = $this->getBranchAlias($config)) {
|
||||
$package->setAlias($aliasNormalized);
|
||||
$package->setPrettyAlias(preg_replace('{(\.9{7})+}', '.x', $aliasNormalized));
|
||||
}
|
||||
|
||||
foreach (Package\BasePackage::$supportedLinkTypes as $type => $opts) {
|
||||
if (isset($config[$type])) {
|
||||
$method = 'set'.ucfirst($opts['method']);
|
||||
$package->{$method}(
|
||||
$this->loadLinksFromConfig($package, $opts['description'], $config[$type])
|
||||
$this->versionParser->parseLinks(
|
||||
$package->getName(),
|
||||
$package->getPrettyVersion(),
|
||||
$opts['description'],
|
||||
$config[$type]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -184,25 +134,84 @@ class ArrayLoader implements LoaderInterface
|
|||
$package->setIncludePaths($config['include-path']);
|
||||
}
|
||||
|
||||
if (isset($config['support'])) {
|
||||
$package->setSupport($config['support']);
|
||||
if (!empty($config['time'])) {
|
||||
try {
|
||||
$date = new \DateTime($config['time']);
|
||||
$date->setTimezone(new \DateTimeZone('UTC'));
|
||||
$package->setReleaseDate($date);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($package instanceof Package\CompletePackageInterface) {
|
||||
if (isset($config['scripts']) && is_array($config['scripts'])) {
|
||||
foreach ($config['scripts'] as $event => $listeners) {
|
||||
$config['scripts'][$event]= (array) $listeners;
|
||||
}
|
||||
$package->setScripts($config['scripts']);
|
||||
}
|
||||
|
||||
if (!empty($config['description']) && is_string($config['description'])) {
|
||||
$package->setDescription($config['description']);
|
||||
}
|
||||
|
||||
if (!empty($config['homepage']) && is_string($config['homepage'])) {
|
||||
$package->setHomepage($config['homepage']);
|
||||
}
|
||||
|
||||
if (!empty($config['keywords']) && is_array($config['keywords'])) {
|
||||
$package->setKeywords($config['keywords']);
|
||||
}
|
||||
|
||||
if (!empty($config['license'])) {
|
||||
$package->setLicense(is_array($config['license']) ? $config['license'] : array($config['license']));
|
||||
}
|
||||
|
||||
if (!empty($config['authors']) && is_array($config['authors'])) {
|
||||
$package->setAuthors($config['authors']);
|
||||
}
|
||||
|
||||
if (isset($config['support'])) {
|
||||
$package->setSupport($config['support']);
|
||||
}
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
private function loadLinksFromConfig($package, $description, array $linksSpecs)
|
||||
/**
|
||||
* Retrieves a branch alias (dev-master => 1.0.x-dev for example) if it exists
|
||||
*
|
||||
* @param array $config the entire package config
|
||||
* @return string|null normalized version of the branch alias or null if there is none
|
||||
*/
|
||||
public function getBranchAlias(array $config)
|
||||
{
|
||||
$links = array();
|
||||
foreach ($linksSpecs as $packageName => $constraint) {
|
||||
if ('self.version' === $constraint) {
|
||||
$parsedConstraint = $this->versionParser->parseConstraints($package->getPrettyVersion());
|
||||
} else {
|
||||
$parsedConstraint = $this->versionParser->parseConstraints($constraint);
|
||||
}
|
||||
$links[] = new Package\Link($package->getName(), $packageName, $parsedConstraint, $description, $constraint);
|
||||
if ('dev-' !== substr($config['version'], 0, 4)
|
||||
|| !isset($config['extra']['branch-alias'])
|
||||
|| !is_array($config['extra']['branch-alias'])
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $links;
|
||||
foreach ($config['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
|
||||
// ensure it is an alias to a -dev package
|
||||
if ('-dev' !== substr($targetBranch, -4)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// normalize without -dev and ensure it's a numeric branch that is parseable
|
||||
$validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
|
||||
if ('-dev' !== substr($validatedTargetBranch, -4)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ensure that it is the current branch aliasing itself
|
||||
if (strtolower($config['version']) !== strtolower($sourceBranch)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $validatedTargetBranch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ interface LoaderInterface
|
|||
* Converts a package from an array to a real instance
|
||||
*
|
||||
* @param array $package Package config
|
||||
* @param string $class Package class to use
|
||||
* @return \Composer\Package\PackageInterface
|
||||
*/
|
||||
public function load(array $package);
|
||||
public function load(array $package, $class = 'Composer\Package\CompletePackage');
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class RootPackageLoader extends ArrayLoader
|
|||
parent::__construct($parser);
|
||||
}
|
||||
|
||||
public function load(array $config)
|
||||
public function load(array $config, $class = 'Composer\Package\RootPackage')
|
||||
{
|
||||
if (!isset($config['name'])) {
|
||||
$config['name'] = '__root__';
|
||||
|
@ -62,7 +62,7 @@ class RootPackageLoader extends ArrayLoader
|
|||
$version = $config['version'];
|
||||
}
|
||||
|
||||
$package = parent::load($config);
|
||||
$package = parent::load($config, $class);
|
||||
|
||||
$aliases = array();
|
||||
$stabilityFlags = array();
|
||||
|
|
|
@ -36,7 +36,7 @@ class ValidatingArrayLoader implements LoaderInterface
|
|||
$this->versionParser = $parser;
|
||||
}
|
||||
|
||||
public function load(array $config)
|
||||
public function load(array $config, $class = 'Composer\Package\CompletePackage')
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
|
@ -168,7 +168,7 @@ class ValidatingArrayLoader implements LoaderInterface
|
|||
throw new \Exception(implode("\n", $this->errors));
|
||||
}
|
||||
|
||||
$package = $this->loader->load($this->config);
|
||||
$package = $this->loader->load($this->config, $class);
|
||||
$this->errors = array();
|
||||
$this->config = null;
|
||||
|
||||
|
|
|
@ -177,11 +177,22 @@ class Locker
|
|||
'hash' => $this->hash,
|
||||
'packages' => null,
|
||||
'packages-dev' => null,
|
||||
'aliases' => $aliases,
|
||||
'aliases' => array(),
|
||||
'minimum-stability' => $minimumStability,
|
||||
'stability-flags' => $stabilityFlags,
|
||||
);
|
||||
|
||||
foreach ($aliases as $package => $versions) {
|
||||
foreach ($versions as $version => $alias) {
|
||||
$lock['aliases'][] = array(
|
||||
'alias' => $alias['alias'],
|
||||
'alias_normalized' => $alias['alias_normalized'],
|
||||
'version' => $version,
|
||||
'package' => $package,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$lock['packages'] = $this->lockPackages($packages);
|
||||
if (null !== $devPackages) {
|
||||
$lock['packages-dev'] = $this->lockPackages($devPackages);
|
||||
|
|
|
@ -15,11 +15,11 @@ namespace Composer\Package;
|
|||
use Composer\Package\Version\VersionParser;
|
||||
|
||||
/**
|
||||
* A package with setters for all members to create it dynamically in memory
|
||||
* Core package definitions that are needed to resolve dependencies and install packages
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
class MemoryPackage extends BasePackage
|
||||
class Package extends BasePackage
|
||||
{
|
||||
protected $type;
|
||||
protected $targetDir;
|
||||
|
@ -33,24 +33,14 @@ class MemoryPackage extends BasePackage
|
|||
protected $distSha1Checksum;
|
||||
protected $version;
|
||||
protected $prettyVersion;
|
||||
protected $repositories;
|
||||
protected $license = array();
|
||||
protected $releaseDate;
|
||||
protected $keywords;
|
||||
protected $authors;
|
||||
protected $description;
|
||||
protected $homepage;
|
||||
protected $extra = array();
|
||||
protected $binaries = array();
|
||||
protected $scripts = array();
|
||||
protected $aliases = array();
|
||||
protected $alias;
|
||||
protected $prettyAlias;
|
||||
protected $dev;
|
||||
|
||||
protected $minimumStability = 'stable';
|
||||
protected $stabilityFlags = array();
|
||||
protected $references = array();
|
||||
protected $stability;
|
||||
|
||||
protected $requires = array();
|
||||
protected $conflicts = array();
|
||||
|
@ -60,7 +50,6 @@ class MemoryPackage extends BasePackage
|
|||
protected $suggests = array();
|
||||
protected $autoload = array();
|
||||
protected $includePaths = array();
|
||||
protected $support = array();
|
||||
|
||||
/**
|
||||
* Creates a new in memory package.
|
||||
|
@ -160,22 +149,6 @@ class MemoryPackage extends BasePackage
|
|||
return $this->binaries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $scripts
|
||||
*/
|
||||
public function setScripts(array $scripts)
|
||||
{
|
||||
$this->scripts = $scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getScripts()
|
||||
{
|
||||
return $this->scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aliases
|
||||
*/
|
||||
|
@ -352,24 +325,6 @@ class MemoryPackage extends BasePackage
|
|||
return $this->distSha1Checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the repositories
|
||||
*
|
||||
* @param string $repositories
|
||||
*/
|
||||
public function setRepositories($repositories)
|
||||
{
|
||||
$this->repositories = $repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getRepositories()
|
||||
{
|
||||
return $this->repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -387,21 +342,21 @@ class MemoryPackage extends BasePackage
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the license
|
||||
* Set the releaseDate
|
||||
*
|
||||
* @param array $license
|
||||
* @param DateTime $releaseDate
|
||||
*/
|
||||
public function setLicense(array $license)
|
||||
public function setReleaseDate(\DateTime $releaseDate)
|
||||
{
|
||||
$this->license = $license;
|
||||
$this->releaseDate = $releaseDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getLicense()
|
||||
public function getReleaseDate()
|
||||
{
|
||||
return $this->license;
|
||||
return $this->releaseDate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -512,150 +467,6 @@ class MemoryPackage extends BasePackage
|
|||
return $this->suggests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the releaseDate
|
||||
*
|
||||
* @param DateTime $releaseDate
|
||||
*/
|
||||
public function setReleaseDate(\DateTime $releaseDate)
|
||||
{
|
||||
$this->releaseDate = $releaseDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getReleaseDate()
|
||||
{
|
||||
return $this->releaseDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the keywords
|
||||
*
|
||||
* @param array $keywords
|
||||
*/
|
||||
public function setKeywords(array $keywords)
|
||||
{
|
||||
$this->keywords = $keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getKeywords()
|
||||
{
|
||||
return $this->keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authors
|
||||
*
|
||||
* @param array $authors
|
||||
*/
|
||||
public function setAuthors(array $authors)
|
||||
{
|
||||
$this->authors = $authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getAuthors()
|
||||
{
|
||||
return $this->authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the description
|
||||
*
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the homepage
|
||||
*
|
||||
* @param string $homepage
|
||||
*/
|
||||
public function setHomepage($homepage)
|
||||
{
|
||||
$this->homepage = $homepage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getHomepage()
|
||||
{
|
||||
return $this->homepage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimumStability
|
||||
*
|
||||
* @param string $minimumStability
|
||||
*/
|
||||
public function setMinimumStability($minimumStability)
|
||||
{
|
||||
$this->minimumStability = $minimumStability;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMinimumStability()
|
||||
{
|
||||
return $this->minimumStability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stabilityFlags
|
||||
*
|
||||
* @param array $stabilityFlags
|
||||
*/
|
||||
public function setStabilityFlags(array $stabilityFlags)
|
||||
{
|
||||
$this->stabilityFlags = $stabilityFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getStabilityFlags()
|
||||
{
|
||||
return $this->stabilityFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the references
|
||||
*
|
||||
* @param array $references
|
||||
*/
|
||||
public function setReferences(array $references)
|
||||
{
|
||||
$this->references = $references;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getReferences()
|
||||
{
|
||||
return $this->references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autoload mapping
|
||||
*
|
||||
|
@ -691,22 +502,4 @@ class MemoryPackage extends BasePackage
|
|||
{
|
||||
return $this->includePaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the support information
|
||||
*
|
||||
* @param array $support
|
||||
*/
|
||||
public function setSupport(array $support)
|
||||
{
|
||||
$this->support = $support;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSupport()
|
||||
{
|
||||
return $this->support;
|
||||
}
|
||||
}
|
|
@ -12,11 +12,12 @@
|
|||
|
||||
namespace Composer\Package;
|
||||
|
||||
use Composer\Package\LinkConstraint\LinkConstraintInterface;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
* Defines the essential information a package has that is used during solving/installation
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface PackageInterface
|
||||
{
|
||||
|
@ -58,16 +59,6 @@ interface PackageInterface
|
|||
*/
|
||||
public function getId();
|
||||
|
||||
/**
|
||||
* Checks if the package matches the given constraint directly or through
|
||||
* provided or replaced packages
|
||||
*
|
||||
* @param string $name Name of the package to be matched
|
||||
* @param LinkConstraintInterface $constraint The constraint to verify
|
||||
* @return bool Whether this package matches the name and constraint
|
||||
*/
|
||||
public function matches($name, LinkConstraintInterface $constraint);
|
||||
|
||||
/**
|
||||
* Returns whether the package is a development virtual package or a concrete one
|
||||
*
|
||||
|
@ -159,13 +150,6 @@ interface PackageInterface
|
|||
*/
|
||||
public function getDistSha1Checksum();
|
||||
|
||||
/**
|
||||
* Returns the scripts of this package
|
||||
*
|
||||
* @return array array('script name' => array('listeners'))
|
||||
*/
|
||||
public function getScripts();
|
||||
|
||||
/**
|
||||
* Returns the version of this package
|
||||
*
|
||||
|
@ -180,6 +164,13 @@ interface PackageInterface
|
|||
*/
|
||||
public function getPrettyVersion();
|
||||
|
||||
/**
|
||||
* Returns the release date of the package
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getReleaseDate();
|
||||
|
||||
/**
|
||||
* Returns the stability of this package: one of (dev, alpha, beta, RC, stable)
|
||||
*
|
||||
|
@ -187,13 +178,6 @@ interface PackageInterface
|
|||
*/
|
||||
public function getStability();
|
||||
|
||||
/**
|
||||
* Returns the package license, e.g. MIT, BSD, GPL
|
||||
*
|
||||
* @return array The package licenses
|
||||
*/
|
||||
public function getLicense();
|
||||
|
||||
/**
|
||||
* Returns a set of links to packages which need to be installed before
|
||||
* this package can be installed
|
||||
|
@ -262,15 +246,6 @@ interface PackageInterface
|
|||
*/
|
||||
public function getIncludePaths();
|
||||
|
||||
/**
|
||||
* Returns an array of repositories
|
||||
*
|
||||
* {"<type>": {<config key/values>}}
|
||||
*
|
||||
* @return array Repositories
|
||||
*/
|
||||
public function getRepositories();
|
||||
|
||||
/**
|
||||
* Stores a reference to the repository that owns the package
|
||||
*
|
||||
|
@ -285,27 +260,6 @@ interface PackageInterface
|
|||
*/
|
||||
public function getRepository();
|
||||
|
||||
/**
|
||||
* Returns the release date of the package
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getReleaseDate();
|
||||
|
||||
/**
|
||||
* Returns an array of keywords relating to the package
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getKeywords();
|
||||
|
||||
/**
|
||||
* Returns the package description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Returns the package binaries
|
||||
*
|
||||
|
@ -313,22 +267,6 @@ interface PackageInterface
|
|||
*/
|
||||
public function getBinaries();
|
||||
|
||||
/**
|
||||
* Returns the package homepage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHomepage();
|
||||
|
||||
/**
|
||||
* Returns an array of authors of the package
|
||||
*
|
||||
* Each item can contain name/homepage/email keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthors();
|
||||
|
||||
/**
|
||||
* Returns a version this package should be aliased to
|
||||
*
|
||||
|
@ -363,11 +301,4 @@ interface PackageInterface
|
|||
* @return string
|
||||
*/
|
||||
public function getPrettyString();
|
||||
|
||||
/**
|
||||
* Returns the support information
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSupport();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?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\Package;
|
||||
|
||||
use Composer\Package\Version\VersionParser;
|
||||
|
||||
/**
|
||||
* The root package represents the project's composer.json and contains additional metadata
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class RootPackage extends CompletePackage implements RootPackageInterface
|
||||
{
|
||||
protected $minimumStability = 'stable';
|
||||
protected $stabilityFlags = array();
|
||||
protected $references = array();
|
||||
|
||||
/**
|
||||
* Set the minimumStability
|
||||
*
|
||||
* @param string $minimumStability
|
||||
*/
|
||||
public function setMinimumStability($minimumStability)
|
||||
{
|
||||
$this->minimumStability = $minimumStability;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMinimumStability()
|
||||
{
|
||||
return $this->minimumStability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stabilityFlags
|
||||
*
|
||||
* @param array $stabilityFlags
|
||||
*/
|
||||
public function setStabilityFlags(array $stabilityFlags)
|
||||
{
|
||||
$this->stabilityFlags = $stabilityFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getStabilityFlags()
|
||||
{
|
||||
return $this->stabilityFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the references
|
||||
*
|
||||
* @param array $references
|
||||
*/
|
||||
public function setReferences(array $references)
|
||||
{
|
||||
$this->references = $references;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getReferences()
|
||||
{
|
||||
return $this->references;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?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\Package;
|
||||
|
||||
/**
|
||||
* Defines additional fields that are only needed for the root package
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface RootPackageInterface extends CompletePackageInterface
|
||||
{
|
||||
/**
|
||||
* Returns the minimum stability of the package
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMinimumStability();
|
||||
|
||||
/**
|
||||
* Returns the stability flags to apply to dependencies
|
||||
*
|
||||
* array('foo/bar' => 'dev')
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStabilityFlags();
|
||||
|
||||
/**
|
||||
* Returns a set of package names and source references that must be enforced on them
|
||||
*
|
||||
* array('foo/bar' => 'abcd1234')
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReferences();
|
||||
}
|
|
@ -14,6 +14,7 @@ namespace Composer\Package\Version;
|
|||
|
||||
use Composer\Package\BasePackage;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\LinkConstraint\MultiConstraint;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
|
||||
|
@ -164,6 +165,28 @@ class VersionParser
|
|||
return 'dev-'.$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source source package name
|
||||
* @param string $sourceVersion source package version (pretty version ideally)
|
||||
* @param string $description link description (e.g. requires, replaces, ..)
|
||||
* @param array $links array of package name => constraint mappings
|
||||
* @return Link[]
|
||||
*/
|
||||
public function parseLinks($source, $sourceVersion, $description, $links)
|
||||
{
|
||||
$res = array();
|
||||
foreach ($links as $target => $constraint) {
|
||||
if ('self.version' === $constraint) {
|
||||
$parsedConstraint = $this->parseConstraints($sourceVersion);
|
||||
} else {
|
||||
$parsedConstraint = $this->parseConstraints($constraint);
|
||||
}
|
||||
$res[] = new Link($source, $target, $parsedConstraint, $description, $constraint);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses as constraint string into LinkConstraint objects
|
||||
*
|
||||
|
|
|
@ -112,6 +112,20 @@ class ArrayRepository implements RepositoryInterface
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function filterPackages($callback, $class = 'Composer\Package\Package')
|
||||
{
|
||||
foreach ($this->getPackages() as $package) {
|
||||
if (false === $callback($package)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function createAliasPackage(PackageInterface $package, $alias = null, $prettyAlias = null)
|
||||
{
|
||||
return new AliasPackage($package, $alias ?: $package->getAlias(), $prettyAlias ?: $package->getPrettyAlias());
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Composer\Repository;
|
|||
|
||||
use Composer\Package\Loader\ArrayLoader;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Cache;
|
||||
use Composer\Config;
|
||||
|
@ -23,14 +24,16 @@ use Composer\Util\RemoteFilesystem;
|
|||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class ComposerRepository extends ArrayRepository implements NotifiableRepositoryInterface
|
||||
class ComposerRepository extends ArrayRepository implements NotifiableRepositoryInterface, StreamableRepositoryInterface
|
||||
{
|
||||
protected $config;
|
||||
protected $url;
|
||||
protected $io;
|
||||
protected $packages;
|
||||
protected $cache;
|
||||
protected $notifyUrl;
|
||||
protected $loader;
|
||||
private $rawData;
|
||||
private $minimalPackages;
|
||||
|
||||
public function __construct(array $repoConfig, IOInterface $io, Config $config)
|
||||
{
|
||||
|
@ -47,6 +50,7 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
$this->url = $repoConfig['url'];
|
||||
$this->io = $io;
|
||||
$this->cache = new Cache($io, $config->get('home').'/cache/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url));
|
||||
$this->loader = new ArrayLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,10 +82,110 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
@file_get_contents($url, false, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMinimalPackages()
|
||||
{
|
||||
if (isset($this->minimalPackages)) {
|
||||
return $this->minimalPackages;
|
||||
}
|
||||
|
||||
if (null === $this->rawData) {
|
||||
$this->rawData = $this->loadDataFromServer();
|
||||
}
|
||||
|
||||
$this->minimalPackages = array();
|
||||
$versionParser = new VersionParser;
|
||||
|
||||
foreach ($this->rawData as $package) {
|
||||
$version = !empty($package['version_normalized']) ? $package['version_normalized'] : $versionParser->normalize($package['version']);
|
||||
$data = array(
|
||||
'name' => strtolower($package['name']),
|
||||
'repo' => $this,
|
||||
'version' => $version,
|
||||
'raw' => $package,
|
||||
);
|
||||
if (!empty($package['replace'])) {
|
||||
$data['replace'] = $package['replace'];
|
||||
}
|
||||
if (!empty($package['provide'])) {
|
||||
$data['provide'] = $package['provide'];
|
||||
}
|
||||
|
||||
// add branch aliases
|
||||
if ($aliasNormalized = $this->loader->getBranchAlias($package)) {
|
||||
$data['alias'] = preg_replace('{(\.9{7})+}', '.x', $aliasNormalized);
|
||||
$data['alias_normalized'] = $aliasNormalized;
|
||||
}
|
||||
|
||||
$this->minimalPackages[] = $data;
|
||||
}
|
||||
|
||||
return $this->minimalPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function filterPackages($callback, $class = 'Composer\Package\Package')
|
||||
{
|
||||
if (null === $this->rawData) {
|
||||
$this->rawData = $this->loadDataFromServer();
|
||||
}
|
||||
|
||||
foreach ($this->rawData as $package) {
|
||||
if (false === $callback($package = $this->loader->load($package, $class))) {
|
||||
return false;
|
||||
}
|
||||
if ($package->getAlias()) {
|
||||
if (false === $callback($this->createAliasPackage($package))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function loadPackage(array $data)
|
||||
{
|
||||
$package = $this->loader->load($data['raw'], 'Composer\Package\Package');
|
||||
$package->setRepository($this);
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function loadAliasPackage(array $data, PackageInterface $aliasOf)
|
||||
{
|
||||
$aliasPackage = $this->createAliasPackage($aliasOf, $data['version'], $data['alias']);
|
||||
$aliasPackage->setRepository($this);
|
||||
|
||||
return $aliasPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$repoData = $this->loadDataFromServer();
|
||||
|
||||
foreach ($repoData as $package) {
|
||||
$this->addPackage($this->loader->load($package, 'Composer\Package\CompletePackage'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadDataFromServer()
|
||||
{
|
||||
if (!extension_loaded('openssl') && 'https' === substr($this->url, 0, 5)) {
|
||||
throw new \RuntimeException('You must enable the openssl extension in your php.ini to load information from '.$this->url);
|
||||
}
|
||||
|
@ -109,17 +213,18 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
}
|
||||
}
|
||||
|
||||
$loader = new ArrayLoader();
|
||||
$this->loadRepository($loader, $data);
|
||||
return $this->loadIncludes($data);
|
||||
}
|
||||
|
||||
protected function loadRepository(ArrayLoader $loader, $data)
|
||||
protected function loadIncludes($data)
|
||||
{
|
||||
$packages = array();
|
||||
|
||||
// legacy repo handling
|
||||
if (!isset($data['packages']) && !isset($data['includes'])) {
|
||||
foreach ($data as $pkg) {
|
||||
foreach ($pkg['versions'] as $metadata) {
|
||||
$this->addPackage($loader->load($metadata));
|
||||
$packages[] = $metadata;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +234,7 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
if (isset($data['packages'])) {
|
||||
foreach ($data['packages'] as $package => $versions) {
|
||||
foreach ($versions as $version => $metadata) {
|
||||
$this->addPackage($loader->load($metadata));
|
||||
$packages[] = $metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,8 +248,10 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
$includedData = $json->read();
|
||||
$this->cache->write($include, json_encode($includedData));
|
||||
}
|
||||
$this->loadRepository($loader, $includedData);
|
||||
$packages = array_merge($packages, $this->loadIncludes($includedData));
|
||||
}
|
||||
}
|
||||
|
||||
return $packages;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,20 @@ class CompositeRepository implements RepositoryInterface
|
|||
return call_user_func_array('array_merge', $packages);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function filterPackages($callback, $class = 'Composer\Package\Package')
|
||||
{
|
||||
foreach ($this->repositories as $repository) {
|
||||
if (false === $repository->filterPackages($callback, $class)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ use Composer\Util\RemoteFilesystem;
|
|||
/**
|
||||
* PEAR Channel package reader.
|
||||
*
|
||||
* Reads channel packages info from and builds MemoryPackage's
|
||||
* Reads channel packages info from and builds Package's
|
||||
*
|
||||
* @author Alexey Prilipko <palex@farpost.com>
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Composer\Repository;
|
|||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Repository\Pear\ChannelReader;
|
||||
use Composer\Package\MemoryPackage;
|
||||
use Composer\Package\CompletePackage;
|
||||
use Composer\Repository\Pear\ChannelInfo;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
|
@ -81,10 +81,10 @@ class PearRepository extends ArrayRepository
|
|||
}
|
||||
|
||||
/**
|
||||
* Builds MemoryPackages from PEAR package definition data.
|
||||
* Builds CompletePackages from PEAR package definition data.
|
||||
*
|
||||
* @param ChannelInfo $channelInfo
|
||||
* @return MemoryPackage
|
||||
* @return CompletePackage
|
||||
*/
|
||||
private function buildComposerPackages(ChannelInfo $channelInfo, VersionParser $versionParser)
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ class PearRepository extends ArrayRepository
|
|||
}
|
||||
}
|
||||
|
||||
$package = new MemoryPackage($composerPackageName, $normalizedVersion, $version);
|
||||
$package = new CompletePackage($composerPackageName, $normalizedVersion, $version);
|
||||
$package->setType('pear-library');
|
||||
$package->setDescription($packageDefinition->getDescription());
|
||||
$package->setDistType('file');
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace Composer\Repository;
|
||||
|
||||
use Composer\Package\MemoryPackage;
|
||||
use Composer\Package\CompletePackage;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
|
||||
/**
|
||||
|
@ -34,7 +34,7 @@ class PlatformRepository extends ArrayRepository
|
|||
$version = $versionParser->normalize($prettyVersion);
|
||||
}
|
||||
|
||||
$php = new MemoryPackage('php', $version, $prettyVersion);
|
||||
$php = new CompletePackage('php', $version, $prettyVersion);
|
||||
$php->setDescription('The PHP interpreter');
|
||||
parent::addPackage($php);
|
||||
|
||||
|
@ -55,7 +55,7 @@ class PlatformRepository extends ArrayRepository
|
|||
$version = $versionParser->normalize($prettyVersion);
|
||||
}
|
||||
|
||||
$ext = new MemoryPackage('ext-'.$name, $version, $prettyVersion);
|
||||
$ext = new CompletePackage('ext-'.$name, $version, $prettyVersion);
|
||||
$ext->setDescription('The '.$name.' PHP extension');
|
||||
parent::addPackage($ext);
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class PlatformRepository extends ArrayRepository
|
|||
continue;
|
||||
}
|
||||
|
||||
$lib = new MemoryPackage('lib-'.$name, $version, $prettyVersion);
|
||||
$lib = new CompletePackage('lib-'.$name, $version, $prettyVersion);
|
||||
$lib->setDescription('The '.$name.' PHP library');
|
||||
parent::addPackage($lib);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,20 @@ interface RepositoryInterface extends \Countable
|
|||
*/
|
||||
public function findPackages($name, $version = null);
|
||||
|
||||
/**
|
||||
* Filters all the packages through a callback
|
||||
*
|
||||
* The packages are not guaranteed to be instances in the repository
|
||||
* and this can only be used for streaming through a list of packages.
|
||||
*
|
||||
* If the callback returns false, the process stops
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param string $class
|
||||
* @return bool false if the process was interrupted, true otherwise
|
||||
*/
|
||||
public function filterPackages($callback, $class = 'Composer\Package\Package');
|
||||
|
||||
/**
|
||||
* Returns list of registered packages.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?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\Repository;
|
||||
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\PackageInterface;
|
||||
|
||||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface StreamableRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Return partial package data without loading them all to save on memory
|
||||
*
|
||||
* The function must return an array of package arrays.
|
||||
*
|
||||
* The package array must contain the following fields:
|
||||
* - name: package name (normalized/lowercased)
|
||||
* - repo: reference to the repository instance
|
||||
* - version: normalized version
|
||||
* - replace: array of package name => version constraint, optional
|
||||
* - provide: array of package name => version constraint, optional
|
||||
* - alias: pretty alias that this package should be aliased to, optional
|
||||
* - alias_normalized: normalized alias that this package should be aliased to, optional
|
||||
*
|
||||
* Any additional information can be returned and will be sent back
|
||||
* into loadPackage/loadAliasPackage for completing the package loading
|
||||
* when it's needed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMinimalPackages();
|
||||
|
||||
/**
|
||||
* Loads a package from minimal info of the package
|
||||
*
|
||||
* @param array $data the minimal info as was returned by getMinimalPackage
|
||||
* @return PackageInterface
|
||||
*/
|
||||
public function loadPackage(array $data);
|
||||
|
||||
/**
|
||||
* Loads an alias package from minimal info of the package
|
||||
*
|
||||
* @param array $data the minimal info as was returned by getMinimalPackage
|
||||
* @param PackageInterface $aliasOf the package which this alias is an alias of
|
||||
* @return AliasPackage
|
||||
*/
|
||||
public function loadAliasPackage(array $data, PackageInterface $aliasOf);
|
||||
}
|
|
@ -15,7 +15,7 @@ namespace Composer\Test\Autoload;
|
|||
use Composer\Autoload\AutoloadGenerator;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\MemoryPackage;
|
||||
use Composer\Package\Package;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
class AutoloadGeneratorTest extends TestCase
|
||||
|
@ -76,7 +76,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testMainPackageAutoloading()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => array('src/', 'lib/')),
|
||||
'classmap' => array('composersrc/'),
|
||||
|
@ -101,7 +101,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
{
|
||||
$this->vendorDir = $this->workingDir;
|
||||
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||
'classmap' => array('composersrc/'),
|
||||
|
@ -124,7 +124,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testMainPackageAutoloadingAlternativeVendorDir()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||
'classmap' => array('composersrc/'),
|
||||
|
@ -147,7 +147,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testMainPackageAutoloadingWithTargetDir()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main\\Foo' => '', 'Main\\Bar' => ''),
|
||||
));
|
||||
|
@ -166,11 +166,11 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testVendorsAutoloading()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
|
||||
$packages = array();
|
||||
$packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0');
|
||||
$packages[] = $a = new Package('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new Package('b/b', '1.0', '1.0');
|
||||
$packages[] = $c = new AliasPackage($b, '1.2', '1.2');
|
||||
$a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/')));
|
||||
$b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/')));
|
||||
|
@ -191,11 +191,11 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testVendorsClassMapAutoloading()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
|
||||
$packages = array();
|
||||
$packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0');
|
||||
$packages[] = $a = new Package('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new Package('b/b', '1.0', '1.0');
|
||||
$a->setAutoload(array('classmap' => array('src/')));
|
||||
$b->setAutoload(array('classmap' => array('src/', 'lib/')));
|
||||
|
||||
|
@ -226,12 +226,12 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testClassMapAutoloadingEmptyDirAndExactFile()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
|
||||
$packages = array();
|
||||
$packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0');
|
||||
$packages[] = $c = new MemoryPackage('c/c', '1.0', '1.0');
|
||||
$packages[] = $a = new Package('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new Package('b/b', '1.0', '1.0');
|
||||
$packages[] = $c = new Package('c/c', '1.0', '1.0');
|
||||
$a->setAutoload(array('classmap' => array('')));
|
||||
$b->setAutoload(array('classmap' => array('test.php')));
|
||||
$c->setAutoload(array('classmap' => array('./')));
|
||||
|
@ -263,12 +263,12 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testFilesAutoloadGeneration()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array('files' => array('root.php')));
|
||||
|
||||
$packages = array();
|
||||
$packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0');
|
||||
$packages[] = $a = new Package('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new Package('b/b', '1.0', '1.0');
|
||||
$a->setAutoload(array('files' => array('test.php')));
|
||||
$b->setAutoload(array('files' => array('test2.php')));
|
||||
|
||||
|
@ -297,12 +297,12 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
public function testOverrideVendorsAutoloading()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array('psr-0' => array('A\\B' => $this->workingDir.'/lib')));
|
||||
|
||||
$packages = array();
|
||||
$packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0');
|
||||
$packages[] = $a = new Package('a/a', '1.0', '1.0');
|
||||
$packages[] = $b = new Package('b/b', '1.0', '1.0');
|
||||
$a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/')));
|
||||
$b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/')));
|
||||
|
||||
|
@ -356,16 +356,16 @@ EOF;
|
|||
|
||||
public function testIncludePathFileGeneration()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$packages = array();
|
||||
|
||||
$a = new MemoryPackage("a/a", "1.0", "1.0");
|
||||
$a = new Package("a/a", "1.0", "1.0");
|
||||
$a->setIncludePaths(array("lib/"));
|
||||
|
||||
$b = new MemoryPackage("b/b", "1.0", "1.0");
|
||||
$b = new Package("b/b", "1.0", "1.0");
|
||||
$b->setIncludePaths(array("library"));
|
||||
|
||||
$c = new MemoryPackage("c", "1.0", "1.0");
|
||||
$c = new Package("c", "1.0", "1.0");
|
||||
$c->setIncludePaths(array("library"));
|
||||
|
||||
$packages[] = $a;
|
||||
|
@ -393,10 +393,10 @@ EOF;
|
|||
|
||||
public function testIncludePathsArePrependedInAutoloadFile()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$packages = array();
|
||||
|
||||
$a = new MemoryPackage("a/a", "1.0", "1.0");
|
||||
$a = new Package("a/a", "1.0", "1.0");
|
||||
$a->setIncludePaths(array("lib/"));
|
||||
|
||||
$packages[] = $a;
|
||||
|
@ -426,10 +426,10 @@ EOF;
|
|||
|
||||
public function testIncludePathFileWithoutPathsIsSkipped()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$packages = array();
|
||||
|
||||
$a = new MemoryPackage("a/a", "1.0", "1.0");
|
||||
$a = new Package("a/a", "1.0", "1.0");
|
||||
$packages[] = $a;
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
|
|
|
@ -18,7 +18,7 @@ class ComposerTest extends TestCase
|
|||
public function testSetGetPackage()
|
||||
{
|
||||
$composer = new Composer();
|
||||
$package = $this->getMock('Composer\Package\PackageInterface');
|
||||
$package = $this->getMock('Composer\Package\RootPackageInterface');
|
||||
$composer->setPackage($package);
|
||||
|
||||
$this->assertSame($package, $composer->getPackage());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
--TEST--
|
||||
Update aliased package to non-aliased version
|
||||
Update aliased package does not mess up the lock file
|
||||
--COMPOSER--
|
||||
{
|
||||
"repositories": [
|
||||
|
@ -12,12 +12,22 @@ Update aliased package to non-aliased version
|
|||
"source": { "reference": "master", "type": "git", "url": "" }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "package",
|
||||
"package": [
|
||||
{
|
||||
"name": "a/a", "version": "dev-master",
|
||||
"extra": { "branch-alias": { "dev-master": "1.0.x-dev" } },
|
||||
"source": { "reference": "lowpriomaster", "type": "git", "url": "" }
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"a/a": "1.*"
|
||||
},
|
||||
"minimum-stability": "stable"
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
--LOCK--
|
||||
{
|
||||
|
@ -27,7 +37,7 @@ Update aliased package to non-aliased version
|
|||
],
|
||||
"packages-dev": null,
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": []
|
||||
}
|
||||
--INSTALLED--
|
||||
|
@ -48,7 +58,7 @@ update
|
|||
],
|
||||
"packages-dev": null,
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": []
|
||||
}
|
||||
--EXPECT--
|
||||
|
|
|
@ -235,7 +235,7 @@ class LibraryInstallerTest extends TestCase
|
|||
|
||||
protected function createPackageMock()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\Package\MemoryPackage')
|
||||
return $this->getMockBuilder('Composer\Package\Package')
|
||||
->setConstructorArgs(array(md5(rand()), '1.0.0.0', '1.0.0'))
|
||||
->getMock();
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ class MetapackageInstallerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
private function createPackageMock()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\Package\MemoryPackage')
|
||||
return $this->getMockBuilder('Composer\Package\Package')
|
||||
->setConstructorArgs(array(md5(rand()), '1.0.0.0', '1.0.0'))
|
||||
->getMock();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use Composer\Config;
|
|||
use Composer\Json\JsonFile;
|
||||
use Composer\Repository\ArrayRepository;
|
||||
use Composer\Repository\RepositoryManager;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\Locker;
|
||||
use Composer\Test\Mock\FactoryMock;
|
||||
|
@ -32,7 +32,7 @@ class InstallerTest extends TestCase
|
|||
/**
|
||||
* @dataProvider provideInstaller
|
||||
*/
|
||||
public function testInstaller(PackageInterface $rootPackage, $repositories, array $options)
|
||||
public function testInstaller(RootPackageInterface $rootPackage, $repositories, array $options)
|
||||
{
|
||||
$io = $this->getMock('Composer\IO\IOInterface');
|
||||
|
||||
|
@ -80,7 +80,7 @@ class InstallerTest extends TestCase
|
|||
// when A requires B and B requires A, and A is a non-published root package
|
||||
// the install of B should succeed
|
||||
|
||||
$a = $this->getPackage('A', '1.0.0');
|
||||
$a = $this->getPackage('A', '1.0.0', 'Composer\Package\RootPackage');
|
||||
$a->setRequires(array(
|
||||
new Link('A', 'B', $this->getVersionConstraint('=', '1.0.0')),
|
||||
));
|
||||
|
@ -100,7 +100,7 @@ class InstallerTest extends TestCase
|
|||
// #480: when A requires B and B requires A, and A is a published root package
|
||||
// only B should be installed, as A is the root
|
||||
|
||||
$a = $this->getPackage('A', '1.0.0');
|
||||
$a = $this->getPackage('A', '1.0.0', 'Composer\Package\RootPackage');
|
||||
$a->setRequires(array(
|
||||
new Link('A', 'B', $this->getVersionConstraint('=', '1.0.0')),
|
||||
));
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
|
||||
namespace Composer\Test\Package;
|
||||
|
||||
use Composer\Package\MemoryPackage;
|
||||
use Composer\Package\Package;
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
class MemoryPackageTest extends TestCase
|
||||
class CompletePackageTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Memory package naming, versioning, and marshalling semantics provider
|
||||
|
@ -38,11 +38,11 @@ class MemoryPackageTest extends TestCase
|
|||
* Tests memory package naming semantics
|
||||
* @dataProvider providerVersioningSchemes
|
||||
*/
|
||||
public function testMemoryPackageHasExpectedNamingSemantics($name, $version)
|
||||
public function testPackageHasExpectedNamingSemantics($name, $version)
|
||||
{
|
||||
$versionParser = new VersionParser();
|
||||
$normVersion = $versionParser->normalize($version);
|
||||
$package = new MemoryPackage($name, $normVersion, $version);
|
||||
$package = new Package($name, $normVersion, $version);
|
||||
$this->assertEquals(strtolower($name), $package->getName());
|
||||
}
|
||||
|
||||
|
@ -50,11 +50,11 @@ class MemoryPackageTest extends TestCase
|
|||
* Tests memory package versioning semantics
|
||||
* @dataProvider providerVersioningSchemes
|
||||
*/
|
||||
public function testMemoryPackageHasExpectedVersioningSemantics($name, $version)
|
||||
public function testPackageHasExpectedVersioningSemantics($name, $version)
|
||||
{
|
||||
$versionParser = new VersionParser();
|
||||
$normVersion = $versionParser->normalize($version);
|
||||
$package = new MemoryPackage($name, $normVersion, $version);
|
||||
$package = new Package($name, $normVersion, $version);
|
||||
$this->assertEquals($version, $package->getPrettyVersion());
|
||||
$this->assertEquals($normVersion, $package->getVersion());
|
||||
}
|
||||
|
@ -63,11 +63,11 @@ class MemoryPackageTest extends TestCase
|
|||
* Tests memory package marshalling/serialization semantics
|
||||
* @dataProvider providerVersioningSchemes
|
||||
*/
|
||||
public function testMemoryPackageHasExpectedMarshallingSemantics($name, $version)
|
||||
public function testPackageHasExpectedMarshallingSemantics($name, $version)
|
||||
{
|
||||
$versionParser = new VersionParser();
|
||||
$normVersion = $versionParser->normalize($version);
|
||||
$package = new MemoryPackage($name, $normVersion, $version);
|
||||
$package = new Package($name, $normVersion, $version);
|
||||
$this->assertEquals(strtolower($name).'-'.$normVersion, (string) $package);
|
||||
}
|
||||
|
|
@ -23,14 +23,14 @@ class ArrayDumperTest extends \PHPUnit_Framework_TestCase
|
|||
*/
|
||||
private $dumper;
|
||||
/**
|
||||
* @var \Composer\Package\PackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @var \Composer\Package\CompletePackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $package;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->dumper = new ArrayDumper();
|
||||
$this->package = $this->getMock('Composer\Package\PackageInterface');
|
||||
$this->package = $this->getMock('Composer\Package\CompletePackageInterface');
|
||||
}
|
||||
|
||||
public function testRequiredInformation()
|
||||
|
|
|
@ -16,7 +16,7 @@ use Composer\Test\TestCase;
|
|||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\MemoryPackage;
|
||||
use Composer\Package\CompletePackage;
|
||||
use Composer\Test\Mock\RemoteFilesystemMock;
|
||||
|
||||
class ChannelReaderTest extends TestCase
|
||||
|
@ -117,7 +117,7 @@ class ChannelReaderTest extends TestCase
|
|||
|
||||
$packages = $ref->invoke($reader, $channelInfo, new VersionParser());
|
||||
|
||||
$expectedPackage = new MemoryPackage('pear-test.loc/sample', '1.0.0.1' , '1.0.0.1');
|
||||
$expectedPackage = new CompletePackage('pear-test.loc/sample', '1.0.0.1' , '1.0.0.1');
|
||||
$expectedPackage->setType('pear-library');
|
||||
$expectedPackage->setDistType('file');
|
||||
$expectedPackage->setDescription('description');
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
namespace Composer\Test;
|
||||
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Package\MemoryPackage;
|
||||
use Composer\Package\Package;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Util\Filesystem;
|
||||
|
@ -43,11 +43,11 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
|
|||
return $constraint;
|
||||
}
|
||||
|
||||
protected function getPackage($name, $version)
|
||||
protected function getPackage($name, $version, $class = 'Composer\Package\Package')
|
||||
{
|
||||
$normVersion = self::getVersionParser()->normalize($version);
|
||||
|
||||
return new MemoryPackage($name, $normVersion, $version);
|
||||
return new $class($name, $normVersion, $version);
|
||||
}
|
||||
|
||||
protected function getAliasPackage($package, $version)
|
||||
|
|
Loading…
Reference in New Issue