1
0
Fork 0
Conflicts:
	README.md
pull/151/head
digitalkaoz 2012-02-14 22:58:12 +01:00
commit 110bd8c23f
28 changed files with 526 additions and 259 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/.buildpath /.buildpath
/composer.phar /composer.phar
/vendor /vendor
/nbproject

View File

@ -12,7 +12,10 @@ Installation / Usage
1. Download the [`composer.phar`](http://getcomposer.org/composer.phar) executable or use the installer. 1. Download the [`composer.phar`](http://getcomposer.org/composer.phar) executable or use the installer.
$ curl http://getcomposer.org/installer | php ``` sh
$ curl -s http://getcomposer.org/installer | php
```
2. Create a composer.json defining your dependencies. Note that this example is 2. Create a composer.json defining your dependencies. Note that this example is
a short version for applications that are not meant to be published as packages a short version for applications that are not meant to be published as packages
@ -46,10 +49,11 @@ Since composer works with the current working directory it is possible to instal
in a system wide way. in a system wide way.
1. Change into a directory in your path like `cd /usr/local/bin` 1. Change into a directory in your path like `cd /usr/local/bin`
2. Get composer `curl http://getcomposer.org/installer | php` 2. Get composer `curl -s http://getcomposer.org/installer | php`
3. Make the phar executeable `chmod a+x composer.phar` 3. Make the phar executeable `chmod a+x composer.phar`
3. Change into a project directory `cd /path/to/my/project` 4. Change into a project directory `cd /path/to/my/project`
4. Use composer as you normally would `composer.phar install` 5. Use composer as you normally would `composer.phar install`
6. Optionally you can rename the composer.phar to composer to make it easier
Global installation of composer (via homebrew) Global installation of composer (via homebrew)
---------------------------------------------- ----------------------------------------------

View File

@ -27,7 +27,7 @@ Request: install A
Packages Repo1.Av1, Repo2.Av1 Packages Repo1.Av1, Repo2.Av1
* priority(Repo1) >= priority(Repo2) => (Repo1.Av1, Repo2.Av1) * priority(Repo1) >= priority(Repo2) => (Repo1.Av1, Repo2.Av1)
* priority(Repo2) < priority(Repo2) => (Repo2.Av1, Repo1.Av1) * priority(Repo1) < priority(Repo2) => (Repo2.Av1, Repo1.Av1)
### Virtual Packages (provides) ### Virtual Packages (provides)
@ -39,7 +39,7 @@ Packages Av1, Bv1
Request: install X Request: install X
* priority(Av1.repo) >= priority(Bv1.repo) => (Av1, Bv1) * priority(Av1.repo) >= priority(Bv1.repo) => (Av1, Bv1)
* priority(Av1.repo) < priority(Bv1.repo) => (Bv1, Av1) * priority(Av1.repo) < priority(Bv1.repo) => (Bv1, Av1)
### Package replacements ### Package replacements
@ -49,8 +49,7 @@ Packages: Av1, Bv2
Request: install A Request: install A
* priority(Av1.repo) > priority(Bv2.repo) => (Av1, Bv2) * priority(Av1.repo) >= priority(Bv2.repo) => (Av1, Bv2)
* priority(Av1.repo) = priority(Bv2.repo) => (Av1, Bv2) * priority(Av1.repo) < priority(Bv2.repo) => (Bv2, Av1)
* priority(Av1.repo) < priority(Bv2.repo) => (Bv2, Av1)
Bv2.version is ignored, only the replacement version for A matters. Bv2 version is ignored, only the replacement version for A matters.

View File

@ -0,0 +1,22 @@
# Packagist Update Schedule
## How often does Packagist crawl newly added packages?
New packages will be crawled **within ten minutes**.
## How often does Packagist crawl existing packages?
Existing packages will be crawled **every hour**.
## How often does the Packagist search index update?
The search index is updated **every five minutes**. It will index (or reindex)
any package that has been crawled since the last time the search
indexer ran.
## Can Packagist be triggered to recrawl a package (on commit or by other means)?
Not yet. :) See [#84](https://github.com/composer/packagist/issues/84).

View File

@ -17,7 +17,7 @@ use Composer\Json\JsonFile;
use Composer\Package\Loader\JsonLoader; use Composer\Package\Loader\JsonLoader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Downloader\Util\Filesystem; use Composer\Util\Filesystem;
/** /**
* @author Igor Wiedler <igor@wiedler.ch> * @author Igor Wiedler <igor@wiedler.ch>

View File

@ -26,6 +26,9 @@ namespace Composer\Autoload;
* // activate the autoloader * // activate the autoloader
* $loader->register(); * $loader->register();
* *
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component * In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance), * namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/ * the autoloader will first look for the class under the component/
@ -41,6 +44,7 @@ class ClassLoader
{ {
private $prefixes = array(); private $prefixes = array();
private $fallbackDirs = array(); private $fallbackDirs = array();
private $useIncludePath = false;
public function getPrefixes() public function getPrefixes()
{ {
@ -61,7 +65,9 @@ class ClassLoader
public function add($prefix, $paths) public function add($prefix, $paths)
{ {
if (!$prefix) { if (!$prefix) {
$this->fallbackDirs = (array) $paths; foreach ((array) $paths as $path) {
$this->fallbackDirs[] = $path;
}
return; return;
} }
if (isset($this->prefixes[$prefix])) { if (isset($this->prefixes[$prefix])) {
@ -74,6 +80,27 @@ class ClassLoader
} }
} }
/**
* Turns on searching the include for class files.
*
* @param Boolean $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return Boolean
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/** /**
* Registers this instance as an autoloader. * Registers this instance as an autoloader.
* *
@ -121,7 +148,7 @@ class ClassLoader
if (false !== $pos = strrpos($class, '\\')) { if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name // namespaced class name
$classPath = DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)); $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
$className = substr($class, $pos + 1); $className = substr($class, $pos + 1);
} else { } else {
// PEAR-like class name // PEAR-like class name
@ -129,22 +156,26 @@ class ClassLoader
$className = $class; $className = $class;
} }
$classPath .= DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
foreach ($this->prefixes as $prefix => $dirs) { foreach ($this->prefixes as $prefix => $dirs) {
foreach ($dirs as $dir) { foreach ($dirs as $dir) {
if (0 === strpos($class, $prefix)) { if (0 === strpos($class, $prefix)) {
if (file_exists($dir . $classPath)) { if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
return $dir . $classPath; return $dir . DIRECTORY_SEPARATOR . $classPath;
} }
} }
} }
} }
foreach ($this->fallbackDirs as $dir) { foreach ($this->fallbackDirs as $dir) {
if (file_exists($dir . $classPath)) { if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
return $dir . $classPath; return $dir . DIRECTORY_SEPARATOR . $classPath;
} }
} }
if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) {
return $file;
}
} }
} }

View File

@ -25,8 +25,8 @@ abstract class Command extends BaseCommand
/** /**
* @return \Composer\Composer * @return \Composer\Composer
*/ */
protected function getComposer() protected function getComposer($required = true)
{ {
return $this->getApplication()->getComposer(); return $this->getApplication()->getComposer($required);
} }
} }

View File

@ -1,90 +0,0 @@
<?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\Command;
use Composer\Autoload\AutoloadGenerator;
use Composer\DependencyResolver;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Request;
use Composer\DependencyResolver\Operation;
use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class DebugPackagesCommand extends Command
{
protected function configure()
{
$this
->setName('debug:packages')
->setDescription('Lists all existing packages and their version')
->setDefinition(array(
new InputOption('local', null, InputOption::VALUE_NONE, 'list locally installed packages only'),
new InputOption('platform', null, InputOption::VALUE_NONE, 'list platform packages only'),
))
->setHelp(<<<EOT
<info>php composer.phar debug:packages</info>
EOT
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$composer = $this->getComposer();
// create local repo, this contains all packages that are installed in the local project
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
// create installed repo, this contains all local packages + platform packages (php & extensions)
$installedRepo = new CompositeRepository(array($localRepo, new PlatformRepository()));
if ($input->getOption('local')) {
foreach ($localRepo->getPackages() as $package) {
$output->writeln('<info>local:</info> ' . $package->getPrettyName() . ' ' . $package->getPrettyVersion() . '<comment> (' . $package->getVersion() . ')</comment>');
}
return;
}
if ($input->getOption('platform')) {
$repos = array_diff($installedRepo->getPackages(), $localRepo->getPackages());
foreach ($repos as $package) {
$output->writeln('<info>plattform:</info> ' . $package->getPrettyName() . ' ' . $package->getPrettyVersion() . '<comment> (' . $package->getVersion() . ')</comment>');
}
return;
}
foreach ($installedRepo->getPackages() as $package) {
if ($localRepo->hasPackage($package)) {
$output->writeln('<info>installed:</info> ' . $package->getPrettyName() . ' ' . $package->getPrettyVersion() . '<comment> (' . $package->getVersion() . ')</comment>');
} else {
$output->writeln('<info>platform:</info> ' . $package->getPrettyName() . ' ' . $package->getPrettyVersion() . '<comment> (' . $package->getName() . ' ' . $package->getVersion() . ')</comment>');
}
}
foreach ($composer->getRepositoryManager()->getRepositories() as $repository) {
foreach ($repository->getPackages() as $package) {
$output->writeln('<comment>available:</comment> ' . $package->getPrettyName() . ' ' . $package->getPrettyVersion() . '<comment> (' . $package->getName() . ' ' . $package->getVersion() . ')</comment>');
}
}
}
}

View File

@ -46,7 +46,7 @@ class InstallCommand extends Command
->setName('install') ->setName('install')
->setDescription('Parses the composer.json file and downloads the needed dependencies.') ->setDescription('Parses the composer.json file and downloads the needed dependencies.')
->setDefinition(array( ->setDefinition(array(
new InputOption('dev', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'), new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'), new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
new InputOption('no-install-recommends', null, InputOption::VALUE_NONE, 'Do not install recommended packages (ignored when installing from an existing lock file).'), new InputOption('no-install-recommends', null, InputOption::VALUE_NONE, 'Do not install recommended packages (ignored when installing from an existing lock file).'),
new InputOption('install-suggests', null, InputOption::VALUE_NONE, 'Also install suggested packages (ignored when installing from an existing lock file).'), new InputOption('install-suggests', null, InputOption::VALUE_NONE, 'Also install suggested packages (ignored when installing from an existing lock file).'),
@ -73,7 +73,7 @@ EOT
$io, $io,
$composer, $composer,
$eventDispatcher, $eventDispatcher,
(Boolean)$input->getOption('dev'), (Boolean)$input->getOption('prefer-source'),
(Boolean)$input->getOption('dry-run'), (Boolean)$input->getOption('dry-run'),
(Boolean)$input->getOption('verbose'), (Boolean)$input->getOption('verbose'),
(Boolean)$input->getOption('no-install-recommends'), (Boolean)$input->getOption('no-install-recommends'),

View File

@ -13,6 +13,7 @@
namespace Composer\Command; namespace Composer\Command;
use Composer\Composer; use Composer\Composer;
use Composer\Util\StreamContextFactory;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
@ -39,7 +40,9 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$latest = trim(file_get_contents('http://getcomposer.org/version')); $ctx = StreamContextFactory::getContext();
$latest = trim(file_get_contents('http://getcomposer.org/version'), false, $ctx);
if (Composer::VERSION !== $latest) { if (Composer::VERSION !== $latest) {
$output->writeln(sprintf("Updating to version <info>%s</info>.", $latest)); $output->writeln(sprintf("Updating to version <info>%s</info>.", $latest));
@ -47,7 +50,7 @@ EOT
$remoteFilename = 'http://getcomposer.org/composer.phar'; $remoteFilename = 'http://getcomposer.org/composer.phar';
$localFilename = $_SERVER['argv'][0]; $localFilename = $_SERVER['argv'][0];
file_put_contents($localFilename, file_get_contents($remoteFilename)); copy($remoteFilename, $localFilename, $ctx);
} else { } else {
$output->writeln("<info>You are using the latest composer version.</info>"); $output->writeln("<info>You are using the latest composer version.</info>");
} }

View File

@ -16,7 +16,12 @@ use Composer\Composer;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\ComposerRepository;
use Composer\Repository\RepositoryInterface;
/** /**
* @author Robert Schönthal <seroscho@googlemail.com> * @author Robert Schönthal <seroscho@googlemail.com>
@ -28,14 +33,16 @@ class ShowCommand extends Command
{ {
$this $this
->setName('show') ->setName('show')
->setDescription('Show package details') ->setDescription('Show information about packages')
->setDefinition(array( ->setDefinition(array(
new InputArgument('package', InputArgument::REQUIRED, 'the package to inspect'), new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect'),
new InputArgument('version', InputArgument::OPTIONAL, 'the version'), 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'),
)) ))
->setHelp(<<<EOT ->setHelp(<<<EOT
The show command displays detailed information about a package The show command displays detailed information about a package, or
<info>php composer.phar show composer/composer master-dev</info> lists all packages available.
EOT EOT
) )
@ -44,16 +51,48 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$composer = $this->getComposer(); // init repos
$package = $this->getPackage($input, $output, $composer); $platformRepo = new PlatformRepository;
if (!$package) { if ($input->getOption('platform')) {
throw new \InvalidArgumentException('no package found'); $repos = $installedRepo = $platformRepo;
} elseif ($input->getOption('installed')) {
$composer = $this->getComposer();
$repos = $installedRepo = $composer->getRepositoryManager()->getLocalRepository();
} elseif ($composer = $this->getComposer(false)) {
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
$installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
} else {
$output->writeln('No composer.json found in the current directory, showing packages from packagist.org');
$installedRepo = $platformRepo;
$repos = new CompositeRepository(array($installedRepo, new ComposerRepository(array('url' => 'http://packagist.org'))));
} }
$this->printMeta($input, $output, $package, $composer); // show single package or single version
$this->printLinks($input, $output, $package, 'requires'); if ($input->getArgument('package')) {
$this->printLinks($input, $output, $package, 'recommends'); $package = $this->getPackage($input, $output, $installedRepo, $repos);
$this->printLinks($input, $output, $package, 'replaces'); if (!$package) {
throw new \InvalidArgumentException('Package '.$input->getArgument('package').' not found');
}
$this->printMeta($input, $output, $package, $installedRepo, $repos);
$this->printLinks($input, $output, $package, 'requires');
$this->printLinks($input, $output, $package, 'recommends');
$this->printLinks($input, $output, $package, 'replaces');
return;
}
// list packages
foreach ($repos->getPackages() as $package) {
if ($platformRepo->hasPackage($package)) {
$type = '<info>platform: </info> ';
} elseif ($installedRepo->hasPackage($package)) {
$type = '<info>installed:</info> ';
} else {
$type = '<comment>available:</comment> ';
}
$output->writeln($type . ' ' . $package->getPrettyName() . ' ' . $package->getPrettyVersion() . '<comment> (' . $package->getVersion() . ')</comment>');
}
} }
/** /**
@ -63,16 +102,15 @@ EOT
* @return PackageInterface * @return PackageInterface
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
protected function getPackage(InputInterface $input, OutputInterface $output, Composer $composer) protected function getPackage(InputInterface $input, OutputInterface $output, RepositoryInterface $installedRepo, RepositoryInterface $repos)
{ {
// we have a name and a version so we can use ::findPackage // we have a name and a version so we can use ::findPackage
if ($input->getArgument('version')) { if ($input->getArgument('version')) {
return $composer->getRepositoryManager()->findPackage($input->getArgument('package'), $input->getArgument('version')); return $repos->findPackage($input->getArgument('package'), $input->getArgument('version'));
} }
// check if we have a local installation so we can grab the right package/version // check if we have a local installation so we can grab the right package/version
$localRepo = $composer->getRepositoryManager()->getLocalRepository(); foreach ($installedRepo->getPackages() as $package) {
foreach ($localRepo->getPackages() as $package) {
if ($package->getName() === $input->getArgument('package')) { if ($package->getName() === $input->getArgument('package')) {
return $package; return $package;
} }
@ -80,15 +118,9 @@ EOT
// we only have a name, so search for the highest version of the given package // we only have a name, so search for the highest version of the given package
$highestVersion = null; $highestVersion = null;
$repos = array_merge( foreach ($repos->findPackagesByName($input->getArgument('package')) as $package) {
array($composer->getRepositoryManager()->getLocalRepository()), if (null === $highestVersion || version_compare($package->getVersion(), $highestVersion->getVersion(), '>=')) {
$composer->getRepositoryManager()->getRepositories() $highestVersion = $package;
);
foreach ($repos as $repository) {
foreach ($repository->findPackagesByName($input->getArgument('package')) as $package) {
if (null === $highestVersion || version_compare($package->getVersion(), $highestVersion->getVersion(), '>=')) {
$highestVersion = $package;
}
} }
} }
@ -98,15 +130,15 @@ EOT
/** /**
* prints package meta data * prints package meta data
*/ */
protected function printMeta(InputInterface $input, OutputInterface $output, PackageInterface $package, Composer $composer) protected function printMeta(InputInterface $input, OutputInterface $output, PackageInterface $package, RepositoryInterface $installedRepo, RepositoryInterface $repos)
{ {
$output->writeln('<info>name</info> : ' . $package->getPrettyName()); $output->writeln('<info>name</info> : ' . $package->getPrettyName());
$this->printVersions($input, $output, $package, $composer); $this->printVersions($input, $output, $package, $installedRepo, $repos);
$output->writeln('<info>type</info> : ' . $package->getType()); $output->writeln('<info>type</info> : ' . $package->getType());
$output->writeln('<info>names</info> : ' . join(', ', $package->getNames())); $output->writeln('<info>names</info> : ' . join(', ', $package->getNames()));
$output->writeln('<info>source</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference())); $output->writeln('<info>source</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
$output->writeln('<info>dist</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference())); $output->writeln('<info>dist</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
$output->writeln('<info>licence</info> : ' . join(', ', $package->getLicense())); $output->writeln('<info>license</info> : ' . join(', ', $package->getLicense()));
if ($package->getAutoload()) { if ($package->getAutoload()) {
$output->writeln("\n<info>autoload</info>"); $output->writeln("\n<info>autoload</info>");
@ -123,7 +155,7 @@ EOT
/** /**
* prints all available versions of this package and highlights the installed one if any * prints all available versions of this package and highlights the installed one if any
*/ */
protected function printVersions(InputInterface $input, OutputInterface $output, PackageInterface $package, Composer $composer) protected function printVersions(InputInterface $input, OutputInterface $output, PackageInterface $package, RepositoryInterface $installedRepo, RepositoryInterface $repos)
{ {
if ($input->getArgument('version')) { if ($input->getArgument('version')) {
$output->writeln('<info>version</info> : ' . $package->getPrettyVersion()); $output->writeln('<info>version</info> : ' . $package->getPrettyVersion());
@ -132,16 +164,14 @@ EOT
$versions = array(); $versions = array();
foreach ($composer->getRepositoryManager()->getRepositories() as $repository) { foreach ($repos->findPackagesByName($package->getName()) as $version) {
foreach ($repository->findPackagesByName($package->getName()) as $version) { $versions[] = $version->getPrettyVersion();
$versions[] = $version->getPrettyVersion();
}
} }
$versions = join(', ', $versions); $versions = join(', ', $versions);
// highlight installed version // highlight installed version
if ($composer->getRepositoryManager()->getLocalRepository()->hasPackage($package)) { if ($installedRepo->hasPackage($package)) {
$versions = str_replace($package->getPrettyVersion(), '<info>* ' . $package->getPrettyVersion() . '</info>', $versions); $versions = str_replace($package->getPrettyVersion(), '<info>* ' . $package->getPrettyVersion() . '</info>', $versions);
} }

View File

@ -35,7 +35,7 @@ class UpdateCommand extends Command
->setName('update') ->setName('update')
->setDescription('Updates your dependencies to the latest version, and updates the composer.lock file.') ->setDescription('Updates your dependencies to the latest version, and updates the composer.lock file.')
->setDefinition(array( ->setDefinition(array(
new InputOption('dev', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'), new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'), new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
new InputOption('no-install-recommends', null, InputOption::VALUE_NONE, 'Do not install recommended packages.'), new InputOption('no-install-recommends', null, InputOption::VALUE_NONE, 'Do not install recommended packages.'),
new InputOption('install-suggests', null, InputOption::VALUE_NONE, 'Also install suggested packages.'), new InputOption('install-suggests', null, InputOption::VALUE_NONE, 'Also install suggested packages.'),
@ -63,7 +63,7 @@ EOT
$io, $io,
$composer, $composer,
$eventDispatcher, $eventDispatcher,
(Boolean)$input->getOption('dev'), (Boolean)$input->getOption('prefer-source'),
(Boolean)$input->getOption('dry-run'), (Boolean)$input->getOption('dry-run'),
(Boolean)$input->getOption('verbose'), (Boolean)$input->getOption('verbose'),
(Boolean)$input->getOption('no-install-recommends'), (Boolean)$input->getOption('no-install-recommends'),

View File

@ -71,14 +71,18 @@ class Application extends BaseApplication
/** /**
* @return Composer * @return Composer
*/ */
public function getComposer() public function getComposer($required = true)
{ {
if (null === $this->composer) { if (null === $this->composer) {
try { try {
$this->composer = Factory::create($this->io); $this->composer = Factory::create($this->io);
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$this->io->write($e->getMessage()); if ($required) {
exit(1); $this->io->write($e->getMessage());
exit(1);
}
return;
} }
} }
@ -102,7 +106,6 @@ class Application extends BaseApplication
$this->add(new Command\DependsCommand()); $this->add(new Command\DependsCommand());
$this->add(new Command\InstallCommand()); $this->add(new Command\InstallCommand());
$this->add(new Command\UpdateCommand()); $this->add(new Command\UpdateCommand());
$this->add(new Command\DebugPackagesCommand());
$this->add(new Command\SearchCommand()); $this->add(new Command\SearchCommand());
$this->add(new Command\ValidateCommand()); $this->add(new Command\ValidateCommand());
$this->add(new Command\ShowCommand()); $this->add(new Command\ShowCommand());

View File

@ -14,6 +14,7 @@ namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Downloader\DownloaderInterface; use Composer\Downloader\DownloaderInterface;
use Composer\Util\Filesystem;
/** /**
* Downloaders manager. * Downloaders manager.
@ -134,7 +135,7 @@ class DownloadManager
); );
} }
$fs = new Util\Filesystem(); $fs = new Filesystem();
$fs->ensureDirectoryExists($targetDir); $fs->ensureDirectoryExists($targetDir);
$downloader = $this->getDownloaderForInstalledPackage($package); $downloader = $this->getDownloaderForInstalledPackage($package);

View File

@ -13,6 +13,8 @@ namespace Composer\Downloader;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Util\Filesystem;
use Composer\Util\StreamContextFactory;
/** /**
* Base downloader for file packages * Base downloader for file packages
@ -77,31 +79,14 @@ abstract class FileDownloader implements DownloaderInterface
} }
} }
// Handle system proxy $options = array();
$params = array('http' => array());
if (isset($_SERVER['HTTP_PROXY'])) {
// http(s):// is not supported in proxy
$proxy = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $_SERVER['HTTP_PROXY']);
if (0 === strpos($proxy, 'ssl:') && !extension_loaded('openssl')) {
throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
}
$params['http'] = array(
'proxy' => $proxy,
'request_fulluri' => true,
);
}
if ($this->io->hasAuthorization($package->getSourceUrl())) { if ($this->io->hasAuthorization($package->getSourceUrl())) {
$auth = $this->io->getAuthorization($package->getSourceUrl()); $auth = $this->io->getAuthorization($package->getSourceUrl());
$authStr = base64_encode($auth['username'] . ':' . $auth['password']); $authStr = base64_encode($auth['username'] . ':' . $auth['password']);
$params['http'] = array_merge($params['http'], array('header' => "Authorization: Basic $authStr\r\n")); $options['http']['header'] = "Authorization: Basic $authStr\r\n";
} }
$ctx = stream_context_create($params); $ctx = StreamContextFactory::getContext($options, array('notification' => array($this, 'callbackGet')));
stream_context_set_params($ctx, array("notification" => array($this, 'callbackGet')));
$this->io->overwrite(" Downloading: <comment>connection...</comment>", false); $this->io->overwrite(" Downloading: <comment>connection...</comment>", false);
@copy($url, $fileName, $ctx); @copy($url, $fileName, $ctx);
@ -142,7 +127,7 @@ abstract class FileDownloader implements DownloaderInterface
*/ */
public function update(PackageInterface $initial, PackageInterface $target, $path) public function update(PackageInterface $initial, PackageInterface $target, $path)
{ {
$fs = new Util\Filesystem(); $fs = new Filesystem();
$fs->removeDirectory($path); $fs->removeDirectory($path);
$this->download($target, $path); $this->download($target, $path);
} }
@ -152,7 +137,7 @@ abstract class FileDownloader implements DownloaderInterface
*/ */
public function remove(PackageInterface $package, $path) public function remove(PackageInterface $package, $path)
{ {
$fs = new Util\Filesystem(); $fs = new Filesystem();
$fs->removeDirectory($path); $fs->removeDirectory($path);
} }

View File

@ -15,6 +15,7 @@ namespace Composer\Downloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Util\Filesystem;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -73,7 +74,7 @@ abstract class VcsDownloader implements DownloaderInterface
public function remove(PackageInterface $package, $path) public function remove(PackageInterface $package, $path)
{ {
$this->enforceCleanDirectory($path); $this->enforceCleanDirectory($path);
$fs = new Util\Filesystem(); $fs = new Filesystem();
$fs->removeDirectory($path); $fs->removeDirectory($path);
} }

View File

@ -17,7 +17,7 @@ use Composer\Downloader\DownloadManager;
use Composer\Repository\WritableRepositoryInterface; use Composer\Repository\WritableRepositoryInterface;
use Composer\DependencyResolver\Operation\OperationInterface; use Composer\DependencyResolver\Operation\OperationInterface;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Downloader\Util\Filesystem; use Composer\Util\Filesystem;
/** /**
* Package installation manager. * Package installation manager.
@ -147,6 +147,12 @@ class LibraryInstaller implements InstallerInterface
foreach ($package->getBinaries() as $bin) { foreach ($package->getBinaries() as $bin) {
$link = $this->binDir.'/'.basename($bin); $link = $this->binDir.'/'.basename($bin);
if (file_exists($link)) { if (file_exists($link)) {
if (is_link($link)) {
// likely leftover from a previous install, make sure
// that the target is still executable in case this
// is a fresh install of the vendor.
chmod($link, 0755);
}
$this->io->write('Skipped installation of '.$bin.' for package '.$package->getName().', name conflicts with an existing file'); $this->io->write('Skipped installation of '.$bin.' for package '.$package->getName().', name conflicts with an existing file');
continue; continue;
} }
@ -156,14 +162,14 @@ class LibraryInstaller implements InstallerInterface
// add unixy support for cygwin and similar environments // add unixy support for cygwin and similar environments
if ('.bat' !== substr($bin, -4)) { if ('.bat' !== substr($bin, -4)) {
file_put_contents($link, $this->generateUnixyProxyCode($bin, $link)); file_put_contents($link, $this->generateUnixyProxyCode($bin, $link));
chmod($link, 0777); chmod($link, 0755);
$link .= '.bat'; $link .= '.bat';
} }
file_put_contents($link, $this->generateWindowsProxyCode($bin, $link)); file_put_contents($link, $this->generateWindowsProxyCode($bin, $link));
} else { } else {
symlink($bin, $link); symlink($bin, $link);
} }
chmod($link, 0777); chmod($link, 0755);
} }
} }

View File

@ -14,6 +14,7 @@ namespace Composer\Json;
use Composer\Repository\RepositoryManager; use Composer\Repository\RepositoryManager;
use Composer\Composer; use Composer\Composer;
use Composer\Util\StreamContextFactory;
/** /**
* Reads/writes json files. * Reads/writes json files.
@ -59,11 +60,12 @@ class JsonFile
*/ */
public function read() public function read()
{ {
$context = stream_context_create(array( $ctx = StreamContextFactory::getContext(array(
'http' => array('header' => 'User-Agent: Composer/'.Composer::VERSION."\r\n") 'http' => array(
)); 'header' => 'User-Agent: Composer/'.Composer::VERSION."\r\n"
)));
$json = file_get_contents($this->path, false, $context); $json = file_get_contents($this->path, false, $ctx);
if (!$json) { if (!$json) {
throw new \RuntimeException('Could not read '.$this->path.', you are probably offline'); throw new \RuntimeException('Could not read '.$this->path.', you are probably offline');
} }

View File

@ -24,11 +24,16 @@ class ArrayDumper
{ {
$keys = array( $keys = array(
'binaries' => 'bin', 'binaries' => 'bin',
'scripts',
'type', 'type',
'names', 'names',
'extra', 'extra',
'installationSource' => 'installation-source', 'installationSource' => 'installation-source',
'license', 'license',
'authors',
'description',
'homepage',
'keywords',
'autoload', 'autoload',
'repositories', 'repositories',
); );
@ -41,6 +46,10 @@ class ArrayDumper
$data['target-dir'] = $package->getTargetDir(); $data['target-dir'] = $package->getTargetDir();
} }
if ($package->getReleaseDate()) {
$data['time'] = $package->getReleaseDate()->format('Y-m-d H:i:s');
}
if ($package->getSourceType()) { if ($package->getSourceType()) {
$data['source']['type'] = $package->getSourceType(); $data['source']['type'] = $package->getSourceType();
$data['source']['url'] = $package->getSourceUrl(); $data['source']['url'] = $package->getSourceUrl();

View File

@ -438,7 +438,7 @@ class MemoryPackage extends BasePackage
* *
* @param DateTime $releaseDate * @param DateTime $releaseDate
*/ */
public function setReleasedate(\DateTime $releaseDate) public function setReleaseDate(\DateTime $releaseDate)
{ {
$this->releaseDate = $releaseDate; $this->releaseDate = $releaseDate;
} }

View File

@ -13,6 +13,7 @@
namespace Composer\Repository; namespace Composer\Repository;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Util\StreamContextFactory;
/** /**
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
@ -20,7 +21,8 @@ use Composer\Package\Loader\ArrayLoader;
*/ */
class PearRepository extends ArrayRepository class PearRepository extends ArrayRepository
{ {
protected $url; private $url;
private $streamContext;
public function __construct(array $config) public function __construct(array $config)
{ {
@ -31,7 +33,7 @@ class PearRepository extends ArrayRepository
throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$config['url']); throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$config['url']);
} }
$this->url = $config['url']; $this->url = rtrim($config['url'], '/');
} }
protected function initialize() protected function initialize()
@ -41,6 +43,7 @@ class PearRepository extends ArrayRepository
set_error_handler(function($severity, $message, $file, $line) { set_error_handler(function($severity, $message, $file, $line) {
throw new \ErrorException($message, $severity, $severity, $file, $line); throw new \ErrorException($message, $severity, $severity, $file, $line);
}); });
$this->streamContext = StreamContextFactory::getContext();
$this->fetchFromServer(); $this->fetchFromServer();
restore_error_handler(); restore_error_handler();
} }
@ -51,24 +54,62 @@ class PearRepository extends ArrayRepository
$categories = $categoryXML->getElementsByTagName("c"); $categories = $categoryXML->getElementsByTagName("c");
foreach ($categories as $category) { foreach ($categories as $category) {
$categoryLink = $category->getAttribute("xlink:href"); $link = '/' . ltrim($category->getAttribute("xlink:href"), '/');
$categoryLink = str_replace("info.xml", "packages.xml", $categoryLink); try {
if ('/' !== substr($categoryLink, 0, 1)) { $packagesLink = str_replace("info.xml", "packagesinfo.xml", $link);
$categoryLink = '/' . $categoryLink; $this->fetchPear2Packages($this->url . $packagesLink);
} catch (\ErrorException $e) {
if (false === strpos($e->getMessage(), '404')) {
throw $e;
}
$categoryLink = str_replace("info.xml", "packages.xml", $link);
$this->fetchPearPackages($this->url . $categoryLink);
} }
$packagesXML = $this->requestXml($this->url . $categoryLink);
$packages = $packagesXML->getElementsByTagName('p'); }
$loader = new ArrayLoader(); }
foreach ($packages as $package) {
$packageName = $package->nodeValue;
$packageLink = $package->getAttribute('xlink:href'); /**
$releaseLink = $this->url . str_replace("/rest/p/", "/rest/r/", $packageLink); * @param string $categoryLink
$allReleasesLink = $releaseLink . "/allreleases2.xml"; * @throws ErrorException
* @throws InvalidArgumentException
*/
private function fetchPearPackages($categoryLink)
{
$packagesXML = $this->requestXml($categoryLink);
$packages = $packagesXML->getElementsByTagName('p');
$loader = new ArrayLoader();
foreach ($packages as $package) {
$packageName = $package->nodeValue;
$packageLink = $package->getAttribute('xlink:href');
$releaseLink = $this->url . str_replace("/rest/p/", "/rest/r/", $packageLink);
$allReleasesLink = $releaseLink . "/allreleases2.xml";
try {
$releasesXML = $this->requestXml($allReleasesLink);
} catch (\ErrorException $e) {
if (strpos($e->getMessage(), '404')) {
continue;
}
throw $e;
}
$releases = $releasesXML->getElementsByTagName('r');
foreach ($releases as $release) {
/* @var $release \DOMElement */
$pearVersion = $release->getElementsByTagName('v')->item(0)->nodeValue;
$packageData = array(
'name' => $packageName,
'type' => 'library',
'dist' => array('type' => 'pear', 'url' => $this->url.'/get/'.$packageName.'-'.$pearVersion.".tgz"),
'version' => $pearVersion,
);
try { try {
$releasesXML = $this->requestXml($allReleasesLink); $deps = file_get_contents($releaseLink . "/deps.".$pearVersion.".txt", false, $this->streamContext);
} catch (\ErrorException $e) { } catch (\ErrorException $e) {
if (strpos($e->getMessage(), '404')) { if (strpos($e->getMessage(), '404')) {
continue; continue;
@ -76,54 +117,155 @@ class PearRepository extends ArrayRepository
throw $e; throw $e;
} }
$releases = $releasesXML->getElementsByTagName('r'); $packageData += $this->parseDependencies($deps);
foreach ($releases as $release) { try {
/* @var $release DOMElement */ $this->addPackage($loader->load($packageData));
$pearVersion = $release->getElementsByTagName('v')->item(0)->nodeValue; } catch (\UnexpectedValueException $e) {
continue;
}
}
}
}
$packageData = array( /**
'name' => $packageName, * @param array $data
'type' => 'library', * @return string
'dist' => array('type' => 'pear', 'url' => $this->url.'/get/'.$packageName.'-'.$pearVersion.".tgz"), */
'version' => $pearVersion, private function parseVersion(array $data)
{
if (!isset($data['min']) && !isset($data['max'])) {
return '*';
}
$versions = array();
if (isset($data['min'])) {
$versions[] = '>=' . $data['min'];
}
if (isset($data['max'])) {
$versions[] = '<=' . $data['max'];
}
return implode(',', $versions);
}
/**
* @todo Improve dependencies resolution of pear packages.
* @param array $options
* @return array
*/
private function parseDependenciesOptions(array $depsOptions)
{
$data = array();
foreach ($depsOptions as $name => $options) {
// make sure single deps are wrapped in an array
if (isset($options['name'])) {
$options = array($options);
}
if ('php' == $name) {
$data[$name] = $this->parseVersion($options);
} elseif ('package' == $name) {
foreach ($options as $key => $value) {
if (is_array($value)) {
$dataKey = $value['name'];
$data[$dataKey] = $this->parseVersion($value);
}
}
} elseif ('extension' == $name) {
foreach ($options as $key => $value) {
$dataKey = 'ext-' . $value['name'];
$data[$dataKey] = $this->parseVersion($value);
}
}
}
return $data;
}
/**
* @param string $deps
* @return array
* @throws InvalidArgumentException
*/
private function parseDependencies($deps)
{
if (preg_match('((O:([0-9])+:"([^"]+)"))', $deps, $matches)) {
if (strlen($matches[3]) == $matches[2]) {
throw new \InvalidArgumentException("Invalid dependency data, it contains serialized objects.");
}
}
$deps = (array) @unserialize($deps);
unset($deps['required']['pearinstaller']);
$depsData = array();
if (!empty($deps['required'])) {
$depsData['require'] = $this->parseDependenciesOptions($deps['required']);
}
if (!empty($deps['optional'])) {
$depsData['suggest'] = $this->parseDependenciesOptions($deps['optional']);
}
return $depsData;
}
/**
* @param string $packagesLink
* @return void
* @throws InvalidArgumentException
*/
private function fetchPear2Packages($packagesLink)
{
$loader = new ArrayLoader();
$packagesXml = $this->requestXml($packagesLink);
$informations = $packagesXml->getElementsByTagName('pi');
foreach ($informations as $information) {
$package = $information->getElementsByTagName('p')->item(0);
$packageName = $package->getElementsByTagName('n')->item(0)->nodeValue;
$packageData = array(
'name' => $packageName,
'type' => 'library'
);
$packageKeys = array('l' => 'license', 'd' => 'description');
foreach ($packageKeys as $pear => $composer) {
if ($package->getElementsByTagName($pear)->length > 0
&& ($pear = $package->getElementsByTagName($pear)->item(0)->nodeValue)) {
$packageData[$composer] = $pear;
}
}
$depsData = array();
foreach ($information->getElementsByTagName('deps') as $depElement) {
$depsVersion = $depElement->getElementsByTagName('v')->item(0)->nodeValue;
$depsData[$depsVersion] = $this->parseDependencies(
$depElement->getElementsByTagName('d')->item(0)->nodeValue
);
}
$releases = $information->getElementsByTagName('a')->item(0);
if (!$releases) {
continue;
}
$releases = $releases->getElementsByTagName('r');
$packageUrl = $this->url . '/get/' . $packageName;
foreach ($releases as $release) {
$version = $release->getElementsByTagName('v')->item(0)->nodeValue;
$releaseData = array(
'dist' => array(
'type' => 'pear',
'url' => $packageUrl . '-' . $version . '.tgz'
),
'version' => $version
);
if (isset($depsData[$version])) {
$releaseData += $depsData[$version];
}
try {
$this->addPackage(
$loader->load($packageData + $releaseData)
); );
} catch (\UnexpectedValueException $e) {
try { continue;
$deps = file_get_contents($releaseLink . "/deps.".$pearVersion.".txt");
} catch (\ErrorException $e) {
if (strpos($e->getMessage(), '404')) {
continue;
}
throw $e;
}
if (preg_match('((O:([0-9])+:"([^"]+)"))', $deps, $matches)) {
if (strlen($matches[3]) == $matches[2]) {
throw new \InvalidArgumentException("Invalid dependency data, it contains serialized objects.");
}
}
$deps = unserialize($deps);
if (isset($deps['required']['package'])) {
if (isset($deps['required']['package']['name'])) {
$deps['required']['package'] = array($deps['required']['package']);
}
foreach ($deps['required']['package'] as $dependency) {
if (isset($dependency['min'])) {
$packageData['require'][$dependency['name']] = '>='.$dependency['min'];
} else {
$packageData['require'][$dependency['name']] = '>=0.0.0';
}
}
}
try {
$this->addPackage($loader->load($packageData));
} catch (\UnexpectedValueException $e) {
continue;
}
} }
} }
} }
@ -135,7 +277,7 @@ class PearRepository extends ArrayRepository
*/ */
private function requestXml($url) private function requestXml($url)
{ {
$content = file_get_contents($url); $content = file_get_contents($url, false, $this->streamContext);
if (!$content) { if (!$content) {
throw new \UnexpectedValueException('The PEAR channel at '.$url.' did not respond.'); throw new \UnexpectedValueException('The PEAR channel at '.$url.' did not respond.');
} }

View File

@ -10,9 +10,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Composer\Downloader\Util; namespace Composer\Util;
use Composer\Util\ProcessExecutor;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>

View File

@ -0,0 +1,56 @@
<?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\Util;
/**
* Allows the creation of a basic context supporting http proxy
*
* @author Jordan Alliot <jordan.alliot@gmail.com>
*/
final class StreamContextFactory
{
/**
* Creates a context supporting HTTP proxies
*
* @param array $defaultOptions Options to merge with the default
* @param array $defaultParams Parameters to specify on the context
* @return resource Default context
* @throws \RuntimeException if https proxy required and OpenSSL uninstalled
*/
static public function getContext(array $defaultOptions = array(), array $defaultParams = array())
{
$options = array('http' => array());
// Handle system proxy
if (isset($_SERVER['HTTP_PROXY']) || isset($_SERVER['http_proxy'])) {
// Some systems seem to rely on a lowercased version instead...
$proxy = isset($_SERVER['HTTP_PROXY']) ? $_SERVER['HTTP_PROXY'] : $_SERVER['http_proxy'];
// http(s):// is not supported in proxy
$proxy = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxy);
if (0 === strpos($proxy, 'ssl:') && !extension_loaded('openssl')) {
throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
}
$options['http'] = array(
'proxy' => $proxy,
'request_fulluri' => true,
);
}
$options = array_merge_recursive($options, $defaultOptions);
return stream_context_create($options, $defaultParams);
}
}

View File

@ -13,7 +13,7 @@
namespace Composer\Test\Installer; namespace Composer\Test\Installer;
use Composer\Autoload\AutoloadGenerator; use Composer\Autoload\AutoloadGenerator;
use Composer\Downloader\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Package\MemoryPackage; use Composer\Package\MemoryPackage;
class AutoloadGeneratorTest extends \PHPUnit_Framework_TestCase class AutoloadGeneratorTest extends \PHPUnit_Framework_TestCase

View File

@ -12,7 +12,7 @@
namespace Composer\Test\Repository; namespace Composer\Test\Repository;
use Composer\Downloader\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Test\TestCase; use Composer\Test\TestCase;
class FilesystemTest extends TestCase class FilesystemTest extends TestCase

View File

@ -14,7 +14,7 @@ namespace Composer\Test\Installer;
use Composer\Installer\LibraryInstaller; use Composer\Installer\LibraryInstaller;
use Composer\DependencyResolver\Operation; use Composer\DependencyResolver\Operation;
use Composer\Downloader\Util\Filesystem; use Composer\Util\Filesystem;
class LibraryInstallerTest extends \PHPUnit_Framework_TestCase class LibraryInstallerTest extends \PHPUnit_Framework_TestCase
{ {

View File

@ -0,0 +1,66 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Test\Package\Dumper;
use Composer\Package\Dumper\ArrayDumper;
use Composer\Package\MemoryPackage;
class ArrayDumperTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->dumper = new ArrayDumper();
}
public function testRequiredInformations()
{
$package = new MemoryPackage('foo', '1.0.0.0', '1.0');
$config = $this->dumper->dump($package);
$this->assertEquals(array('name', 'version', 'version_normalized', 'type', 'names'), array_keys($config));
}
/**
* @dataProvider getKeys
*/
public function testKeys($key, $value, $expectedValue = null, $method = null)
{
$package = new MemoryPackage('foo', '1.0.0.0', '1.0');
$setter = 'set'.ucfirst($method ?: $key);
$package->$setter($value);
$config = $this->dumper->dump($package);
$this->assertArrayHasKey($key, $config);
$expectedValue = $expectedValue ?: $value;
$this->assertSame($expectedValue, $config[$key]);
}
public function getKeys()
{
return array(
array('time', new \DateTime('2012-02-01'), '2012-02-01 00:00:00', 'ReleaseDate'),
array('authors', array('Nils Adermann <naderman@naderman.de>', 'Jordi Boggiano <j.boggiano@seld.be>')),
array('homepage', 'http://getcomposer.org'),
array('description', 'Package Manager'),
array('keywords', array('package', 'dependency', 'autoload')),
array('bin', array('bin/composer'), null, 'binaries'),
array('license', array('MIT')),
array('autoload', array('psr-0' => array('Composer' => 'src/'))),
array('repositories', array('packagist' => false)),
array('scripts', array('post-update-cmd' => 'MyVendor\\MyClass::postUpdate')),
array('extra', array('class' => 'MyVendor\\Installer')),
);
}
}

View File

@ -16,6 +16,4 @@ if ((!$loader = @include __DIR__.'/../../../.composer/autoload.php') && (!$loade
'php composer.phar install'.PHP_EOL); 'php composer.phar install'.PHP_EOL);
} }
$loader = require __DIR__.'/../vendor/.composer/autoload.php';
$loader->add('Composer\Test', __DIR__); $loader->add('Composer\Test', __DIR__);
$loader->register();