123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <?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\DependencyResolver\Pool;
- use Composer\DependencyResolver\Request;
- use Composer\DependencyResolver\DefaultPolicy;
- use Composer\DependencyResolver\Solver;
- use Composer\Repository\PlatformRepository;
- use Composer\Package\MemoryPackage;
- use Composer\Package\LinkConstraint\VersionConstraint;
- /**
- * @author Jordi Boggiano <j.boggiano@seld.be>
- */
- class InstallCommand
- {
- protected $composer;
- public function install($composer)
- {
- $this->composer = $composer;
- // TODO this needs a parameter to enable installing from source (i.e. git clone, instead of downloading archives)
- $sourceInstall = false;
- $config = $this->loadConfig();
- echo 'Loading repositories'.PHP_EOL;
- if (isset($config['repositories'])) {
- foreach ($config['repositories'] as $name => $spec) {
- $composer->addRepository($name, $spec);
- }
- }
- $pool = new Pool;
- $repoInstalled = new PlatformRepository;
- $pool->addRepository($repoInstalled);
- // TODO check the lock file to see what's currently installed
- // $repoInstalled->addPackage(new MemoryPackage('$Package', '$Version'));
- echo 'Loading package list'.PHP_EOL;
- foreach ($composer->getRepositories() as $repository) {
- $pool->addRepository($repository);
- }
- $request = new Request($pool);
- echo 'Building up request'.PHP_EOL;
- // TODO there should be an update flag or dedicated update command
- // TODO check lock file to remove packages that disappeared from the requirements
- foreach ($config['require'] as $name => $version) {
- if ('latest' === $version) {
- $request->install($name);
- } else {
- preg_match('#^([>=<~]*)([\d.]+.*)$#', $version, $match);
- if (!$match[1]) {
- $match[1] = '=';
- }
- $constraint = new VersionConstraint($match[1], $match[2]);
- $request->install($name, $constraint);
- }
- }
- echo 'Solving dependencies'.PHP_EOL;
- $policy = new DefaultPolicy;
- $solver = new Solver($policy, $pool, $repoInstalled);
- $transaction = $solver->solve($request);
- $lock = array();
- foreach ($transaction as $task) {
- switch ($task['job']) {
- case 'install':
- $package = $task['package'];
- echo '> Installing '.$package->getName().PHP_EOL;
- if ($sourceInstall) {
- // TODO
- } else {
- if ($package->getDistType()) {
- $downloaderType = $package->getDistType();
- $type = 'dist';
- } elseif ($package->getSourceType()) {
- echo 'Package '.$package->getName().' has no dist url, installing from source instead.';
- $downloaderType = $package->getSourceType();
- $type = 'source';
- } else {
- throw new \UnexpectedValueException('Package '.$package->getName().' has no source or dist URL.');
- }
- $downloader = $composer->getDownloader($downloaderType);
- $installer = $composer->getInstaller($package->getType());
- if (!$installer->install($package, $downloader, $type)) {
- throw new \LogicException($package->getName().' could not be installed.');
- }
- }
- $lock[$package->getName()] = array('version' => $package->getVersion());
- break;
- default:
- throw new \UnexpectedValueException('Unhandled job type : '.$task['job']);
- }
- }
- echo '> Done'.PHP_EOL;
- $this->storeLockFile($lock);
- }
- protected function loadConfig()
- {
- if (!file_exists('composer.json')) {
- throw new \UnexpectedValueException('composer.json config file not found in '.getcwd());
- }
- $config = json_decode(file_get_contents('composer.json'), true);
- if (!$config) {
- switch (json_last_error()) {
- case JSON_ERROR_NONE:
- $msg = 'No error has occurred, is your composer.json file empty?';
- break;
- case JSON_ERROR_DEPTH:
- $msg = 'The maximum stack depth has been exceeded';
- break;
- case JSON_ERROR_STATE_MISMATCH:
- $msg = 'Invalid or malformed JSON';
- break;
- case JSON_ERROR_CTRL_CHAR:
- $msg = 'Control character error, possibly incorrectly encoded';
- break;
- case JSON_ERROR_SYNTAX:
- $msg = 'Syntax error';
- break;
- case JSON_ERROR_UTF8:
- $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
- break;
- }
- throw new \UnexpectedValueException('Incorrect composer.json file: '.$msg);
- }
- return $config;
- }
- protected function storeLockFile(array $content)
- {
- file_put_contents('composer.lock', json_encode($content)."\n");
- echo '> composer.lock dumped'.PHP_EOL;
- }
- }
|