Пример #1
0
 public function __construct(SVNRepositoryConfig $repoConfig, IOInterface $io, Config $config)
 {
     // @TODO: add event dispatcher?
     $this->repoConfig = $repoConfig;
     $this->plugin = $repoConfig->getPlugin();
     // check url immediately - can't do anything without it
     $urls = [];
     foreach ((array) $repoConfig->get('url') as $url) {
         if (($urlParts = parse_url($url)) === false || empty($urlParts['scheme'])) {
             continue;
         }
         // untrailingslashit
         $urls[] = rtrim($url, '/');
     }
     if (!count($urls)) {
         throw new \UnexpectedValueException('No valid URLs for SVN repository: ' . print_r($repoConfig->get('url'), true));
     }
     $repoConfig->set('url', $urls);
     // use the cache TTL from the config?
     if ($repoConfig->get('cache-ttl') === 'config') {
         $repoConfig->set('cache-ttl', $config->get('cache-files-ttl'));
     }
     $this->io = $io;
     $this->cache = new Cache($io, $config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', reset($urls)));
     $this->loader = new ArrayLoader();
     // clear out stale cache
     $this->cache->gc($repoConfig->get('cache-ttl'), $config->get('cache-files-maxsize'));
     $this->vendors = $repoConfig->get('vendors');
     $this->defaultVendor = key($this->vendors);
     // create an SvnUtil to execute commands
     $this->svnUtil = new SvnUtil($io, $repoConfig->get('trust-cert'));
 }
Пример #2
0
 /**
  * @param string $origin domain text
  * @param string $url
  * @param IO\IOInterface $io
  * @param CConfig $config
  * @param array $pluginConfig
  * @return Aspects\HttpGetRequest
  */
 public static function getHttpGetRequest($origin, $url, IO\IOInterface $io, CConfig $config, array $pluginConfig)
 {
     if (substr($origin, -10) === 'github.com') {
         $origin = 'github.com';
         $requestClass = 'GitHub';
     } elseif (in_array($origin, $config->get('github-domains') ?: array())) {
         $requestClass = 'GitHub';
     } elseif (in_array($origin, $config->get('gitlab-domains') ?: array())) {
         $requestClass = 'GitLab';
     } else {
         $requestClass = 'HttpGet';
     }
     $requestClass = __NAMESPACE__ . '\\Aspects\\' . $requestClass . 'Request';
     $request = new $requestClass($origin, $url, $io);
     $request->verbose = $pluginConfig['verbose'];
     if ($pluginConfig['insecure']) {
         $request->curlOpts[CURLOPT_SSL_VERIFYPEER] = false;
     }
     if (!empty($pluginConfig['capath'])) {
         $request->curlOpts[CURLOPT_CAPATH] = $pluginConfig['capath'];
     }
     if (!empty($pluginConfig['userAgent'])) {
         $request->curlOpts[CURLOPT_USERAGENT] = $pluginConfig['userAgent'];
     }
     return $request;
 }
Пример #3
0
 /**
  * @param string $url
  * @param string $destination
  * @param bool $useRedirector
  * @param IO\IOInterface $io
  * @param Config $config
  */
 public function __construct($url, $destination, $useRedirector, IO\IOInterface $io, Config $config)
 {
     $this->setURL($url);
     $this->setDestination($destination);
     $this->setCA($config->get('capath'), $config->get('cafile'));
     $this->setupAuthentication($io, $useRedirector, $config->get('github-domains') ?: array(), $config->get('gitlab-domains') ?: array());
 }
Пример #4
0
 /**
  * {@inheritDoc}
  */
 public function loadConfiguration(Config $config)
 {
     $bitbucketOauth = $config->get('bitbucket-oauth') ?: array();
     $githubOauth = $config->get('github-oauth') ?: array();
     $gitlabOauth = $config->get('gitlab-oauth') ?: array();
     $gitlabToken = $config->get('gitlab-token') ?: array();
     $httpBasic = $config->get('http-basic') ?: array();
     // reload oauth tokens from config if available
     foreach ($bitbucketOauth as $domain => $cred) {
         $this->checkAndSetAuthentication($domain, $cred['consumer-key'], $cred['consumer-secret']);
     }
     foreach ($githubOauth as $domain => $token) {
         if (!preg_match('{^[a-z0-9]+$}', $token)) {
             throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"');
         }
         $this->checkAndSetAuthentication($domain, $token, 'x-oauth-basic');
     }
     foreach ($gitlabOauth as $domain => $token) {
         $this->checkAndSetAuthentication($domain, $token, 'oauth2');
     }
     foreach ($gitlabToken as $domain => $token) {
         $this->checkAndSetAuthentication($domain, $token, 'private-token');
     }
     // reload http basic credentials from config if available
     foreach ($httpBasic as $domain => $cred) {
         $this->checkAndSetAuthentication($domain, $cred['username'], $cred['password']);
     }
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
 }
Пример #5
0
 /**
  * {@inheritDoc}
  */
 public function loadConfiguration(Config $config)
 {
     // reload oauth token from config if available
     if ($tokens = $config->get('github-oauth')) {
         foreach ($tokens as $domain => $token) {
             if (!preg_match('{^[a-z0-9]+$}', $token)) {
                 throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"');
             }
             $this->setAuthentication($domain, $token, 'x-oauth-basic');
         }
     }
     if ($tokens = $config->get('gitlab-oauth')) {
         foreach ($tokens as $domain => $token) {
             $this->setAuthentication($domain, $token, 'oauth2');
         }
     }
     // reload http basic credentials from config if available
     if ($creds = $config->get('http-basic')) {
         foreach ($creds as $domain => $cred) {
             $this->setAuthentication($domain, $cred['username'], $cred['password']);
         }
     }
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
 }
Пример #6
0
 public function getClassmap() : \Traversable
 {
     $filesystem = new Filesystem();
     $vendorPath = $filesystem->normalizePath(realpath($this->config->get('vendor-dir')));
     $classmapPath = $vendorPath . '/composer/autoload_classmap.php';
     if (!is_file($classmapPath)) {
         throw new \RuntimeException('Th dumped classmap does not exists. Try to run `composer dump-autoload --optimize` first.');
     }
     yield from (include $vendorPath . '/composer/autoload_classmap.php');
 }
Пример #7
0
 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, RemoteFilesystem $rfs = null, Filesystem $filesystem = null)
 {
     $this->io = $io;
     $this->config = $config;
     $this->eventDispatcher = $eventDispatcher;
     $this->rfs = $rfs ?: new RemoteFilesystem($io);
     $this->filesystem = $filesystem ?: new Filesystem();
     $this->cache = $cache;
     if ($this->cache && $this->cache->gcIsNecessary()) {
         $this->cache->gc($config->get('cache-files-ttl'), $config->get('cache-files-maxsize'));
     }
 }
Пример #8
0
 /**
  * Constructor.
  *
  * @param IOInterface      $io         The IO instance
  * @param Config           $config     The config
  * @param Cache            $cache      Optional cache instance
  * @param RemoteFilesystem $rfs        The remote filesystem
  * @param Filesystem       $filesystem The filesystem
  */
 public function __construct(IOInterface $io, Config $config, Cache $cache = null, RemoteFilesystem $rfs = null, Filesystem $filesystem = null)
 {
     $this->io = $io;
     $this->config = $config;
     $this->rfs = $rfs ?: new RemoteFilesystem($io);
     $this->filesystem = $filesystem ?: new Filesystem();
     $this->cache = $cache;
     if ($this->cache && !self::$cacheCollected && !mt_rand(0, 50)) {
         $this->cache->gc($config->get('cache-ttl'), $config->get('cache-files-maxsize'));
     }
     self::$cacheCollected = true;
 }
Пример #9
0
 /**
  * {@inheritdoc}
  */
 public function init()
 {
     // Retrieve the configuration variables.
     $this->config = $this->composer->getConfig();
     if (isset($this->config)) {
         if ($this->config->has('component-dir')) {
             $this->componentDir = $this->config->get('component-dir');
         }
     }
     // Get the available packages.
     $allPackages = array();
     /** @var \Composer\Package\Locker $locker */
     $locker = $this->composer->getLocker();
     if ($locker !== null && $locker->isLocked()) {
         $lockData = $locker->getLockData();
         $allPackages = $lockData['packages'];
         // Also merge in any of the development packages.
         $dev = isset($lockData['packages-dev']) ? $lockData['packages-dev'] : array();
         foreach ($dev as $package) {
             $allPackages[] = $package;
         }
     }
     // Only add those packages that we can reasonably
     // assume are components into our packages list
     /** @var \Composer\Package\RootPackageInterface $rootPackage */
     $rootPackage = $this->composer->getPackage();
     $rootExtras = $rootPackage ? $rootPackage->getExtra() : array();
     $customComponents = isset($rootExtras['component']) ? $rootExtras['component'] : array();
     foreach ($allPackages as $package) {
         $name = $package['name'];
         if (isset($customComponents[$name]) && is_array($customComponents[$name])) {
             $package['extra'] = array('component' => $customComponents[$name]);
             $this->packages[] = $package;
         } else {
             $extra = isset($package['extra']) ? $package['extra'] : array();
             if (isset($extra['component']) && is_array($extra['component'])) {
                 $this->packages[] = $package;
             }
         }
     }
     // Add the root package to the packages list.
     $root = $this->composer->getPackage();
     if ($root) {
         $dumper = new ArrayDumper();
         $package = $dumper->dump($root);
         $package['is-root'] = true;
         $this->packages[] = $package;
     }
     return true;
 }
Пример #10
0
 public function loadConfiguration(Config $config)
 {
     if ($tokens = $config->get('github-oauth')) {
         foreach ($tokens as $domain => $token) {
             if (!preg_match('{^[a-z0-9]+$}', $token)) {
                 throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"');
             }
             $this->setAuthentication($domain, $token, 'x-oauth-basic');
         }
     }
     if ($creds = $config->get('http-basic')) {
         foreach ($creds as $domain => $cred) {
             $this->setAuthentication($domain, $cred['username'], $cred['password']);
         }
     }
 }
 /**
  * @dataProvider getAssetTypes
  *
  * @param string $type
  * @param string $filename
  */
 public function testRedirectUrlRepositoryWithCache($type, $filename)
 {
     $originUrl = 'github.com';
     $owner = 'composer-test';
     $repository = 'repo-name';
     $repoUrl = 'http://' . $originUrl . '/' . $owner . '/' . $repository;
     $repoApiUrl = 'https://api.github.com/repos/composer-test/repo-name';
     $repoApiUrlNew = $repoApiUrl . '-new';
     $packageName = $type . '-asset/repo-name';
     $identifier = 'v0.0.0';
     $sha = 'SOMESHA';
     $io = $this->getMockBuilder('Composer\\IO\\IOInterface')->getMock();
     $io->expects($this->any())->method('isInteractive')->will($this->returnValue(true));
     $remoteFilesystem = $this->getMockBuilder('Composer\\Util\\RemoteFilesystem')->setConstructorArgs(array($io))->getMock();
     $remoteFilesystem->expects($this->at(0))->method('getContents')->with($this->equalTo('github.com'), $this->equalTo($repoApiUrlNew), $this->equalTo(false))->will($this->returnValue($this->createJsonComposer(array('master_branch' => 'test_master'))));
     $repoConfig = array('url' => $repoUrl, 'asset-type' => $type, 'filename' => $filename, 'package-name' => $packageName);
     $repoUrl = 'https://github.com/composer-test/repo-name.git';
     /* @var IOInterface $io */
     /* @var RemoteFilesystem $remoteFilesystem */
     $cache = new Cache($io, $this->config->get('cache-repo-dir') . '/' . $originUrl . '/' . $owner . '/' . $repository);
     $cache->write('redirect-api', $repoApiUrlNew);
     $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
     $gitHubDriver->initialize();
     $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
     $this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());
     $dist = $gitHubDriver->getDist($sha);
     $this->assertEquals('zip', $dist['type']);
     $this->assertEquals('https://api.github.com/repos/composer-test/repo-name/zipball/SOMESHA', $dist['url']);
     $this->assertEquals($sha, $dist['reference']);
     $source = $gitHubDriver->getSource($sha);
     $this->assertEquals('git', $source['type']);
     $this->assertEquals($repoUrl, $source['url']);
     $this->assertEquals($sha, $source['reference']);
 }
Пример #12
0
 public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null)
 {
     if (!preg_match('{^[\\w.]+\\??://}', $repoConfig['url'])) {
         // assume http as the default protocol
         $repoConfig['url'] = 'http://' . $repoConfig['url'];
     }
     $repoConfig['url'] = rtrim($repoConfig['url'], '/');
     if ('https?' === substr($repoConfig['url'], 0, 6)) {
         $repoConfig['url'] = (extension_loaded('openssl') ? 'https' : 'http') . substr($repoConfig['url'], 6);
     }
     $urlBits = parse_url($repoConfig['url']);
     if ($urlBits === false || empty($urlBits['scheme'])) {
         throw new \UnexpectedValueException('Invalid url given for Composer repository: ' . $repoConfig['url']);
     }
     if (!isset($repoConfig['options'])) {
         $repoConfig['options'] = array();
     }
     if (isset($repoConfig['allow_ssl_downgrade']) && true === $repoConfig['allow_ssl_downgrade']) {
         $this->allowSslDowngrade = true;
     }
     $this->config = $config;
     $this->options = $repoConfig['options'];
     $this->url = $repoConfig['url'];
     $this->baseUrl = rtrim(preg_replace('{^(.*)(?:/packages.json)?(?:[?#].*)?$}', '$1', $this->url), '/');
     $this->io = $io;
     $this->cache = new Cache($io, $config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url), 'a-z0-9.$');
     $this->loader = new ArrayLoader();
     $this->rfs = new RemoteFilesystem($this->io, $this->config, $this->options);
     $this->eventDispatcher = $eventDispatcher;
 }
Пример #13
0
 /**
  * @return string[]
  */
 public function scan()
 {
     $parameters = ['command' => 'dump-autoload', '--no-interaction' => true, '--working-dir' => $this->directory, '--optimize' => true, '--no-dev' => true];
     $this->createComposerApplication()->run(new ArrayInput($parameters), $this->output);
     $config = new Config(true, $this->directory);
     return require $config->get('vendor-dir') . '/composer/autoload_classmap.php';
 }
Пример #14
0
 public function testOverrideGithubProtocols()
 {
     $config = new Config(false);
     $config->merge(array('config' => array('github-protocols' => array('https', 'git'))));
     $config->merge(array('config' => array('github-protocols' => array('https'))));
     $this->assertEquals(array('https'), $config->get('github-protocols'));
 }
Пример #15
0
 /**
  * Search for a given package version.
  *
  * Usage examples : Composition::has('php', '5.3.*') // PHP version
  *                  Composition::has('ext-memcache') // PHP extension
  *                  Composition::has('vendor/package', '>2.1') // Package version
  *
  * @param type $packageName  The package name
  * @param type $prettyString An optional version constraint
  *
  * @return boolean           Wether or not the package has been found.
  */
 public static function has($packageName, $prettyString = '*')
 {
     if (null === self::$pool) {
         if (null === self::$rootDir) {
             self::$rootDir = getcwd();
             if (!file_exists(self::$rootDir . '/composer.json')) {
                 throw new \RuntimeException('Unable to guess the project root dir, please specify it manually using the Composition::setRootDir method.');
             }
         }
         $minimumStability = 'dev';
         $config = new Config();
         $file = new JsonFile(self::$rootDir . '/composer.json');
         if ($file->exists()) {
             $projectConfig = $file->read();
             $config->merge($projectConfig);
             if (isset($projectConfig['minimum-stability'])) {
                 $minimumStability = $projectConfig['minimum-stability'];
             }
         }
         $vendorDir = self::$rootDir . '/' . $config->get('vendor-dir');
         $pool = new Pool($minimumStability);
         $pool->addRepository(new PlatformRepository());
         $pool->addRepository(new InstalledFilesystemRepository(new JsonFile($vendorDir . '/composer/installed.json')));
         $pool->addRepository(new InstalledFilesystemRepository(new JsonFile($vendorDir . '/composer/installed_dev.json')));
         self::$pool = $pool;
     }
     $parser = new VersionParser();
     $constraint = $parser->parseConstraints($prettyString);
     $packages = self::$pool->whatProvides($packageName, $constraint);
     return empty($packages) ? false : true;
 }
Пример #16
0
 private function initialize()
 {
     if (!file_exists($this->autoloadFile)) {
         $filesystem = new Filesystem();
         // Avoid problems if using the runner before autoload.php has been
         // generated
         $filesystem->dumpFile($this->autoloadFile, '');
     }
     $this->initialized = true;
     // Keep the manually set runner
     if (null === $this->puliRunner) {
         try {
             // Add Composer's bin directory in case the "puli" executable is
             // installed with Composer
             $this->puliRunner = new PuliRunner($this->config->get('bin-dir'));
         } catch (RuntimeException $e) {
             $this->printWarning('Plugin initialization failed', $e);
             $this->runPreAutoloadDump = false;
             $this->runPostAutoloadDump = false;
             $this->runPostInstall = false;
         }
     }
     // Use the runner to verify if Puli has the right version
     try {
         $this->verifyPuliVersion();
     } catch (RuntimeException $e) {
         $this->printWarning('Version check failed', $e);
         $this->runPreAutoloadDump = false;
         $this->runPostAutoloadDump = false;
         $this->runPostInstall = false;
     }
 }
Пример #17
0
 /**
  * {@inheritDoc}
  */
 protected function initialize(InputInterface $input, OutputInterface $output)
 {
     if ($input->getOption('global') && 'composer.json' !== $input->getOption('file')) {
         throw new \RuntimeException('--file and --global can not be combined');
     }
     $this->config = Factory::createConfig($this->getIO());
     // Get the local composer.json, global config.json, or if the user
     // passed in a file to use
     $configFile = $input->getOption('global') ? $this->config->get('home') . '/config.json' : $input->getOption('file');
     $this->configFile = new JsonFile($configFile);
     $this->configSource = new JsonConfigSource($this->configFile);
     $authConfigFile = $input->getOption('global') ? $this->config->get('home') . '/auth.json' : dirname(realpath($input->getOption('file'))) . '/auth.json';
     $this->authConfigFile = new JsonFile($authConfigFile);
     $this->authConfigSource = new JsonConfigSource($this->authConfigFile, true);
     // initialize the global file if it's not there
     if ($input->getOption('global') && !$this->configFile->exists()) {
         touch($this->configFile->getPath());
         $this->configFile->write(array('config' => new \ArrayObject()));
         @chmod($this->configFile->getPath(), 0600);
     }
     if ($input->getOption('global') && !$this->authConfigFile->exists()) {
         touch($this->authConfigFile->getPath());
         $this->authConfigFile->write(array('http-basic' => new \ArrayObject(), 'github-oauth' => new \ArrayObject()));
         @chmod($this->authConfigFile->getPath(), 0600);
     }
     if (!$this->configFile->exists()) {
         throw new \RuntimeException('No composer.json found in the current directory');
     }
 }
Пример #18
0
 /**
  * Clean a package, based on its rules.
  *
  * @param BasePackage $package The package to clean
  * @return bool True if cleaned
  *
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 protected function cleanPackage(BasePackage $package)
 {
     $vendorDir = $this->config->get('vendor-dir');
     $targetDir = $package->getTargetDir();
     $packageName = $package->getPrettyName();
     $packageDir = $targetDir ? $packageName . '/' . $targetDir : $packageName;
     $rules = isset($this->rules[$packageName]) ? $this->rules[$packageName] : null;
     if (!$rules) {
         $this->io->writeError('Rules not found: ' . $packageName);
         return false;
     }
     $dir = $this->filesystem->normalizePath(realpath($vendorDir . '/' . $packageDir));
     if (!is_dir($dir)) {
         $this->io->writeError('Vendor dir not found: ' . $vendorDir . '/' . $packageDir);
         return false;
     }
     //$this->io->write('Rules: ' . print_r($rules, true));
     foreach ((array) $rules as $part) {
         // Split patterns for single globs (should be max 260 chars)
         $patterns = (array) $part;
         foreach ($patterns as $pattern) {
             try {
                 foreach (glob($dir . '/' . $pattern) as $file) {
                     $this->filesystem->remove($file);
                     //$this->io->write('File removed: ' . $file);
                 }
             } catch (\Exception $e) {
                 $this->io->write("Could not parse {$packageDir} ({$pattern}): " . $e->getMessage());
             }
         }
     }
     return true;
 }
Пример #19
0
 /**
  * @param IO\IOInterface $io
  * @param Config $config
  * @param Operation\OperationInterface[] $ops
  */
 public function fetchAllFromOperations(IO\IOInterface $io, Config $config, array $ops)
 {
     $cachedir = rtrim($config->get('cache-files-dir'), '\\/');
     $requests = array();
     foreach ($ops as $op) {
         switch ($op->getJobType()) {
             case 'install':
                 $p = $op->getPackage();
                 break;
             case 'update':
                 $p = $op->getTargetPackage();
                 break;
             default:
                 continue 2;
         }
         $url = $this->getUrlFromPackage($p);
         if (!$url) {
             continue;
         }
         $destination = $cachedir . DIRECTORY_SEPARATOR . FileDownloaderDummy::getCacheKeyCompat($p, $url);
         if (file_exists($destination)) {
             continue;
         }
         $useRedirector = (bool) preg_match('%^(?:https|git)://github\\.com%', $p->getSourceUrl());
         try {
             $request = new CopyRequest($url, $destination, $useRedirector, $io, $config);
             $requests[] = $request;
         } catch (FetchException $e) {
             // do nothing
         }
     }
     if (count($requests) > 0) {
         $this->fetchAll($io, $requests);
     }
 }
 /**
  * Clean a package, based on its rules.
  *
  * @param BasePackage  $package  The package to clean
  * @return bool True if cleaned
  */
 protected function cleanPackage(BasePackage $package)
 {
     // Only clean 'dist' packages
     if ($package->getInstallationSource() !== 'dist') {
         return false;
     }
     $vendorDir = $this->config->get('vendor-dir');
     $targetDir = $package->getTargetDir();
     $packageName = $package->getPrettyName();
     $packageDir = $targetDir ? $packageName . '/' . $targetDir : $packageName;
     $rules = isset($this->rules[$packageName]) ? $this->rules[$packageName] : null;
     if (!$rules) {
         return;
     }
     $dir = $this->filesystem->normalizePath(realpath($vendorDir . '/' . $packageDir));
     if (!is_dir($dir)) {
         return false;
     }
     foreach ((array) $rules as $part) {
         // Split patterns for single globs (should be max 260 chars)
         $patterns = explode(' ', trim($part));
         foreach ($patterns as $pattern) {
             try {
                 foreach (glob($dir . '/' . $pattern) as $file) {
                     $this->filesystem->remove($file);
                 }
             } catch (\Exception $e) {
                 $this->io->write("Could not parse {$packageDir} ({$pattern}): " . $e->getMessage());
             }
         }
     }
     return true;
 }
 public function testCreateWithCustomIgnoreSection()
 {
     $extra = array('custom-ignore-files' => array('foo-asset/foo' => array('PATTERN'), 'foo-asset/bar' => array()));
     $this->rootPackage->expects($this->any())->method('getExtra')->will($this->returnValue($extra));
     $manager = IgnoreFactory::create($this->composer, $this->package, null, 'custom-ignore-files');
     $this->assertTrue($manager->isEnabled());
     $this->assertTrue($manager->hasPattern());
     $this->validateInstallDir($manager, $this->config->get('vendor-dir') . '/' . $this->package->getName());
 }
Пример #22
0
 /**
  * {@inheritDoc}
  */
 public function loadConfiguration(Config $config)
 {
     $githubOauth = $config->get('github-oauth');
     $gitlabOauth = $config->get('gitlab-oauth');
     $httpBasic = $config->get('http-basic');
     // Use COMPOSER_AUTH environment variable if set
     if ($composerAuthEnv = getenv('COMPOSER_AUTH')) {
         $authData = json_decode($composerAuthEnv, true);
         if (is_null($authData)) {
             throw new \UnexpectedValueException('COMPOSER_AUTH environment variable is malformed');
         }
         if (isset($authData['github-oauth'])) {
             $githubOauth = array_merge($githubOauth, $authData['github-oauth']);
         }
         if (isset($authData['gitlab-oauth'])) {
             $gitlabOauth = array_merge($gitlabOauth, $authData['gitlab-oauth']);
         }
         if (isset($authData['http-basic'])) {
             $httpBasic = array_merge($httpBasic, $authData['http-basic']);
         }
     }
     // reload oauth token from config if available
     if ($githubOauth) {
         foreach ($githubOauth as $domain => $token) {
             if (!preg_match('{^[a-z0-9]+$}', $token)) {
                 throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"');
             }
             $this->setAuthentication($domain, $token, 'x-oauth-basic');
         }
     }
     if ($gitlabOauth) {
         foreach ($gitlabOauth as $domain => $token) {
             $this->setAuthentication($domain, $token, 'oauth2');
         }
     }
     // reload http basic credentials from config if available
     if ($httpBasic) {
         foreach ($httpBasic as $domain => $cred) {
             $this->setAuthentication($domain, $cred['username'], $cred['password']);
         }
     }
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
 }
Пример #23
0
 /**
  * {@inheritDoc}
  */
 public function loadConfiguration(Config $config)
 {
     // reload oauth token from config if available
     if ($tokens = $config->get('github-oauth')) {
         foreach ($tokens as $domain => $token) {
             if (!preg_match('{^[a-z0-9]+$}', $token)) {
                 throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"');
             }
             $this->setAuthentication($domain, $token, 'x-oauth-basic');
         }
     }
 }
Пример #24
0
 /**
  * Create the auth params from the configuration file.
  *
  * @return bool
  */
 private function createAuthFromConfig()
 {
     if (!$this->config->has('http-basic')) {
         return $this->hasAuth = false;
     }
     $authConfig = $this->config->get('http-basic');
     $host = parse_url($this->url, PHP_URL_HOST);
     if (isset($authConfig[$host])) {
         $this->credentials['username'] = $authConfig[$host]['username'];
         $this->credentials['password'] = $authConfig[$host]['password'];
         return $this->hasAuth = true;
     }
     return $this->hasAuth = false;
 }
Пример #25
0
 public function __construct(array $repoConfig, IOInterface $io, Config $config)
 {
     if (!preg_match('{^\\w+://}', $repoConfig['url'])) {
         // assume http as the default protocol
         $repoConfig['url'] = 'http://' . $repoConfig['url'];
     }
     $repoConfig['url'] = rtrim($repoConfig['url'], '/');
     if (function_exists('filter_var') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
         throw new \UnexpectedValueException('Invalid url given for Composer repository: ' . $repoConfig['url']);
     }
     $this->config = $config;
     $this->url = $repoConfig['url'];
     $this->io = $io;
     $this->cache = new Cache($io, $config->get('home') . '/cache/' . preg_replace('{[^a-z0-9.]}', '-', $this->url));
 }
 private function initialize()
 {
     $this->initialized = true;
     // Keep the manually set runner
     if (null === $this->puliRunner) {
         try {
             // Add Composer's bin directory in case the "puli" executable is
             // installed with Composer
             $this->puliRunner = new PuliRunner($this->config->get('bin-dir'));
         } catch (RuntimeException $e) {
             $this->printWarning('Plugin initialization failed', $e);
             $this->runPostAutoloadDump = false;
             $this->runPostInstall = false;
         }
     }
     // Use the runner to verify if Puli has the right version
     try {
         $this->verifyPuliVersion();
     } catch (RuntimeException $e) {
         $this->printWarning('Version check failed', $e);
         $this->runPostAutoloadDump = false;
         $this->runPostInstall = false;
     }
 }
Пример #27
0
 /**
  * {@inheritDoc}
  */
 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 {
     if (!preg_match('#^((?:https?|git)://([^/]+)/|git@([^:]+):)([^/]+)/(.+?)(?:\\.git|/)?$#', $url, $matches)) {
         return false;
     }
     $originUrl = !empty($matches[2]) ? $matches[2] : $matches[3];
     if (!in_array(preg_replace('{^www\\.}i', '', $originUrl), $config->get('github-domains'))) {
         return false;
     }
     if (!extension_loaded('openssl')) {
         $io->writeError('Skipping GitHub driver for ' . $url . ' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
         return false;
     }
     return true;
 }
Пример #28
0
 /**
  * {@inheritDoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // Open file in editor
     if ($input->getOption('editor')) {
         $editor = escapeshellcmd(getenv('EDITOR'));
         if (!$editor) {
             if (Platform::isWindows()) {
                 $editor = 'notepad';
             } else {
                 foreach (array('editor', 'vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
                     if (exec('which ' . $candidate)) {
                         $editor = $candidate;
                         break;
                     }
                 }
             }
         }
         $file = $input->getOption('auth') ? $this->authConfigFile->getPath() : $this->configFile->getPath();
         system($editor . ' ' . $file . (Platform::isWindows() ? '' : ' > `tty`'));
         return 0;
     }
     if (!$input->getOption('global')) {
         $this->config->merge($this->configFile->read());
         $this->config->merge(array('config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : array()));
     }
     // List the configuration of the file settings
     if ($input->getOption('list')) {
         $this->listConfiguration($this->config->all(), $this->config->raw(), $output);
         return 0;
     }
     $settingKey = $input->getArgument('setting-key');
     if (!$settingKey) {
         return 0;
     }
     // If the user enters in a config variable, parse it and save to file
     if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
         throw new \RuntimeException('You can not combine a setting value with --unset');
     }
     // show the value if no value is provided
     if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
         $data = $this->config->all();
         if (preg_match('/^repos?(?:itories)?(?:\\.(.+))?/', $settingKey, $matches)) {
             if (empty($matches[1])) {
                 $value = isset($data['repositories']) ? $data['repositories'] : array();
             } else {
                 if (!isset($data['repositories'][$matches[1]])) {
                     throw new \InvalidArgumentException('There is no ' . $matches[1] . ' repository defined');
                 }
                 $value = $data['repositories'][$matches[1]];
             }
         } elseif (strpos($settingKey, '.')) {
             $bits = explode('.', $settingKey);
             $data = $data['config'];
             $match = false;
             foreach ($bits as $bit) {
                 $key = isset($key) ? $key . '.' . $bit : $bit;
                 $match = false;
                 if (isset($data[$key])) {
                     $match = true;
                     $data = $data[$key];
                     unset($key);
                 }
             }
             if (!$match) {
                 throw new \RuntimeException($settingKey . ' is not defined.');
             }
             $value = $data;
         } elseif (isset($data['config'][$settingKey])) {
             $value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
         } else {
             throw new \RuntimeException($settingKey . ' is not defined');
         }
         if (is_array($value)) {
             $value = json_encode($value);
         }
         $this->getIO()->write($value);
         return 0;
     }
     $values = $input->getArgument('setting-value');
     // what the user is trying to add/change
     $booleanValidator = function ($val) {
         return in_array($val, array('true', 'false', '1', '0'), true);
     };
     $booleanNormalizer = function ($val) {
         return $val !== 'false' && (bool) $val;
     };
     // handle config values
     $uniqueConfigValues = array('process-timeout' => array('is_numeric', 'intval'), 'use-include-path' => array($booleanValidator, $booleanNormalizer), 'preferred-install' => array(function ($val) {
         return in_array($val, array('auto', 'source', 'dist'), true);
     }, function ($val) {
         return $val;
     }), 'store-auths' => array(function ($val) {
         return in_array($val, array('true', 'false', 'prompt'), true);
     }, function ($val) {
         if ('prompt' === $val) {
             return 'prompt';
         }
         return $val !== 'false' && (bool) $val;
     }), 'notify-on-install' => array($booleanValidator, $booleanNormalizer), 'vendor-dir' => array('is_string', function ($val) {
         return $val;
     }), 'bin-dir' => array('is_string', function ($val) {
         return $val;
     }), 'archive-dir' => array('is_string', function ($val) {
         return $val;
     }), 'archive-format' => array('is_string', function ($val) {
         return $val;
     }), 'data-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-files-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-repo-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-vcs-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-ttl' => array('is_numeric', 'intval'), 'cache-files-ttl' => array('is_numeric', 'intval'), 'cache-files-maxsize' => array(function ($val) {
         return preg_match('/^\\s*([0-9.]+)\\s*(?:([kmg])(?:i?b)?)?\\s*$/i', $val) > 0;
     }, function ($val) {
         return $val;
     }), 'bin-compat' => array(function ($val) {
         return in_array($val, array('auto', 'full'));
     }, function ($val) {
         return $val;
     }), 'discard-changes' => array(function ($val) {
         return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
     }, function ($val) {
         if ('stash' === $val) {
             return 'stash';
         }
         return $val !== 'false' && (bool) $val;
     }), 'autoloader-suffix' => array('is_string', function ($val) {
         return $val === 'null' ? null : $val;
     }), 'sort-packages' => array($booleanValidator, $booleanNormalizer), 'optimize-autoloader' => array($booleanValidator, $booleanNormalizer), 'classmap-authoritative' => array($booleanValidator, $booleanNormalizer), 'prepend-autoloader' => array($booleanValidator, $booleanNormalizer), 'disable-tls' => array($booleanValidator, $booleanNormalizer), 'secure-http' => array($booleanValidator, $booleanNormalizer), 'cafile' => array(function ($val) {
         return file_exists($val) && is_readable($val);
     }, function ($val) {
         return $val === 'null' ? null : $val;
     }), 'capath' => array(function ($val) {
         return is_dir($val) && is_readable($val);
     }, function ($val) {
         return $val === 'null' ? null : $val;
     }), 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer));
     $multiConfigValues = array('github-protocols' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         foreach ($vals as $val) {
             if (!in_array($val, array('git', 'https', 'ssh'))) {
                 return 'valid protocols include: git, https, ssh';
             }
         }
         return true;
     }, function ($vals) {
         return $vals;
     }), 'github-domains' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         return true;
     }, function ($vals) {
         return $vals;
     }), 'gitlab-domains' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         return true;
     }, function ($vals) {
         return $vals;
     }));
     foreach ($uniqueConfigValues as $name => $callbacks) {
         if ($settingKey === $name) {
             if ($input->getOption('unset')) {
                 return $this->configSource->removeConfigSetting($settingKey);
             }
             list($validator, $normalizer) = $callbacks;
             if (1 !== count($values)) {
                 throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
             }
             if (true !== ($validation = $validator($values[0]))) {
                 throw new \RuntimeException(sprintf('"%s" is an invalid value' . ($validation ? ' (' . $validation . ')' : ''), $values[0]));
             }
             return $this->configSource->addConfigSetting($settingKey, $normalizer($values[0]));
         }
     }
     foreach ($multiConfigValues as $name => $callbacks) {
         if ($settingKey === $name) {
             if ($input->getOption('unset')) {
                 return $this->configSource->removeConfigSetting($settingKey);
             }
             list($validator, $normalizer) = $callbacks;
             if (true !== ($validation = $validator($values))) {
                 throw new \RuntimeException(sprintf('%s is an invalid value' . ($validation ? ' (' . $validation . ')' : ''), json_encode($values)));
             }
             return $this->configSource->addConfigSetting($settingKey, $normalizer($values));
         }
     }
     // handle repositories
     if (preg_match('/^repos?(?:itories)?\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeRepository($matches[1]);
         }
         if (2 === count($values)) {
             return $this->configSource->addRepository($matches[1], array('type' => $values[0], 'url' => $values[1]));
         }
         if (1 === count($values)) {
             $value = strtolower($values[0]);
             if (true === $booleanValidator($value)) {
                 if (false === $booleanNormalizer($value)) {
                     return $this->configSource->addRepository($matches[1], false);
                 }
             } else {
                 $value = JsonFile::parseJson($values[0]);
                 return $this->configSource->addRepository($matches[1], $value);
             }
         }
         throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs https://bar.com');
     }
     // handle platform
     if (preg_match('/^platform\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeConfigSetting($settingKey);
         }
         return $this->configSource->addConfigSetting($settingKey, $values[0]);
     }
     // handle github-oauth
     if (preg_match('/^(github-oauth|gitlab-oauth|http-basic)\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             $this->authConfigSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             return;
         }
         if ($matches[1] === 'github-oauth' || $matches[1] === 'gitlab-oauth') {
             if (1 !== count($values)) {
                 throw new \RuntimeException('Too many arguments, expected only one token');
             }
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->authConfigSource->addConfigSetting($matches[1] . '.' . $matches[2], $values[0]);
         } elseif ($matches[1] === 'http-basic') {
             if (2 !== count($values)) {
                 throw new \RuntimeException('Expected two arguments (username, password), got ' . count($values));
             }
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->authConfigSource->addConfigSetting($matches[1] . '.' . $matches[2], array('username' => $values[0], 'password' => $values[1]));
         }
         return;
     }
     throw new \InvalidArgumentException('Setting ' . $settingKey . ' does not exist or is not supported by this command');
 }
Пример #29
0
 /**
  * @return Config
  */
 private function getConfiguration()
 {
     $config = new Config();
     // add dir to the config
     $config->merge(array('config' => array('home' => $this->getComposerHome())));
     // load global auth file
     $file = new JsonFile($config->get('home') . '/auth.json');
     if ($file->exists()) {
         $config->merge(array('config' => $file->read()));
     }
     $config->setAuthConfigSource(new JsonConfigSource($file, true));
     return $config;
 }
Пример #30
0
    public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '')
    {
        $this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode);
        $filesystem = new Filesystem();
        $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
        $basePath = $filesystem->normalizePath(realpath(getcwd()));
        $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
        $useGlobalIncludePath = (bool) $config->get('use-include-path');
        $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';
        $targetDir = $vendorPath . '/' . $targetDir;
        $filesystem->ensureDirectoryExists($targetDir);
        $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
        $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
        $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
        $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
        $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
        $namespacesFile = <<<EOF
<?php

// autoload_namespaces.php @generated by Composer

\$vendorDir = {$vendorPathCode52};
\$baseDir = {$appBaseDirCode};

return array(

EOF;
        $psr4File = <<<EOF
<?php

// autoload_psr4.php @generated by Composer

\$vendorDir = {$vendorPathCode52};
\$baseDir = {$appBaseDirCode};

return array(

EOF;
        // Collect information from all packages.
        $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
        $autoloads = $this->parseAutoloads($packageMap, $mainPackage);
        // Process the 'psr-0' base directories.
        foreach ($autoloads['psr-0'] as $namespace => $paths) {
            $exportedPaths = array();
            foreach ($paths as $path) {
                $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
            }
            $exportedPrefix = var_export($namespace, true);
            $namespacesFile .= "    {$exportedPrefix} => ";
            $namespacesFile .= "array(" . implode(', ', $exportedPaths) . "),\n";
        }
        $namespacesFile .= ");\n";
        // Process the 'psr-4' base directories.
        foreach ($autoloads['psr-4'] as $namespace => $paths) {
            $exportedPaths = array();
            foreach ($paths as $path) {
                $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
            }
            $exportedPrefix = var_export($namespace, true);
            $psr4File .= "    {$exportedPrefix} => ";
            $psr4File .= "array(" . implode(', ', $exportedPaths) . "),\n";
        }
        $psr4File .= ");\n";
        $classmapFile = <<<EOF
<?php

// autoload_classmap.php @generated by Composer

\$vendorDir = {$vendorPathCode52};
\$baseDir = {$appBaseDirCode};

return array(

EOF;
        // add custom psr-0 autoloading if the root package has a target dir
        $targetDirLoader = null;
        $mainAutoload = $mainPackage->getAutoload();
        if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
            $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir())));
            $prefixes = implode(', ', array_map(function ($prefix) {
                return var_export($prefix, true);
            }, array_keys($mainAutoload['psr-0'])));
            $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
            $targetDirLoader = <<<EOF

    public static function autoload(\$class)
    {
        \$dir = {$baseDirFromTargetDirCode} . '/';
        \$prefixes = array({$prefixes});
        foreach (\$prefixes as \$prefix) {
            if (0 !== strpos(\$class, \$prefix)) {
                continue;
            }
            \$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), {$levels})).'.php';
            if (!\$path = stream_resolve_include_path(\$path)) {
                return false;
            }
            require \$path;

            return true;
        }
    }

EOF;
        }
        // flatten array
        $classMap = array();
        if ($scanPsr0Packages) {
            // Scan the PSR-0/4 directories for class files, and add them to the class map
            foreach (array('psr-0', 'psr-4') as $psrType) {
                foreach ($autoloads[$psrType] as $namespace => $paths) {
                    foreach ($paths as $dir) {
                        $dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath . '/' . $dir);
                        if (!is_dir($dir)) {
                            continue;
                        }
                        $whitelist = sprintf('{%s/%s.+(?<!(?<!/)Test\\.php)$}', preg_quote($dir), $psrType === 'psr-0' && strpos($namespace, '_') === false ? preg_quote(strtr($namespace, '\\', '/')) : '');
                        $namespaceFilter = $namespace === '' ? null : $namespace;
                        foreach (ClassMapGenerator::createMap($dir, $whitelist, $this->io, $namespaceFilter) as $class => $path) {
                            if (!isset($classMap[$class])) {
                                $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
                                $classMap[$class] = $path . ",\n";
                            }
                        }
                    }
                }
            }
        }
        foreach ($autoloads['classmap'] as $dir) {
            foreach (ClassMapGenerator::createMap($dir, null, $this->io) as $class => $path) {
                $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
                $classMap[$class] = $path . ",\n";
            }
        }
        ksort($classMap);
        foreach ($classMap as $class => $code) {
            $classmapFile .= '    ' . var_export($class, true) . ' => ' . $code;
        }
        $classmapFile .= ");\n";
        if (!$suffix) {
            $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
        }
        file_put_contents($targetDir . '/autoload_namespaces.php', $namespacesFile);
        file_put_contents($targetDir . '/autoload_psr4.php', $psr4File);
        file_put_contents($targetDir . '/autoload_classmap.php', $classmapFile);
        if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
            file_put_contents($targetDir . '/include_paths.php', $includePathFile);
        }
        if ($includeFilesFile = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
            file_put_contents($targetDir . '/autoload_files.php', $includeFilesFile);
        }
        file_put_contents($vendorPath . '/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
        file_put_contents($targetDir . '/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
        // use stream_copy_to_stream instead of copy
        // to work around https://bugs.php.net/bug.php?id=64634
        $sourceLoader = fopen(__DIR__ . '/ClassLoader.php', 'r');
        $targetLoader = fopen($targetDir . '/ClassLoader.php', 'w+');
        stream_copy_to_stream($sourceLoader, $targetLoader);
        fclose($sourceLoader);
        fclose($targetLoader);
        unset($sourceLoader, $targetLoader);
        $this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode);
    }