UpdatePackagesCommand.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. /*
  3. * This file is part of Packagist.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. * Nils Adermann <naderman@naderman.de>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Packagist\WebBundle\Command;
  12. use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
  13. use Symfony\Component\Console\Input\InputInterface;
  14. use Symfony\Component\Console\Input\InputOption;
  15. use Symfony\Component\Console\Input\InputArgument;
  16. use Symfony\Component\Console\Output\OutputInterface;
  17. use Packagist\WebBundle\Package\Updater;
  18. use Composer\Repository\VcsRepository;
  19. use Composer\Factory;
  20. use Composer\Package\Loader\ValidatingArrayLoader;
  21. use Composer\Package\Loader\ArrayLoader;
  22. use Composer\IO\BufferIO;
  23. use Composer\IO\ConsoleIO;
  24. use Composer\Repository\InvalidRepositoryException;
  25. /**
  26. * @author Jordi Boggiano <j.boggiano@seld.be>
  27. */
  28. class UpdatePackagesCommand extends ContainerAwareCommand
  29. {
  30. /**
  31. * {@inheritdoc}
  32. */
  33. protected function configure()
  34. {
  35. $this
  36. ->setName('packagist:update')
  37. ->setDefinition(array(
  38. new InputOption('force', null, InputOption::VALUE_NONE, 'Force a re-crawl of all packages'),
  39. new InputOption('delete-before', null, InputOption::VALUE_NONE, 'Force deletion of all versions before an update'),
  40. new InputOption('notify-failures', null, InputOption::VALUE_NONE, 'Notify failures to maintainers by email'),
  41. new InputArgument('package', InputArgument::OPTIONAL, 'Package name to update'),
  42. ))
  43. ->setDescription('Updates packages')
  44. ;
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. protected function execute(InputInterface $input, OutputInterface $output)
  50. {
  51. $verbose = $input->getOption('verbose');
  52. $force = $input->getOption('force');
  53. $package = $input->getArgument('package');
  54. $doctrine = $this->getContainer()->get('doctrine');
  55. $router = $this->getContainer()->get('router');
  56. $flags = 0;
  57. if ($package) {
  58. $packages = array(array('id' => $doctrine->getRepository('PackagistWebBundle:Package')->findOneByName($package)->getId()));
  59. } elseif ($force) {
  60. $packages = $doctrine->getManager()->getConnection()->fetchAll('SELECT id FROM package ORDER BY id ASC');
  61. } else {
  62. $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getStalePackages();
  63. }
  64. $ids = array();
  65. foreach ($packages as $package) {
  66. $ids[] = $package['id'];
  67. }
  68. if ($input->getOption('delete-before')) {
  69. $flags = Updater::DELETE_BEFORE;
  70. }
  71. $updater = $this->getContainer()->get('packagist.package_updater');
  72. $start = new \DateTime();
  73. if ($verbose && $input->getOption('notify-failures')) {
  74. throw new \LogicException('Failures can not be notified in verbose mode since the output is piped to the CLI');
  75. }
  76. $input->setInteractive(false);
  77. $config = Factory::createConfig();
  78. $io = $verbose ? new ConsoleIO($input, $output, $this->getApplication()->getHelperSet()) : new BufferIO('');
  79. $io->loadConfiguration($config);
  80. $loader = new ValidatingArrayLoader(new ArrayLoader());
  81. while ($ids) {
  82. $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getPackagesWithVersions(array_splice($ids, 0, 50));
  83. foreach ($packages as $package) {
  84. if ($verbose) {
  85. $output->writeln('Importing '.$package->getRepository());
  86. }
  87. try {
  88. if (null === $io || $io instanceof BufferIO) {
  89. $io = new BufferIO('');
  90. $io->loadConfiguration($config);
  91. }
  92. $repository = new VcsRepository(array('url' => $package->getRepository()), $io, $config);
  93. $repository->setLoader($loader);
  94. $updater->update($package, $repository, $flags, $start);
  95. } catch (InvalidRepositoryException $e) {
  96. $output->writeln('<error>Broken repository in '.$router->generate('view_package', array('name' => $package->getName()), true).': '.$e->getMessage().'</error>');
  97. if ($input->getOption('notify-failures')) {
  98. if (!$this->getContainer()->get('packagist.package_manager')->notifyUpdateFailure($package, $e, $io->getOutput())) {
  99. $output->writeln('<error>Failed to notify maintainers</error>');
  100. }
  101. }
  102. } catch (\Exception $e) {
  103. $output->writeln('<error>Error updating '.$router->generate('view_package', array('name' => $package->getName()), true).' ['.get_class($e).']: '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().'</error>');
  104. }
  105. }
  106. $doctrine->getManager()->clear();
  107. unset($packages);
  108. }
  109. }
  110. }