/** * @param string $url * @param string $token * @param bool $cacheDir * @param null $bufferIO * * @throws \Exception */ public function __construct($url, $token = '', $cacheDir = false, $bufferIO = null) { $this->url = $url; $this->io = new NullIO(); $this->log = $bufferIO ? $bufferIO : new BufferIO(); $config = Factory::createConfig(); $cfg = ['config' => []]; if ($cacheDir) { $cfg['config']['cache-dir'] = $cacheDir; } if ($token) { $cfg['config']['github-oauth'] = ['github.com' => $token]; } $config->merge($cfg); $this->cacheDir = $cacheDir; $this->io->loadConfiguration($config); $this->repository = new Repository\VcsRepository(['url' => $url, 'no-api' => false], $this->io, $config); $driver = $this->vcsDriver = $this->repository->getDriver(); if (!$driver) { throw new \Exception('No driver found for <' . $url . '>'); } $this->driver = $driver; $composerInfoMaster = $this->driver->getComposerInformation($this->driver->getRootIdentifier()); if (!$composerInfoMaster) { throw new \Exception('master must have a valid composer.json'); } $this->name = $composerInfoMaster['name']; list($this->vendorName, $this->packageName) = explode('/', $this->name); preg_match('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):)([^/]+)/(.+?)(?:\\.git|/)?$#', $this->url, $match); $this->gitHubVendorName = $match[3]; $this->gitHubRepositoryName = $match[4]; $client = new \Github\Client(); $client->authenticate($token, null, \GitHub\Client::AUTH_URL_TOKEN); $this->client = $client; }
/** * Validate repository URL * * @param $repositoryUrl * @return bool */ protected function isRepositoryValid($repositoryUrl) { $io = new NullIO(); $config = Factory::createConfig(); $io->loadConfiguration($config); $repository = new VcsRepository(array('url' => $repositoryUrl), $io, $config); if (!($driver = $repository->getDriver())) { return false; } $information = $driver->getComposerInformation($driver->getRootIdentifier()); return !empty($information['name']); }
/** * @return string[] */ private function fetch() { $this->io->write(sprintf(' - Updating <info>%s</info> tag list', $this->package)); if (isset($_ENV['HRDNS_PHANTOMJS_VERSION']) && !empty($_ENV['HRDNS_PHANTOMJS_VERSION'])) { $this->cache = [$_ENV['HRDNS_PHANTOMJS_VERSION']]; } if ($this->cache === null) { $this->cache = []; $this->io->writeError(" Downloading: <comment>Connecting...</comment>", false); $repo = new VcsRepository(['url' => $this->url, 'type' => $this->type], $this->io, $this->config); $this->cache = array_keys($repo->getDriver()->getTags()); $this->io->overwriteError('', false); $this->io->overwriteError(sprintf("\r Found <comment>%d</comment> versions\n", count($this->cache))); } return $this->cache; }
/** * @return string[] */ private function fetch() { $this->io->write(sprintf(' - Updating <info>%s</info> tag list', $this->package)); if (isset($_ENV['HRDNS_SELENIUM_VERSION']) && !empty($_ENV['HRDNS_SELENIUM_VERSION'])) { $this->cache = [$_ENV['HRDNS_SELENIUM_VERSION']]; } if ($this->cache === null) { $this->cache = []; $this->io->writeError(" Downloading: <comment>Connecting...</comment>", false); $repo = new VcsRepository(['url' => $this->url, 'type' => $this->type], $this->io, $this->config); $this->cache = array_keys($repo->getDriver()->getTags()); $this->io->overwriteError(" Downloading: <comment>100%</comment>", false); $this->cache = array_filter($this->cache, function ($version) { return strpos($version, 'selenium-') === 0; }); array_walk($this->cache, function (&$value) { $value = substr($value, 9); }); $this->io->overwriteError(sprintf("\r Found <comment>%d</comment> versions\n", count($this->cache))); } return $this->cache; }
/** * Set repository * * @param string $repository */ public function setRepository($repoUrl) { $this->vcsDriver = null; // prevent local filesystem URLs if (preg_match('{^(\\.|[a-z]:|/)}i', $repoUrl)) { return; } $this->repository = $repoUrl; // avoid user@host URLs if (preg_match('{https?://.+@}', $repoUrl)) { return; } try { $io = new NullIO(); $config = Factory::createConfig(); $io->loadConfiguration($config); $repository = new VcsRepository(array('url' => $this->repository), $io, $config); $driver = $this->vcsDriver = $repository->getDriver(); if (!$driver) { return; } $information = $driver->getComposerInformation($driver->getRootIdentifier()); if (!isset($information['name'])) { return; } if (null === $this->getName()) { $this->setName($information['name']); } if ($driver instanceof GitHubDriver) { $this->repository = $driver->getRepositoryUrl(); } } catch (\Exception $e) { $this->vcsDriverError = '[' . get_class($e) . '] ' . $e->getMessage(); } }
private function updateGitHubInfo(RemoteFilesystem $rfs, Package $package, $owner, $repo, VcsRepository $repository) { $baseApiUrl = 'https://api.github.com/repos/' . $owner . '/' . $repo; $driver = $repository->getDriver(); if (!$driver instanceof GitHubDriver) { return; } $repoData = $driver->getRepoData(); try { $opts = ['http' => ['header' => ['Accept: application/vnd.github.v3.html']]]; $readme = $rfs->getContents('github.com', $baseApiUrl . '/readme', false, $opts); } catch (\Exception $e) { if (!$e instanceof \Composer\Downloader\TransportException || $e->getCode() !== 404) { return; } // 404s just mean no readme present so we proceed with the rest } if (!empty($readme)) { $elements = array('p', 'br', 'small', 'strong', 'b', 'em', 'i', 'strike', 'sub', 'sup', 'ins', 'del', 'ol', 'ul', 'li', 'h1', 'h2', 'h3', 'dl', 'dd', 'dt', 'pre', 'code', 'samp', 'kbd', 'q', 'blockquote', 'abbr', 'cite', 'table', 'thead', 'tbody', 'th', 'tr', 'td', 'a[href|target|rel|id]', 'img[src|title|alt|width|height|style]'); $config = \HTMLPurifier_Config::createDefault(); $config->set('HTML.Allowed', implode(',', $elements)); $config->set('Attr.EnableID', true); $config->set('Attr.AllowedFrameTargets', ['_blank']); $purifier = new \HTMLPurifier($config); $readme = $purifier->purify($readme); $dom = new \DOMDocument(); $dom->loadHTML('<?xml encoding="UTF-8">' . $readme); // Links can not be trusted, mark them nofollow and convert relative to absolute links $links = $dom->getElementsByTagName('a'); foreach ($links as $link) { $link->setAttribute('rel', 'nofollow noopener external'); if ('#' === substr($link->getAttribute('href'), 0, 1)) { $link->setAttribute('href', '#user-content-' . substr($link->getAttribute('href'), 1)); } elseif ('mailto:' === substr($link->getAttribute('href'), 0, 7)) { // do nothing } elseif (false === strpos($link->getAttribute('href'), '//')) { $link->setAttribute('href', 'https://github.com/' . $owner . '/' . $repo . '/blob/HEAD/' . $link->getAttribute('href')); } } // convert relative to absolute images $images = $dom->getElementsByTagName('img'); foreach ($images as $img) { if (false === strpos($img->getAttribute('src'), '//')) { $img->setAttribute('src', 'https://raw.github.com/' . $owner . '/' . $repo . '/HEAD/' . $img->getAttribute('src')); } } // remove first title as it's usually the project name which we don't need if ($dom->getElementsByTagName('h1')->length) { $first = $dom->getElementsByTagName('h1')->item(0); $first->parentNode->removeChild($first); } elseif ($dom->getElementsByTagName('h2')->length) { $first = $dom->getElementsByTagName('h2')->item(0); $first->parentNode->removeChild($first); } $readme = $dom->saveHTML(); $readme = substr($readme, strpos($readme, '<body>') + 6); $readme = substr($readme, 0, strrpos($readme, '</body>')); $package->setReadme($readme); } if (!empty($repoData['language'])) { $package->setLanguage($repoData['language']); } if (isset($repoData['stargazers_count'])) { $package->setGitHubStars($repoData['stargazers_count']); } if (isset($repoData['subscribers_count'])) { $package->setGitHubWatches($repoData['subscribers_count']); } if (isset($repoData['network_count'])) { $package->setGitHubForks($repoData['network_count']); } if (isset($repoData['open_issues_count'])) { $package->setGitHubOpenIssues($repoData['open_issues_count']); } }
/** * Set repository * * @param string $repository */ public function setRepository($repository) { $this->repository = $repository; // avoid user@host URLs if (preg_match('{//.+@}', $repository)) { return; } try { $repository = new VcsRepository(array('url' => $repository), new NullIO()); $repo = $this->repositoryClass = $repository->getDriver(); if (!$repo) { return; } $information = $repo->getComposerInformation($repo->getRootIdentifier()); $this->setName($information['name']); } catch (\UnexpectedValueException $e) { } }
/** * Set repository * * @param string $repository */ public function setRepository($repository) { $this->vcsDriver = null; // prevent local filesystem URLs if (preg_match('{^(\\.|[a-z]:|/)}i', $repository)) { return; } $this->repository = $repository; // avoid user@host URLs if (preg_match('{//.+@}', $repository)) { return; } try { $config = Factory::createConfig(); $repository = new VcsRepository(array('url' => $repository), new NullIO(), $config); $driver = $this->vcsDriver = $repository->getDriver(); if (!$driver) { return; } $information = $driver->getComposerInformation($driver->getRootIdentifier()); if (!isset($information['name'])) { throw new \RuntimeException('No name found in composer.json'); } if (null === $this->getName()) { $this->setName($information['name']); } } catch (\Exception $e) { } }