Пример #1
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')) {
         $properties = array('name', 'type', 'description', 'homepage', 'version', 'minimum-stability', 'prefer-stable', 'keywords', 'license', 'extra');
         $rawData = $this->configFile->read();
         $data = $this->config->all();
         if (preg_match('/^repos?(?:itories)?(?:\\.(.+))?/', $settingKey, $matches)) {
             if (!isset($matches[1]) || $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);
             if ($bits[0] === 'extra') {
                 $data = $rawData;
             } else {
                 $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);
         } elseif (in_array($settingKey, $properties, true) && isset($rawData[$settingKey])) {
             $value = $rawData[$settingKey];
         } 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;
     }));
     if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
         return $this->configSource->removeConfigSetting($settingKey);
     }
     if (isset($uniqueConfigValues[$settingKey])) {
         return $this->handleSingleValue($settingKey, $uniqueConfigValues[$settingKey], $values, 'addConfigSetting');
     }
     if (isset($multiConfigValues[$settingKey])) {
         return $this->handleMultiValue($settingKey, $multiConfigValues[$settingKey], $values, 'addConfigSetting');
     }
     // handle properties
     $uniqueProps = array('name' => array('is_string', function ($val) {
         return $val;
     }), 'type' => array('is_string', function ($val) {
         return $val;
     }), 'description' => array('is_string', function ($val) {
         return $val;
     }), 'homepage' => array('is_string', function ($val) {
         return $val;
     }), 'version' => array('is_string', function ($val) {
         return $val;
     }), 'minimum-stability' => array(function ($val) {
         return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
     }, function ($val) {
         return VersionParser::normalizeStability($val);
     }), 'prefer-stable' => array($booleanValidator, $booleanNormalizer));
     $multiProps = array('keywords' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         return true;
     }, function ($vals) {
         return $vals;
     }), 'license' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         return true;
     }, function ($vals) {
         return $vals;
     }));
     if ($input->getOption('global') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]) || substr($settingKey, 0, 6) === 'extra.')) {
         throw new \InvalidArgumentException('The ' . $settingKey . ' property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json');
     }
     if ($input->getOption('unset') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]))) {
         return $this->configSource->removeProperty($settingKey);
     }
     if (isset($uniqueProps[$settingKey])) {
         return $this->handleSingleValue($settingKey, $uniqueProps[$settingKey], $values, 'addProperty');
     }
     if (isset($multiProps[$settingKey])) {
         return $this->handleMultiValue($settingKey, $multiProps[$settingKey], $values, 'addProperty');
     }
     // 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 extra
     if (preg_match('/^extra\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeProperty($settingKey);
         }
         return $this->configSource->addProperty($settingKey, $values[0]);
     }
     // 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 auth
     if (preg_match('/^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|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] === 'bitbucket-oauth') {
             if (2 !== count($values)) {
                 throw new \RuntimeException('Expected two arguments (consumer-key, consumer-secret), got ' . count($values));
             }
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->authConfigSource->addConfigSetting($matches[1] . '.' . $matches[2], array('consumer-key' => $values[0], 'consumer-secret' => $values[1]));
         } elseif (in_array($matches[1], array('github-oauth', 'gitlab-oauth', 'gitlab-token'), true)) {
             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');
 }
Пример #2
0
 private function extractStabilityFlags(array $requires, array $stabilityFlags, $minimumStability)
 {
     $stabilities = BasePackage::$stabilities;
     $minimumStability = $stabilities[$minimumStability];
     foreach ($requires as $reqName => $reqVersion) {
         $constraints = array();
         // extract all sub-constraints in case it is an OR/AND multi-constraint
         $orSplit = preg_split('{\\s*\\|\\|?\\s*}', trim($reqVersion));
         foreach ($orSplit as $constraint) {
             $andSplit = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraint);
             foreach ($andSplit as $constraint) {
                 $constraints[] = $constraint;
             }
         }
         // parse explicit stability flags to the most unstable
         $match = false;
         foreach ($constraints as $constraint) {
             if (preg_match('{^[^@]*?@(' . implode('|', array_keys($stabilities)) . ')$}i', $constraint, $match)) {
                 $name = strtolower($reqName);
                 $stability = $stabilities[VersionParser::normalizeStability($match[1])];
                 if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) {
                     continue;
                 }
                 $stabilityFlags[$name] = $stability;
                 $match = true;
             }
         }
         if ($match) {
             continue;
         }
         // infer flags for requirements that have an explicit -dev or -beta version specified but only
         // for those that are more unstable than the minimumStability or existing flags
         $reqVersion = preg_replace('{^([^,\\s@]+) as .+$}', '$1', $reqVersion);
         if (preg_match('{^[^,\\s@]+$}', $reqVersion) && 'stable' !== ($stabilityName = VersionParser::parseStability($reqVersion))) {
             $name = strtolower($reqName);
             $stability = $stabilities[$stabilityName];
             if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability || $minimumStability > $stability) {
                 continue;
             }
             $stabilityFlags[$name] = $stability;
         }
     }
     return $stabilityFlags;
 }
Пример #3
0
 private function extractStabilityFlags(array $requires, array $stabilityFlags, $minimumStability)
 {
     $stabilities = BasePackage::$stabilities;
     $minimumStability = $stabilities[$minimumStability];
     foreach ($requires as $reqName => $reqVersion) {
         // parse explicit stability flags to the most unstable
         if (preg_match('{^[^@]*?@(' . implode('|', array_keys($stabilities)) . ')$}i', $reqVersion, $match)) {
             $name = strtolower($reqName);
             $stability = $stabilities[VersionParser::normalizeStability($match[1])];
             if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) {
                 continue;
             }
             $stabilityFlags[$name] = $stability;
             continue;
         }
         // infer flags for requirements that have an explicit -dev or -beta version specified but only
         // for those that are more unstable than the minimumStability or existing flags
         $reqVersion = preg_replace('{^([^,\\s@]+) as .+$}', '$1', $reqVersion);
         if (preg_match('{^[^,\\s@]+$}', $reqVersion) && 'stable' !== ($stabilityName = VersionParser::parseStability($reqVersion))) {
             $name = strtolower($reqName);
             $stability = $stabilities[$stabilityName];
             if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability || $minimumStability > $stability) {
                 continue;
             }
             $stabilityFlags[$name] = $stability;
         }
     }
     return $stabilityFlags;
 }