فهرست منبع

Integrating the command system with Symfony's command system

Parts are still a WIP, as there are some embedded echo statements that should eventually be run through some sort of output interface.
Ryan Weaver 13 سال پیش
والد
کامیت
f5b054985a
5فایلهای تغییر یافته به همراه147 افزوده شده و 21 حذف شده
  1. 5 2
      bin/composer
  2. 31 0
      src/Composer/Command/Command.php
  3. 29 19
      src/Composer/Command/InstallCommand.php
  4. 2 0
      src/Composer/Composer.php
  5. 80 0
      src/Composer/Console/Application.php

+ 5 - 2
bin/composer

@@ -9,12 +9,15 @@ use Composer\Downloader\PearDownloader;
 use Composer\Downloader\ZipDownloader;
 use Composer\Command\InstallCommand;
 use Composer\Installer\LibraryInstaller;
+use Composer\Console\Application;
 
+// initialize composer
 $composer = new Composer();
 $composer->addDownloader('git', new GitDownloader);
 $composer->addDownloader('pear', new PearDownloader);
 $composer->addDownloader('zip', new ZipDownloader);
 $composer->addInstaller('library', new LibraryInstaller);
 
-$cmd = new InstallCommand();
-$cmd->install($composer);
+// run the command application
+$application = new Application($composer);
+$application->run();

+ 31 - 0
src/Composer/Command/Command.php

@@ -0,0 +1,31 @@
+<?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 Symfony\Component\Console\Command\Command as BaseCommand;
+
+/**
+ * Base class for Composer commands
+ *
+ * @author Ryan Weaver <ryan@knplabs.com>
+ */
+abstract class Command extends BaseCommand
+{
+    /**
+     * @return \Composer\Composer
+     */
+    public function getComposer()
+    {
+        return $this->getApplication()->getComposer();
+    }
+}

+ 29 - 19
src/Composer/Command/InstallCommand.php

@@ -20,27 +20,36 @@ use Composer\Repository\PlatformRepository;
 use Composer\Package\MemoryPackage;
 use Composer\Package\LinkConstraint\VersionConstraint;
 
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @author Ryan Weaver <ryan@knplabs.com>
  */
-class InstallCommand
+class InstallCommand extends Command
 {
-    protected $composer;
-
-    public function install($composer)
+    protected function configure()
     {
-        $this->composer = $composer;
+        $this
+            ->setName('install')
+            ->setDescription('Parses the composer.json file and downloads the needed dependencies.')
+        ;
+    }
 
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
         // 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;
+        $output->writeln('<info>Loading repositories</info>');
 
         if (isset($config['repositories'])) {
             foreach ($config['repositories'] as $name => $spec) {
-                $composer->addRepository($name, $spec);
+                $this->getComposer()->addRepository($name, $spec);
             }
         }
 
@@ -52,15 +61,15 @@ class InstallCommand
         // TODO check the lock file to see what's currently installed
         // $repoInstalled->addPackage(new MemoryPackage('$Package', '$Version'));
 
-        echo 'Loading package list'.PHP_EOL;
+        $output->writeln('Loading package list');
 
-        foreach ($composer->getRepositories() as $repository) {
+        foreach ($this->getComposer()->getRepositories() as $repository) {
             $pool->addRepository($repository);
         }
 
         $request = new Request($pool);
 
-        echo 'Building up request'.PHP_EOL;
+        $output->writeln('Building up request');
 
         // TODO there should be an update flag or dedicated update command
         // TODO check lock file to remove packages that disappeared from the requirements
@@ -78,7 +87,7 @@ class InstallCommand
             }
         }
 
-        echo 'Solving dependencies'.PHP_EOL;
+        $output->writeln('Solving dependencies');
 
         $policy = new DefaultPolicy;
         $solver = new Solver($policy, $pool, $repoInstalled);
@@ -90,7 +99,7 @@ class InstallCommand
             switch ($task['job']) {
             case 'install':
                 $package = $task['package'];
-                echo '> Installing '.$package->getName().PHP_EOL;
+                $output->writeln('> Installing '.$package->getName());
                 if ($sourceInstall) {
                     // TODO
                 } else {
@@ -98,14 +107,14 @@ class InstallCommand
                         $downloaderType = $package->getDistType();
                         $type = 'dist';
                     } elseif ($package->getSourceType()) {
-                        echo 'Package '.$package->getName().' has no dist url, installing from source instead.';
+                        $output->writeln('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());
+                    $downloader = $this->getComposer()->getDownloader($downloaderType);
+                    $installer = $this->getComposer()->getInstaller($package->getType());
                     if (!$installer->install($package, $downloader, $type)) {
                         throw new \LogicException($package->getName().' could not be installed.');
                     }
@@ -116,9 +125,9 @@ class InstallCommand
                 throw new \UnexpectedValueException('Unhandled job type : '.$task['job']);
             }
         }
-        echo '> Done'.PHP_EOL;
+        $output->writeln('> Done');
 
-        $this->storeLockFile($lock);
+        $this->storeLockFile($lock, $output);
     }
 
     protected function loadConfig()
@@ -153,10 +162,11 @@ class InstallCommand
         return $config;
     }
 
-    protected function storeLockFile(array $content)
+    protected function storeLockFile(array $content, OutputInterface $output)
     {
         file_put_contents('composer.lock', json_encode($content, JSON_FORCE_OBJECT)."\n");
-        echo '> composer.lock dumped'.PHP_EOL;
+        $output->writeln('> composer.lock dumped');
+
     }
 
     protected function lowercase($str)

+ 2 - 0
src/Composer/Composer.php

@@ -22,6 +22,8 @@ use Composer\Repository\PearRepository;
  */
 class Composer
 {
+    const VERSION = '1.0.0-DEV';
+
     protected $repositories = array();
     protected $downloaders = array();
     protected $installers = array();

+ 80 - 0
src/Composer/Console/Application.php

@@ -0,0 +1,80 @@
+<?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\Console;
+
+use Symfony\Component\Console\Application as BaseApplication;
+use Composer\Composer;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Finder\Finder;
+
+/**
+ * The console application that handles the commands
+ *
+ * @author Ryan Weaver <ryan@knplabs.com>
+ */
+class Application extends BaseApplication
+{
+    private $composer;
+
+    public function __construct(Composer $composer)
+    {
+        parent::__construct('Composer', Composer::VERSION);
+
+        $this->composer = $composer;
+    }
+
+    /**
+     * Runs the current application.
+     *
+     * @param InputInterface  $input  An Input instance
+     * @param OutputInterface $output An Output instance
+     *
+     * @return integer 0 if everything went fine, or an error code
+     */
+    public function doRun(InputInterface $input, OutputInterface $output)
+    {
+        $this->registerCommands();
+
+        return parent::doRun($input, $output);
+    }
+
+    /**
+     * @return Composer
+     */
+    public function getComposer()
+    {
+        return $this->composer;
+    }
+
+    /**
+     * Looks for all *Command files in Composer's Command directory
+     */
+    protected function registerCommands()
+    {
+        $dir = __DIR__.'/../Command';
+        $finder = new Finder();
+        $finder->files()->name('*Command.php')->in($dir);
+
+        foreach ($finder as $file) {
+            $ns = 'Composer\\Command';
+            if ($relativePath = $file->getRelativePath()) {
+                $ns .= '\\'.strtr($relativePath, '/', '\\');
+            }
+            $r = new \ReflectionClass($ns.'\\'.$file->getBasename('.php'));
+            if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract()) {
+                $this->add($r->newInstance());
+            }
+        }
+    }
+}