diff --git a/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php new file mode 100644 index 000000000..c305ce8da --- /dev/null +++ b/src/Composer/Command/ArchiveCommand.php @@ -0,0 +1,119 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Command; + +use Composer\Factory; +use Composer\IO\IOInterface; +use Composer\DependencyResolver\Pool; +use Composer\Package\LinkConstraint\VersionConstraint; +use Composer\Repository\CompositeRepository; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Install a package as new project into new directory. + * + * @author Nils Adermann + */ +class ArchiveCommand extends Command +{ + protected function configure() + { + $this + ->setName('archive') + ->setDescription('Create an archive of this composer package') + ->setDefinition(array( + new InputArgument('package', InputArgument::REQUIRED, 'The package to archive'), + new InputArgument('version', InputArgument::OPTIONAL, 'The package version to archive'), + new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the resulting archive: tar or zip', 'tar'), + new InputOption('dir', false, InputOption::VALUE_REQUIRED, 'Write the archive to this directory', '.'), + )) + ->setHelp(<<archive command creates an archive of the specified format +containing the files and directories of the Composer project or the specified +package and writes it to the specified directory. + +php composer.phar archive [--format=zip] [--dir=/foo] package version + +EOT + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + return $this->archive( + $this->getIO(), + $input->getArgument('package'), + $input->getArgument('version'), + $input->getOption('format'), + $input->getOption('dir') + ); + } + + public function archive(IOInterface $io, $packageName, $version = false, $format = 'tar', $dest = '.') + { + $config = Factory::createConfig(); + $factory = new Factory; + $archiveManager = $factory->createArchiveManager($config); + + $package = $this->selectPackage($io, $packageName, $version); + + if (!$package) { + return 1; + } + + $io->write('Creating the archive.'); + $archiveManager->archive($package, $format, $dest); + + return 0; + } + + protected function selectPackage(IOInterface $io, $packageName, $version = false) + { + $io->write('Searching for the specified package.'); + + if ($composer = $this->getComposer(false)) { + $localRepo = $composer->getRepositoryManager()->getLocalRepository(); + $repos = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories())); + } else { + $defaultRepos = Factory::createDefaultRepositories($this->getIO()); + $output->writeln('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); + $repos = new CompositeRepository($defaultRepos); + } + + $pool = new Pool(); + $pool->addRepository($repos); + + $constraint = ($version) ? new VersionConstraint('>=', $version) : null; + $packages = $pool->whatProvides($packageName, $constraint); + + if (count($packages) > 1) { + $package = $packages[0]; + $io->write('Found multiple matches, selected '.$package.'.'); + $io->write('Alternatives were '.implode(', ', $packages).'.'); + $io->write('Please use a more specific constraint to pick a different package.'); + } elseif ($packages) { + $package = $packages[0]; + $io->write('Found an exact match '.$package.'.'); + } else { + $io->write('Could not find a package matching '.$packageName.'.'); + return false; + } + + return $package; + } +} diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 55d078cee..40dfd9eb9 100755 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -194,6 +194,7 @@ class Application extends BaseApplication $commands[] = new Command\RequireCommand(); $commands[] = new Command\DumpAutoloadCommand(); $commands[] = new Command\StatusCommand(); + $commands[] = new Command\ArchiveCommand(); if ('phar:' === substr(__FILE__, 0, 5)) { $commands[] = new Command\SelfUpdateCommand(); diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 92e89f5a5..b77d6bb1d 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -324,7 +324,7 @@ class Factory * * @return Archiver\ArchiveManager */ - public function createArchiveManager(Config $config, DownloadManager $dm = null) + public function createArchiveManager(Config $config, Downloader\DownloadManager $dm = null) { if (null === $dm) { $dm = $this->createDownloadManager(new IO\NullIO(), $config);