/** * Create a new instance. * * @param RepositoryInterface $repository */ public function __construct(RepositoryInterface $repository) { $this->repository = $repository; $this->decorateBaseUrl = null; if ($this->repository instanceof ComposerRepository) { $repoConfig = $this->repository->getRepoConfig(); if (!preg_match('{^[\\w.]+\\??://}', $repoConfig['url'])) { // assume https as the default protocol $repoConfig['url'] = 'https://' . $repoConfig['url']; } $this->decorateBaseUrl = rtrim($repoConfig['url'], '/') . '/packages/%1$s.json'; } }
/** * Update a project * * @param \Packagist\WebBundle\Entity\Package $package * @param RepositoryInterface $repository the repository instance used to update from * @param int $flags a few of the constants of this class * @param \DateTime $start */ public function update(IOInterface $io, Config $config, Package $package, RepositoryInterface $repository, $flags = 0, \DateTime $start = null) { $rfs = new RemoteFilesystem($io, $config); $blacklist = '{^symfony/symfony (2.0.[456]|dev-charset|dev-console)}i'; if (null === $start) { $start = new \DateTime(); } $pruneDate = clone $start; $pruneDate->modify('-1min'); $em = $this->doctrine->getManager(); $apc = extension_loaded('apcu'); if ($repository instanceof VcsRepository) { $cfg = $repository->getRepoConfig(); if (isset($cfg['url']) && preg_match('{\\bgithub\\.com\\b}', $cfg['url'])) { foreach ($package->getMaintainers() as $maintainer) { if (!($newGithubToken = $maintainer->getGithubToken())) { continue; } $valid = null; if ($apc) { $valid = apcu_fetch('is_token_valid_' . $maintainer->getUsernameCanonical()); } if (true !== $valid) { $context = stream_context_create(['http' => ['header' => 'User-agent: packagist-token-check']]); $rate = json_decode(@file_get_contents('https://api.github.com/rate_limit?access_token=' . $newGithubToken, false, $context), true); // invalid/outdated token, wipe it so we don't try it again if (!$rate && (strpos($http_response_header[0], '403') || strpos($http_response_header[0], '401'))) { $maintainer->setGithubToken(null); $em->flush($maintainer); continue; } } if ($apc) { apcu_store('is_token_valid_' . $maintainer->getUsernameCanonical(), true, 86400); } $io->setAuthentication('github.com', $newGithubToken, 'x-oauth-basic'); break; } } } $versions = $repository->getPackages(); usort($versions, function ($a, $b) { $aVersion = $a->getVersion(); $bVersion = $b->getVersion(); if ($aVersion === '9999999-dev' || 'dev-' === substr($aVersion, 0, 4)) { $aVersion = 'dev'; } if ($bVersion === '9999999-dev' || 'dev-' === substr($bVersion, 0, 4)) { $bVersion = 'dev'; } $aIsDev = $aVersion === 'dev' || substr($aVersion, -4) === '-dev'; $bIsDev = $bVersion === 'dev' || substr($bVersion, -4) === '-dev'; // push dev versions to the end if ($aIsDev !== $bIsDev) { return $aIsDev ? 1 : -1; } // equal versions are sorted by date if ($aVersion === $bVersion) { return $a->getReleaseDate() > $b->getReleaseDate() ? 1 : -1; } // the rest is sorted by version return version_compare($aVersion, $bVersion); }); $versionRepository = $this->doctrine->getRepository('PackagistWebBundle:Version'); if ($flags & self::DELETE_BEFORE) { foreach ($package->getVersions() as $version) { $versionRepository->remove($version); } $em->flush(); $em->refresh($package); } $lastUpdated = true; $lastProcessed = null; foreach ($versions as $version) { if ($version instanceof AliasPackage) { continue; } if (preg_match($blacklist, $version->getName() . ' ' . $version->getPrettyVersion())) { continue; } if ($lastProcessed && $lastProcessed->getVersion() === $version->getVersion()) { $io->write('Skipping version ' . $version->getPrettyVersion() . ' (duplicate of ' . $lastProcessed->getPrettyVersion() . ')', true, IOInterface::VERBOSE); continue; } $lastProcessed = $version; $lastUpdated = $this->updateInformation($package, $version, $flags); if ($lastUpdated) { $em->flush(); } } if (!$lastUpdated) { $em->flush(); } // remove outdated versions foreach ($package->getVersions() as $version) { if ($version->getUpdatedAt() < $pruneDate) { $versionRepository->remove($version); } } if (preg_match('{^(?:git://|git@|https?://)github.com[:/]([^/]+)/(.+?)(?:\\.git|/)?$}i', $package->getRepository(), $match) && $repository instanceof VcsRepository) { $this->updateGitHubInfo($rfs, $package, $match[1], $match[2], $repository); } $package->setUpdatedAt(new \DateTime()); $package->setCrawledAt(new \DateTime()); $em->flush(); if ($repository->hadInvalidBranches()) { throw new InvalidRepositoryException('Some branches contained invalid data and were discarded, it is advised to review the log and fix any issues present in branches'); } }