/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $verbose = $input->getOption('verbose'); $force = $input->getOption('force'); $package = $input->getArgument('package'); $doctrine = $this->getContainer()->get('doctrine'); $router = $this->getContainer()->get('router'); $flags = 0; if ($package) { $packages = array(array('id' => $doctrine->getRepository('PackagistWebBundle:Package')->findOneByName($package)->getId())); $flags = Updater::UPDATE_TAGS; } elseif ($force) { $packages = $doctrine->getEntityManager()->getConnection()->fetchAll('SELECT id FROM package ORDER BY id ASC'); $flags = Updater::UPDATE_TAGS; } else { $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getStalePackages(); } $ids = array(); foreach ($packages as $package) { $ids[] = $package['id']; } if ($input->getOption('delete-before')) { $flags = Updater::DELETE_BEFORE; } $updater = $this->getContainer()->get('packagist.package_updater'); $start = new \DateTime(); $input->setInteractive(false); $io = $verbose ? new ConsoleIO($input, $output, $this->getApplication()->getHelperSet()) : new NullIO(); $config = Factory::createConfig(); $loader = new ValidatingArrayLoader(new ArrayLoader()); while ($ids) { $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getPackagesWithVersions(array_splice($ids, 0, 50)); foreach ($packages as $package) { if ($verbose) { $output->writeln('Importing ' . $package->getRepository()); } try { $repository = new VcsRepository(array('url' => $package->getRepository()), $io, $config); $repository->setLoader($loader); $updater->update($package, $repository, $flags, $start); } catch (\Exception $e) { $output->writeln('<error>Exception: ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine() . ', skipping package ' . $router->generate('view_package', array('name' => $package->getName()), true) . '</error>'); } } $doctrine->getEntityManager()->clear(); unset($packages); } }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $verbose = $input->getOption('verbose'); $force = $input->getOption('force'); $package = $input->getArgument('package'); $doctrine = $this->getContainer()->get('doctrine'); $router = $this->getContainer()->get('router'); $flags = 0; if ($package) { $packages = array(array('id' => $doctrine->getRepository('PackagistWebBundle:Package')->findOneByName($package)->getId())); $flags = $force ? Updater::UPDATE_EQUAL_REFS : 0; } elseif ($force) { $packages = $doctrine->getManager()->getConnection()->fetchAll('SELECT id FROM package ORDER BY id ASC'); $flags = Updater::UPDATE_EQUAL_REFS; } else { $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getStalePackages(); } $ids = array(); foreach ($packages as $package) { $ids[] = $package['id']; } if ($input->getOption('delete-before')) { $flags = Updater::DELETE_BEFORE; } elseif ($input->getOption('update-equal-refs')) { $flags = Updater::UPDATE_EQUAL_REFS; } $updater = $this->getContainer()->get('packagist.package_updater'); $start = new \DateTime(); if ($verbose && $input->getOption('notify-failures')) { throw new \LogicException('Failures can not be notified in verbose mode since the output is piped to the CLI'); } $input->setInteractive(false); $config = Factory::createConfig(); $io = $verbose ? new ConsoleIO($input, $output, $this->getApplication()->getHelperSet()) : new BufferIO(''); $io->loadConfiguration($config); $loader = new ValidatingArrayLoader(new ArrayLoader()); while ($ids) { $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getPackagesWithVersions(array_splice($ids, 0, 50)); foreach ($packages as $package) { if ($verbose) { $output->writeln('Importing ' . $package->getRepository()); } try { if (null === $io || $io instanceof BufferIO) { $io = new BufferIO(''); $io->loadConfiguration($config); } $repository = new VcsRepository(array('url' => $package->getRepository()), $io, $config); $repository->setLoader($loader); $updater->update($io, $config, $package, $repository, $flags, $start); } catch (InvalidRepositoryException $e) { $output->writeln('<error>Broken repository in ' . $router->generate('view_package', array('name' => $package->getName()), true) . ': ' . $e->getMessage() . '</error>'); if ($input->getOption('notify-failures')) { if (!$this->getContainer()->get('packagist.package_manager')->notifyUpdateFailure($package, $e, $io->getOutput())) { $output->writeln('<error>Failed to notify maintainers</error>'); } } } catch (\Exception $e) { $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>'); } } $doctrine->getManager()->clear(); unset($packages); } }
/** * Perform the package update * * @param Request $request the current request * @param string $url the repository's URL (deducted from the request) * @param string $urlRegex the regex used to split the user packages into domain and path * @return Response */ protected function receivePost(Request $request, $url, $urlRegex) { // try to parse the URL first to avoid the DB lookup on malformed requests if (!preg_match($urlRegex, $url)) { return new Response(json_encode(array('status' => 'error', 'message' => 'Could not parse payload repository URL')), 406); } // find the user $user = $this->findUser($request); if (!$user) { return new Response(json_encode(array('status' => 'error', 'message' => 'Invalid credentials')), 403); } // try to find the user package $packages = $this->findPackagesByUrl($user, $url, $urlRegex); if (!$packages) { return new Response(json_encode(array('status' => 'error', 'message' => 'Could not find a package that matches this request (does user maintain the package?)')), 404); } // don't die if this takes a while set_time_limit(3600); // put both updating the database and scanning the repository in a transaction $em = $this->get('doctrine.orm.entity_manager'); $updater = $this->get('packagist.package_updater'); $config = Factory::createConfig(); $io = new BufferIO('', OutputInterface::VERBOSITY_VERBOSE, new HtmlOutputFormatter(Factory::createAdditionalStyles())); $io->loadConfiguration($config); try { foreach ($packages as $package) { $em->transactional(function ($em) use($package, $updater, $io, $config) { // prepare dependencies $loader = new ValidatingArrayLoader(new ArrayLoader()); // prepare repository $repository = new VcsRepository(array('url' => $package->getRepository()), $io, $config); $repository->setLoader($loader); // perform the actual update (fetch and re-scan the repository's source) $updater->update($io, $config, $package, $repository); // update the package entity $package->setAutoUpdated(true); $em->flush(); }); } } catch (\Exception $e) { if ($e instanceof InvalidRepositoryException) { $this->get('packagist.package_manager')->notifyUpdateFailure($package, $e, $io->getOutput()); } return new Response(json_encode(array('status' => 'error', 'message' => '[' . get_class($e) . '] ' . $e->getMessage(), 'details' => '<pre>' . $io->getOutput() . '</pre>')), 400); } return new JsonResponse(array('status' => 'success'), 202); }
protected function receivePost(Request $request, $urlRegex, $optionalRepositorySuffix) { $payload = json_decode($request->request->get('payload'), true); if (!$payload || !isset($payload['repository']['url'])) { return new Response(json_encode(array('status' => 'error', 'message' => 'Missing or invalid payload')), 406); } // try to parse the URL first to avoid the DB lookup on malformed requests if (!preg_match($urlRegex, $payload['repository']['url'], $match)) { return new Response(json_encode(array('status' => 'error', 'message' => 'Could not parse payload repository URL')), 406); } $payloadRepositoryChunk = $match['url']; $username = $request->request->has('username') ? $request->request->get('username') : $request->query->get('username'); $apiToken = $request->request->has('apiToken') ? $request->request->get('apiToken') : $request->query->get('apiToken'); $user = $this->get('packagist.user_repository')->findOneBy(array('username' => $username, 'apiToken' => $apiToken)); if (!$user) { return new Response(json_encode(array('status' => 'error', 'message' => 'Invalid credentials')), 403); } $updated = false; $config = Factory::createConfig(); $loader = new ValidatingArrayLoader(new ArrayLoader()); $updater = $this->get('packagist.package_updater'); $em = $this->get('doctrine.orm.entity_manager'); foreach ($user->getPackages() as $package) { if (preg_match('{' . preg_quote($payloadRepositoryChunk) . $optionalRepositorySuffix . '}', $package->getRepository())) { set_time_limit(3600); $updated = true; $repository = new VcsRepository(array('url' => $package->getRepository()), new NullIO(), $config); $repository->setLoader($loader); $package->setAutoUpdated(true); $em->flush(); $updater->update($package, $repository); } } if ($updated) { return new Response('{"status": "success"}', 202); } return new Response(json_encode(array('status' => 'error', 'message' => 'Could not find a package that matches this request (does user maintain the package?)')), 404); }
/** * @Template() * @Route("/packages/{name}", name="update_package", requirements={"name"="[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+"}, defaults={"_format" = "json"}) * @Method({"PUT"}) */ public function updatePackageAction(Request $req, $name) { $doctrine = $this->getDoctrine(); try { /** @var Package $package */ $package = $doctrine->getRepository('PackagistWebBundle:Package')->getPackageByName($name); } catch (NoResultException $e) { return new Response(json_encode(array('status' => 'error', 'message' => 'Package not found')), 404); } $username = $req->request->has('username') ? $req->request->get('username') : $req->query->get('username'); $apiToken = $req->request->has('apiToken') ? $req->request->get('apiToken') : $req->query->get('apiToken'); $update = $req->request->get('update', $req->query->get('update')); $autoUpdated = $req->request->get('autoUpdated', $req->query->get('autoUpdated')); $updateEqualRefs = $req->request->get('updateAll', $req->query->get('updateAll')); $user = $this->getUser() ?: $doctrine->getRepository('PackagistWebBundle:User')->findOneBy(array('username' => $username, 'apiToken' => $apiToken)); if (!$user) { return new Response(json_encode(array('status' => 'error', 'message' => 'Invalid credentials')), 403); } if ($package->getMaintainers()->contains($user) || $this->isGranted('ROLE_UPDATE_PACKAGES')) { $req->getSession()->save(); if (null !== $autoUpdated) { $package->setAutoUpdated((bool) $autoUpdated); $doctrine->getManager()->flush(); } if ($update) { set_time_limit(3600); $updater = $this->get('packagist.package_updater'); $io = new BufferIO('', OutputInterface::VERBOSITY_VERY_VERBOSE, new HtmlOutputFormatter(Factory::createAdditionalStyles())); $config = Factory::createConfig(); $io->loadConfiguration($config); $repository = new VcsRepository(array('url' => $package->getRepository()), $io, $config); $loader = new ValidatingArrayLoader(new ArrayLoader()); $repository->setLoader($loader); try { $updater->update($io, $config, $package, $repository, $updateEqualRefs ? Updater::UPDATE_EQUAL_REFS : 0); } catch (\Exception $e) { return new Response(json_encode(array('status' => 'error', 'message' => '[' . get_class($e) . '] ' . $e->getMessage(), 'details' => '<pre>' . $io->getOutput() . '</pre>')), 400); } } return new Response('{"status": "success"}', 202); } return new JsonResponse(array('status' => 'error', 'message' => 'Could not find a package that matches this request (does user maintain the package?)'), 404); }
/** * @Template() * @Route("/packages/{name}", name="update_package", requirements={"name"="[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+"}, defaults={"_format" = "json"}) * @Method({"PUT"}) */ public function updatePackageAction($name) { $doctrine = $this->getDoctrine(); try { $package = $doctrine->getRepository('PackagistWebBundle:Package')->getFullPackageByName($name); } catch (NoResultException $e) { return new Response(json_encode(array('status' => 'error', 'message' => 'Package not found')), 404); } $req = $this->getRequest(); $username = $req->request->has('username') ? $req->request->get('username') : $req->query->get('username'); $apiToken = $req->request->has('apiToken') ? $req->request->get('apiToken') : $req->query->get('apiToken'); $update = $req->request->get('update', $req->query->get('update')); $autoUpdated = $req->request->get('autoUpdated', $req->query->get('autoUpdated')); $user = $this->getUser() ?: $doctrine->getRepository('PackagistWebBundle:User')->findOneBy(array('username' => $username, 'apiToken' => $apiToken)); if (!$user) { return new Response(json_encode(array('status' => 'error', 'message' => 'Invalid credentials')), 403); } if ($package->getMaintainers()->contains($user) || $this->get('security.context')->isGranted('ROLE_UPDATE_PACKAGES')) { if (null !== $autoUpdated) { $package->setAutoUpdated((bool) $autoUpdated); $doctrine->getManager()->flush(); } if ($update) { set_time_limit(3600); $updater = $this->get('packagist.package_updater'); $config = Factory::createConfig(); $repository = new VcsRepository(array('url' => $package->getRepository()), new NullIO(), $config); $loader = new ValidatingArrayLoader(new ArrayLoader()); $repository->setLoader($loader); $updater->update($package, $repository, Updater::UPDATE_TAGS); } return new Response('{"status": "success"}', 202); } return new Response(json_encode(array('status' => 'error', 'message' => 'Could not find a package that matches this request (does user maintain the package?)')), 404); }