Exemplo n.º 1
0
 /**
  * Download the file and return its contents
  * 
  * @param string $url The URL from where to download
  * @return string Contents of the URL
  */
 public function getContents($url)
 {
     if (array_key_exists($url, $this->cache)) {
         return $this->cache[$url];
     }
     return $this->cache[$url] = $this->remoteFileSystem->getContents($this->getOriginUrl($url), $url);
 }
Exemplo n.º 2
0
 /**
  * Read content from remote filesystem.
  *
  * @param $origin string server
  * @param $path   string relative path to content
  * @throws \UnexpectedValueException
  * @return \SimpleXMLElement
  */
 protected function requestContent($origin, $path)
 {
     $url = rtrim($origin, '/') . '/' . ltrim($path, '/');
     $content = $this->rfs->getContents($origin, $url, false);
     if (!$content) {
         throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.');
     }
     return str_replace('http://pear.php.net/rest/', 'https://pear.php.net/rest/', $content);
 }
 /**
  * Read content from remote filesystem.
  *
  * @param $origin string server
  * @param $path   string relative path to content
  * @return \SimpleXMLElement
  */
 protected function requestContent($origin, $path)
 {
     $url = rtrim($origin, '/') . '/' . ltrim($path, '/');
     $content = $this->rfs->getContents($origin, $url, false);
     if (!$content) {
         throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.');
     }
     return $content;
 }
Exemplo n.º 4
0
 /**
  * @inheritDoc
  */
 public function getContents($originUrl, $fileUrl, $progress = true, $options = array())
 {
     $res = null;
     if (isset($options['http']['header'])) {
         $headers = $options['http']['header'];
     } elseif (isset($options['https']['header'])) {
         $headers = $options['https']['header'];
     } else {
         $headers = array();
     }
     try {
         $this->req = new FetchRequest($fileUrl, $this->io, $this->config);
         foreach ($headers as $header) {
             list($key, $val) = explode(':', $header, 2);
             $this->req->addHeader($key, $val);
         }
         $res = $this->req->fetch();
     } catch (\Exception $e) {
         $this->io->writeError((string) $e);
     }
     if (false === $res) {
         return parent::getContents($originUrl, $fileUrl, $progress, $options);
     } else {
         return $res;
     }
 }
Exemplo n.º 5
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $rfs = new RemoteFilesystem($this->getIO());
     $latest = trim($rfs->getContents('getcomposer.org', 'http://getcomposer.org/version', false));
     if (Composer::VERSION !== $latest) {
         $output->writeln(sprintf("Updating to version <info>%s</info>.", $latest));
         $remoteFilename = 'http://getcomposer.org/composer.phar';
         $localFilename = $_SERVER['argv'][0];
         $tempFilename = basename($localFilename, '.phar') . '-temp.phar';
         $rfs->copy('getcomposer.org', $remoteFilename, $tempFilename);
         try {
             chmod($tempFilename, 0777 & ~umask());
             // test the phar validity
             $phar = new \Phar($tempFilename);
             // free the variable to unlock the file
             unset($phar);
             rename($tempFilename, $localFilename);
         } catch (\Exception $e) {
             @unlink($tempFilename);
             if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
                 throw $e;
             }
             $output->writeln('<error>The download is corrupted (' . $e->getMessage() . ').</error>');
             $output->writeln('<error>Please re-run the self-update command to try again.</error>');
         }
     } else {
         $output->writeln("<info>You are using the latest composer version.</info>");
     }
 }
Exemplo n.º 6
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $baseUrl = (extension_loaded('openssl') ? 'https' : 'http') . '://' . self::HOMEPAGE;
     $config = Factory::createConfig();
     $remoteFilesystem = new RemoteFilesystem($this->getIO(), $config);
     $cacheDir = $config->get('cache-dir');
     $rollbackDir = $config->get('home');
     $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
     // check if current dir is writable and if not try the cache dir from settings
     $tmpDir = is_writable(dirname($localFilename)) ? dirname($localFilename) : $cacheDir;
     // check for permissions in local filesystem before start connection process
     if (!is_writable($tmpDir)) {
         throw new FilesystemException('Composer update failed: the "' . $tmpDir . '" directory used to download the temp file could not be written');
     }
     if (!is_writable($localFilename)) {
         throw new FilesystemException('Composer update failed: the "' . $localFilename . '" file could not be written');
     }
     if ($input->getOption('rollback')) {
         return $this->rollback($output, $rollbackDir, $localFilename);
     }
     $latestVersion = trim($remoteFilesystem->getContents(self::HOMEPAGE, $baseUrl . '/version', false));
     $updateVersion = $input->getArgument('version') ?: $latestVersion;
     if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
         $output->writeln('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>');
         return 1;
     }
     if (Composer::VERSION === $updateVersion) {
         $output->writeln('<info>You are already using composer version ' . $updateVersion . '.</info>');
         return 0;
     }
     $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar') . '-temp.phar';
     $backupFile = sprintf('%s/%s-%s%s', $rollbackDir, strtr(Composer::RELEASE_DATE, ' :', '_-'), preg_replace('{^([0-9a-f]{7})[0-9a-f]{33}$}', '$1', Composer::VERSION), self::OLD_INSTALL_EXT);
     $output->writeln(sprintf("Updating to version <info>%s</info>.", $updateVersion));
     $remoteFilename = $baseUrl . (preg_match('{^[0-9a-f]{40}$}', $updateVersion) ? '/composer.phar' : "/download/{$updateVersion}/composer.phar");
     $remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename);
     if (!file_exists($tempFilename)) {
         $output->writeln('<error>The download of the new composer version failed for an unexpected reason</error>');
         return 1;
     }
     // remove saved installations of composer
     if ($input->getOption('clean-backups')) {
         $finder = $this->getOldInstallationFinder($rollbackDir);
         $fs = new Filesystem();
         foreach ($finder as $file) {
             $file = (string) $file;
             $output->writeln('<info>Removing: ' . $file . '</info>');
             $fs->remove($file);
         }
     }
     if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) {
         $output->writeln('<error>The file is corrupted (' . $err->getMessage() . ').</error>');
         $output->writeln('<error>Please re-run the self-update command to try again.</error>');
         return 1;
     }
     if (file_exists($backupFile)) {
         $output->writeln('Use <info>composer self-update --rollback</info> to return to version ' . Composer::VERSION);
     } else {
         $output->writeln('<warning>A backup of the current version could not be written to ' . $backupFile . ', no rollback possible</warning>');
     }
 }
Exemplo n.º 7
0
 /**
  * @param InputInterface $input The input instance
  * @param OutputInterface $output The output instance
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $verbose = $input->getOption('verbose');
     $configFile = $input->getArgument('file');
     $packagesFilter = $input->getArgument('packages');
     $skipErrors = (bool) $input->getOption('skip-errors');
     // load auth.json authentication information and pass it to the io interface
     $io = $this->getIO();
     $io->loadConfiguration($this->getConfiguration());
     if (preg_match('{^https?://}i', $configFile)) {
         $rfs = new RemoteFilesystem($io);
         $contents = $rfs->getContents(parse_url($configFile, PHP_URL_HOST), $configFile, false);
         $config = JsonFile::parseJson($contents, $configFile);
     } else {
         $file = new JsonFile($configFile);
         if (!$file->exists()) {
             $output->writeln('<error>File not found: ' . $configFile . '</error>');
             return 1;
         }
         $config = $file->read();
     }
     // disable packagist by default
     unset(Config::$defaultRepositories['packagist']);
     if (!($outputDir = $input->getArgument('output-dir'))) {
         $outputDir = isset($config['output-dir']) ? $config['output-dir'] : null;
     }
     if (null === $outputDir) {
         throw new \InvalidArgumentException('The output dir must be specified as second argument or be configured inside ' . $input->getArgument('file'));
     }
     $composer = $this->getApplication()->getComposer(true, $config);
     $packagesBuilder = new PackagesBuilder($output, $outputDir, $config, $skipErrors);
     $packagesBuilder->setPackagesFilter($packagesFilter);
     $packages = $packagesBuilder->select($composer, $verbose);
     if (isset($config['archive']['directory'])) {
         $downloads = new ArchiveBuilder($output, $outputDir, $config, $skipErrors);
         $downloads->setInputInterface($input)->setHelperSet($this->getApplication()->getHelperSet());
         $downloads->dump($packages);
     }
     if (!$packagesBuilder->hasFilterForPackages()) {
         // in case of an active package filter we need to load the dumped packages.json and merge the
         // updated packages in
         $oldPackages = $packagesBuilder->load();
         $packages += $oldPackages;
         ksort($packages);
     }
     $packagesBuilder->dump($packages);
     if ($htmlView = !$input->getOption('no-html-output')) {
         $htmlView = !isset($config['output-html']) || $config['output-html'];
     }
     if ($htmlView) {
         $web = new WebBuilder($output, $outputDir, $config, $skipErrors);
         $web->setRootPackage($composer->getPackage());
         $web->dump($packages);
     }
 }
Exemplo n.º 8
0
 /**
  * @param InputInterface  $input  The input instance
  * @param OutputInterface $output The output instance
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $verbose = $input->getOption('verbose');
     $configFile = $input->getArgument('file');
     if (preg_match('{^https?://}i', $configFile)) {
         $rfs = new RemoteFilesystem($this->getIO());
         $contents = $rfs->getContents(parse_url($configFile, PHP_URL_HOST), $configFile, false);
         $config = JsonFile::parseJson($contents, $configFile);
     } else {
         $file = new JsonFile($configFile);
         if (!$file->exists()) {
             $output->writeln('<error>File not found: ' . $configFile . '</error>');
             return 1;
         }
         $config = $file->read();
     }
     // disable packagist by default
     unset(Config::$defaultRepositories['packagist']);
     // fetch options
     $requireAll = isset($config['require-all']) && true === $config['require-all'];
     $requireDependencies = isset($config['require-dependencies']) && true === $config['require-dependencies'];
     if (!$requireAll && !isset($config['require'])) {
         $output->writeln('No explicit requires defined, enabling require-all');
         $requireAll = true;
     }
     if (!($outputDir = $input->getArgument('output-dir'))) {
         $outputDir = isset($config['output-dir']) ? $config['output-dir'] : null;
     }
     if (null === $outputDir) {
         throw new \InvalidArgumentException('The output dir must be specified as second argument or be configured inside ' . $input->getArgument('file'));
     }
     $composer = $this->getApplication()->getComposer(true, $config);
     $packages = $this->selectPackages($composer, $output, $verbose, $requireAll, $requireDependencies);
     if ($htmlView = !$input->getOption('no-html-output')) {
         $htmlView = !isset($config['output-html']) || $config['output-html'];
     }
     if (isset($config['archive']['directory'])) {
         $skipErrors = (bool) $input->getOption('skip-errors');
         $this->dumpDownloads($config, $packages, $output, $outputDir, $skipErrors);
     }
     $filename = $outputDir . '/packages.json';
     $this->dumpJson($packages, $output, $filename);
     if ($htmlView) {
         $dependencies = array();
         foreach ($packages as $package) {
             foreach ($package->getRequires() as $link) {
                 $dependencies[$link->getTarget()][$link->getSource()] = $link->getSource();
             }
         }
         $rootPackage = $composer->getPackage();
         $twigTemplate = isset($config['twig-template']) ? $config['twig-template'] : null;
         $this->dumpWeb($packages, $output, $rootPackage, $outputDir, $twigTemplate, $dependencies);
     }
 }
Exemplo n.º 9
0
 /**
  * @return string
  * @throws \Exception
  */
 protected function downloadComposer()
 {
     $this->output->writeln('<info>Could not find composer. Try to download it.</info>');
     $io = new ConsoleIO($this->input, $this->output, $this->getCommand()->getHelperSet());
     $rfs = new RemoteFilesystem($io);
     $composerInstaller = $rfs->getContents('getcomposer.org', 'https://getcomposer.org/installer', true);
     $tempComposerInstaller = $this->config['installationFolder'] . '/_composer_installer.php';
     file_put_contents($tempComposerInstaller, $composerInstaller);
     if (OperatingSystem::isWindows()) {
         $installCommand = 'php ' . $tempComposerInstaller . ' --force';
     } else {
         $installCommand = '/usr/bin/env php ' . $tempComposerInstaller . ' --force';
     }
     $this->output->writeln('<comment>' . $installCommand . '</comment>');
     exec($installCommand, $installationOutput, $returnStatus);
     unlink($tempComposerInstaller);
     $installationOutput = implode(PHP_EOL, $installationOutput);
     if ($returnStatus !== self::EXEC_STATUS_OK) {
         throw new \Exception('Installation failed.' . $installationOutput);
     } else {
         $this->output->writeln('<info>Successfully installed composer to Magento root</info>');
     }
     return $this->config['installationFolder'] . '/composer.phar';
 }
Exemplo n.º 10
0
 /**
  * Get the remote content.
  *
  * @param string $url The URL of content
  *
  * @return mixed The result
  */
 protected function getContents($url)
 {
     return $this->remoteFilesystem->getContents($this->originUrl, $url, false);
 }
 public function testGetContents()
 {
     $fs = new RemoteFilesystem($this->getMock('Composer\\IO\\IOInterface'));
     $this->assertContains('testGetContents', $fs->getContents('http://example.org', 'file://' . __FILE__));
 }
Exemplo n.º 12
0
 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']);
     }
 }
 /**
  * Retrieve the available versions of a package.
  *
  * NOTE: This method will become inaccessible as soon as the installation is complete.
  *
  * @param string $vendor  The vendor name of the package.
  *
  * @param string $project The name of the package.
  *
  * @return JsonResponse
  *
  * @ApiDoc(
  *   section="install",
  *   statusCodes = {
  *     201 = "When everything worked out ok",
  *     406 = "When the installation is already complete"
  *   },
  * )
  * @ApiDescription(
  *   response={
  *     "versions" = {
  *       "actualType" = "collection",
  *       "subType" = "object",
  *       "description" = "The list of versions",
  *       "children" = {
  *         "name" = {
  *           "dataType" = "string",
  *           "description" = "The name of the package"
  *         },
  *         "version" = {
  *           "dataType" = "string",
  *           "description" = "The version of the package"
  *         },
  *         "version_normalized" = {
  *           "dataType" = "string",
  *           "description" = "The normalized version of the package"
  *         },
  *         "reference" = {
  *           "dataType" = "string",
  *           "description" = "The optional reference"
  *         }
  *       }
  *     }
  *   }
  * )
  */
 public function getProjectVersionsAction($vendor, $project)
 {
     $this->checkUninstalled();
     $url = sprintf('https://packagist.org/packages/%s/%s.json', $vendor, $project);
     $rfs = new RemoteFilesystem($this->getInputOutput());
     $results = $rfs->getContents($url, $url);
     $data = new JsonArray($results);
     $versions = [];
     foreach ($data->get('package/versions') as $information) {
         $version = ['name' => $information['name'], 'version' => $information['version'], 'version_normalized' => $information['version_normalized']];
         $normalized = $information['version'];
         if ('dev-' === substr($normalized, 0, 4)) {
             if (isset($information['extra']['branch-alias'][$normalized])) {
                 $version['version_normalized'] = $information['extra']['branch-alias'][$normalized];
             }
         }
         if (isset($information['source']['reference'])) {
             $version['reference'] = $information['source']['reference'];
         } elseif (isset($information['dist']['reference'])) {
             $version['reference'] = $information['dist']['reference'];
         }
         $versions[] = $version;
     }
     return new JsonResponse(['status' => 'OK', 'versions' => $versions]);
 }
Exemplo n.º 14
0
 /**
  * Check online for the latest version available.
  *
  * @return string
  */
 protected function getLatestVersion()
 {
     $latestVersion = trim($this->rfs->getContents($this->getOriginName(), $this->getBaseUrl() . '/version', false));
     return $latestVersion;
 }
Exemplo n.º 15
0
 /**
  * @param InputInterface  $input  The input instance
  * @param OutputInterface $output The output instance
  *
  * @throws JsonValidationException
  * @throws ParsingException
  * @throws \Exception
  *
  * @return int
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $verbose = $input->getOption('verbose');
     $configFile = $input->getArgument('file');
     $packagesFilter = $input->getArgument('packages');
     $repositoryUrl = $input->getOption('repository-url');
     $skipErrors = (bool) $input->getOption('skip-errors');
     // load auth.json authentication information and pass it to the io interface
     $io = $this->getIO();
     $io->loadConfiguration($this->getConfiguration());
     if (preg_match('{^https?://}i', $configFile)) {
         $rfs = new RemoteFilesystem($io);
         $contents = $rfs->getContents(parse_url($configFile, PHP_URL_HOST), $configFile, false);
         $config = JsonFile::parseJson($contents, $configFile);
     } else {
         $file = new JsonFile($configFile);
         if (!$file->exists()) {
             $output->writeln('<error>File not found: ' . $configFile . '</error>');
             return 1;
         }
         $config = $file->read();
     }
     try {
         $this->check($configFile);
     } catch (JsonValidationException $e) {
         foreach ($e->getErrors() as $error) {
             $output->writeln(sprintf('<error>%s</error>', $error));
         }
         if (!$skipErrors) {
             throw $e;
         }
         $output->writeln(sprintf('<warning>%s: %s</warning>', get_class($e), $e->getMessage()));
     } catch (ParsingException $e) {
         if (!$skipErrors) {
             throw $e;
         }
         $output->writeln(sprintf('<warning>%s: %s</warning>', get_class($e), $e->getMessage()));
     } catch (\UnexpectedValueException $e) {
         if (!$skipErrors) {
             throw $e;
         }
         $output->writeln(sprintf('<warning>%s: %s</warning>', get_class($e), $e->getMessage()));
     }
     if ($repositoryUrl !== null && count($packagesFilter) > 0) {
         throw new \InvalidArgumentException('The arguments "package" and "repository-url" can not be used together.');
     }
     // disable packagist by default
     unset(Config::$defaultRepositories['packagist']);
     if (!($outputDir = $input->getArgument('output-dir'))) {
         $outputDir = isset($config['output-dir']) ? $config['output-dir'] : null;
     }
     if (null === $outputDir) {
         throw new \InvalidArgumentException('The output dir must be specified as second argument or be configured inside ' . $input->getArgument('file'));
     }
     /** @var $application Application */
     $application = $this->getApplication();
     $composer = $application->getComposer(true, $config);
     $packageSelection = new PackageSelection($output, $outputDir, $config, $skipErrors);
     if ($repositoryUrl !== null) {
         $packageSelection->setRepositoryFilter($repositoryUrl);
     } else {
         $packageSelection->setPackagesFilter($packagesFilter);
     }
     $packages = $packageSelection->select($composer, $verbose);
     if (isset($config['archive']['directory'])) {
         $downloads = new ArchiveBuilder($output, $outputDir, $config, $skipErrors);
         $downloads->setComposer($composer);
         $downloads->setInput($input);
         $downloads->dump($packages);
     }
     if ($packageSelection->hasFilterForPackages() || $packageSelection->hasRepositoryFilter()) {
         // in case of an active filter we need to load the dumped packages.json and merge the
         // updated packages in
         $oldPackages = $packageSelection->load();
         $packages += $oldPackages;
         ksort($packages);
     }
     $packagesBuilder = new PackagesBuilder($output, $outputDir, $config, $skipErrors);
     $packagesBuilder->dump($packages);
     if ($htmlView = !$input->getOption('no-html-output')) {
         $htmlView = !isset($config['output-html']) || $config['output-html'];
     }
     if ($htmlView) {
         $web = new WebBuilder($output, $outputDir, $config, $skipErrors);
         $web->setRootPackage($composer->getPackage());
         $web->dump($packages);
     }
     return 0;
 }
Exemplo n.º 16
0
 /**
  * @param InputInterface  $input  The input instance
  * @param OutputInterface $output The output instance
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $verbose = $input->getOption('verbose');
     $configFile = $input->getArgument('file');
     $packagesFilter = $input->getArgument('packages');
     $skipErrors = (bool) $input->getOption('skip-errors');
     // load auth.json authentication information and pass it to the io interface
     $io = $this->getIO();
     $io->loadConfiguration($this->getConfiguration());
     if (preg_match('{^https?://}i', $configFile)) {
         $rfs = new RemoteFilesystem($io);
         $contents = $rfs->getContents(parse_url($configFile, PHP_URL_HOST), $configFile, false);
         $config = JsonFile::parseJson($contents, $configFile);
     } else {
         $file = new JsonFile($configFile);
         if (!$file->exists()) {
             $output->writeln('<error>File not found: ' . $configFile . '</error>');
             return 1;
         }
         $config = $file->read();
     }
     // disable packagist by default
     unset(Config::$defaultRepositories['packagist']);
     // fetch options
     $requireAll = isset($config['require-all']) && true === $config['require-all'];
     $requireDependencies = isset($config['require-dependencies']) && true === $config['require-dependencies'];
     $requireDevDependencies = isset($config['require-dev-dependencies']) && true === $config['require-dev-dependencies'];
     if (!$requireAll && !isset($config['require'])) {
         $output->writeln('No explicit requires defined, enabling require-all');
         $requireAll = true;
     }
     $minimumStability = isset($config['minimum-stability']) ? $config['minimum-stability'] : 'dev';
     if (!($outputDir = $input->getArgument('output-dir'))) {
         $outputDir = isset($config['output-dir']) ? $config['output-dir'] : null;
     }
     if (null === $outputDir) {
         throw new \InvalidArgumentException('The output dir must be specified as second argument or be configured inside ' . $input->getArgument('file'));
     }
     $composer = $this->getApplication()->getComposer(true, $config);
     $packages = $this->selectPackages($composer, $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, $packagesFilter);
     if ($htmlView = !$input->getOption('no-html-output')) {
         $htmlView = !isset($config['output-html']) || $config['output-html'];
     }
     if (isset($config['archive']['directory'])) {
         $this->dumpDownloads($config, $packages, $input, $output, $outputDir, $skipErrors);
     }
     $filenamePrefix = $outputDir . '/include/all';
     $filename = $outputDir . '/packages.json';
     if (!empty($packagesFilter)) {
         // in case of an active package filter we need to load the dumped packages.json and merge the
         // updated packages in
         $oldPackages = $this->loadDumpedPackages($filename, $packagesFilter);
         $packages += $oldPackages;
         ksort($packages);
     }
     $packageFile = $this->dumpPackageIncludeJson($packages, $output, $filenamePrefix);
     $packageFileHash = hash_file('sha1', $packageFile);
     $includes = array('include/all$' . $packageFileHash . '.json' => array('sha1' => $packageFileHash));
     $this->dumpPackagesJson($includes, $output, $filename);
     if ($htmlView) {
         $dependencies = array();
         foreach ($packages as $package) {
             foreach ($package->getRequires() as $link) {
                 $dependencies[$link->getTarget()][$link->getSource()] = $link->getSource();
             }
         }
         $rootPackage = $composer->getPackage();
         $twigTemplate = isset($config['twig-template']) ? $config['twig-template'] : null;
         $this->dumpWeb($packages, $output, $rootPackage, $outputDir, $twigTemplate, $dependencies);
     }
 }
Exemplo n.º 17
0
    /**
     * Tests that a BitBucket public download is correctly retrieved when `bitbucket-oauth` is configured.
     *
     * @param string $url
     * @param string $contents
     * @dataProvider provideBitbucketPublicDownloadUrls
     */
    public function testBitBucketPublicDownloadWithAuthConfigured($url, $contents)
    {
        $io = $this
            ->getMockBuilder('Composer\IO\ConsoleIO')
            ->disableOriginalConstructor()
            ->getMock();

        $config = $this
            ->getMockBuilder('Composer\Config')
            ->getMock();
        $config
            ->method('get')
            ->withAnyParameters()
            ->willReturn(array());

        $io
            ->method('hasAuthentication')
            ->with('bitbucket.org')
            ->willReturn(true);
        $io
            ->method('getAuthentication')
            ->with('bitbucket.org')
            ->willReturn(array(
                'username' => 'x-token-auth',
                // This token is fake, but it matches a valid token's pattern.
                'password' => '1A0yeK5Po3ZEeiiRiMWLivS0jirLdoGuaSGq9NvESFx1Fsdn493wUDXC8rz_1iKVRTl1GINHEUCsDxGh5lZ='
            ));


        $rfs = new RemoteFilesystem($io, $config);
        $hostname = parse_url($url, PHP_URL_HOST);

        $result = $rfs->getContents($hostname, $url, false);

        $this->assertEquals($contents, $result);
    }
Exemplo n.º 18
0
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
        $tempFilename = dirname($localFilename) . '/' . basename($localFilename, '.phar') . '-temp.phar';
        // check for permissions in local filesystem before start connection process
        if (!is_writable($tempDirectory = dirname($tempFilename))) {
            throw new FilesystemException('imi-conrun update failed: the "' . $tempDirectory . '" directory used to download the temp file could not be written');
        }
        if (!is_writable($localFilename)) {
            throw new FilesystemException('imi-conrun update failed: the "' . $localFilename . '" file could not be written');
        }
        $io = new ConsoleIO($input, $output, $this->getHelperSet());
        $rfs = new RemoteFilesystem($io);
        $loadUnstable = $input->getOption('unstable');
        if ($loadUnstable) {
            $versionTxtUrl = 'https://raw.githubusercontent.com/iMi-digital/imi-conrun/develop/version.txt';
            $remoteFilename = 'https://raw.githubusercontent.com/iMi-digital/imi-conrun/develop/imi-conrun.phar';
        } else {
            $versionTxtUrl = 'https://raw.githubusercontent.com/iMi-digital/imi-conrun/master/version.txt';
            $remoteFilename = 'https://raw.githubusercontent.com/iMi-digital/imi-conrun/master/imi-conrun.phar';
        }
        $latest = trim($rfs->getContents('raw.githubusercontent.com', $versionTxtUrl, false));
        if ($this->getApplication()->getVersion() !== $latest || $loadUnstable) {
            $output->writeln(sprintf("Updating to version <info>%s</info>.", $latest));
            $rfs->copy('raw.github.com', $remoteFilename, $tempFilename);
            if (!file_exists($tempFilename)) {
                $output->writeln('<error>The download of the new imi-conrun version failed for an unexpected reason');
                return 1;
            }
            try {
                \error_reporting(E_ALL);
                // supress notices
                @chmod($tempFilename, 0777 & ~umask());
                // test the phar validity
                $phar = new \Phar($tempFilename);
                // free the variable to unlock the file
                unset($phar);
                @rename($tempFilename, $localFilename);
                $output->writeln('<info>Successfully updated imi-conrun</info>');
                if ($loadUnstable) {
                    $changeLogContent = $rfs->getContents('raw.github.com', 'https://raw.github.com/netz98/imi-conrun/develop/changes.txt', false);
                } else {
                    $changeLogContent = $rfs->getContents('raw.github.com', 'https://raw.github.com/netz98/imi-conrun/master/changes.txt', false);
                }
                if ($changeLogContent) {
                    $output->writeln($changeLogContent);
                }
                if ($loadUnstable) {
                    $unstableFooterMessage = <<<UNSTABLE_FOOTER
<comment>
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! DEVELOPMENT VERSION. DO NOT USE IN PRODUCTION !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
</comment>
UNSTABLE_FOOTER;
                    $output->writeln($unstableFooterMessage);
                }
                $this->_exit();
            } catch (\Exception $e) {
                @unlink($tempFilename);
                if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
                    throw $e;
                }
                $output->writeln('<error>The download is corrupted (' . $e->getMessage() . ').</error>');
                $output->writeln('<error>Please re-run the self-update command to try again.</error>');
            }
        } else {
            $output->writeln("<info>You are using the latest imi-conrun version.</info>");
        }
    }
Exemplo n.º 19
0
 private function updateGitHubInfo(RemoteFilesystem $rfs, Package $package, $owner, $repo)
 {
     $baseApiUrl = 'https://api.github.com/repos/' . $owner . '/' . $repo;
     try {
         $repoData = JsonFile::parseJson($rfs->getContents('github.com', $baseApiUrl, false), $baseApiUrl);
     } catch (\Exception $e) {
         return;
     }
     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)) {
         $config = \HTMLPurifier_Config::createDefault();
         $config->set('HTML.Allowed', 'a[href|target|rel|id],strong,b,em,i,strike,pre,code,p,ol,ul,li,br,h1,h2,h3,img[src|title|alt|width|height|style]');
         $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
         $links = $dom->getElementsByTagName('a');
         foreach ($links as $link) {
             $link->setAttribute('rel', 'nofollow');
             if ('#' === substr($link->getAttribute('href'), 0, 1)) {
                 $link->setAttribute('href', '#user-content-' . substr($link->getAttribute('href'), 1));
             } elseif (false === strpos($link->getAttribute('href'), '//')) {
                 $link->setAttribute('href', 'https://github.com/' . $owner . '/' . $repo . '/blob/HEAD/' . $link->getAttribute('href'));
             }
         }
         // 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 (!empty($repoData['stargazers_count'])) {
         $package->setGitHubStars($repoData['stargazers_count']);
     }
     if (!empty($repoData['subscribers_count'])) {
         $package->setGitHubWatches($repoData['subscribers_count']);
     }
     if (!empty($repoData['network_count'])) {
         $package->setGitHubForks($repoData['network_count']);
     }
     if (!empty($repoData['open_issues_count'])) {
         $package->setGitHubOpenIssues($repoData['open_issues_count']);
     }
 }
Exemplo n.º 20
0
 /**
  * Decorate the package with stats from packagist.
  *
  * @param VersionedPackage $package The package version.
  *
  * @return VersionedPackage
  */
 protected function decorateWithPackagistStats(VersionedPackage $package)
 {
     if (null === $this->decorateBaseUrl) {
         return $package;
     }
     $rfs = new RemoteFilesystem(new BufferIO());
     $requestUrl = sprintf($this->decorateBaseUrl, $package->getName());
     if (!($jsonData = $rfs->getContents($requestUrl, $requestUrl))) {
         $this->decorateBaseUrl = null;
         return $package;
     }
     try {
         $data = new JsonArray($jsonData);
     } catch (\RuntimeException $exception) {
         $this->decorateBaseUrl = null;
         return $package;
     }
     $metaPaths = ['downloads' => 'package/downloads/total', 'favers' => 'package/favers'];
     foreach ($metaPaths as $metaKey => $metaPath) {
         $package->addMetaData($metaKey, $data->get($metaPath));
     }
     return $package;
 }
Exemplo n.º 21
0
 /**
  * Get the remote content.
  *
  * @param string $url The URL of content
  *
  * @return mixed The result
  */
 protected function getContents($url)
 {
     $rfs = new RemoteFilesystem($this->io);
     return $rfs->getContents($this->url, $url, false);
 }