Changeset View
Changeset View
Standalone View
Standalone View
src/config/ArcanistConfigurationEngine.php
| <?php | <?php | ||||
| final class ArcanistConfigurationEngine | final class ArcanistConfigurationEngine | ||||
| extends Phobject { | extends Phobject { | ||||
| private $workingCopy; | private $workingCopy; | ||||
| private $arguments; | private $arguments; | ||||
| private $toolset; | |||||
| public function setWorkingCopy(ArcanistWorkingCopy $working_copy) { | public function setWorkingCopy(ArcanistWorkingCopy $working_copy) { | ||||
| $this->workingCopy = $working_copy; | $this->workingCopy = $working_copy; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function getWorkingCopy() { | public function getWorkingCopy() { | ||||
| return $this->workingCopy; | return $this->workingCopy; | ||||
| ▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | final class ArcanistConfigurationEngine | ||||
| private function getUserConfigurationFilePath() { | private function getUserConfigurationFilePath() { | ||||
| if (phutil_is_windows()) { | if (phutil_is_windows()) { | ||||
| return getenv('APPDATA').'/.arcrc'; | return getenv('APPDATA').'/.arcrc'; | ||||
| } else { | } else { | ||||
| return getenv('HOME').'/.arcrc'; | return getenv('HOME').'/.arcrc'; | ||||
| } | } | ||||
| } | } | ||||
| public function newDefaults() { | |||||
| $map = $this->newConfigOptionsMap(); | |||||
| return mpull($map, 'getDefaultValue'); | |||||
| } | |||||
| public function newConfigOptionsMap() { | |||||
| $extensions = $this->newEngineExtensions(); | |||||
| $map = array(); | |||||
| $alias_map = array(); | |||||
| foreach ($extensions as $extension) { | |||||
| $options = $extension->newConfigurationOptions(); | |||||
| foreach ($options as $option) { | |||||
| $key = $option->getKey(); | |||||
| $this->validateConfigOptionKey($key, $extension); | |||||
| if (isset($map[$key])) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Configuration option ("%s") defined by extension "%s" '. | |||||
| 'conflicts with an existing option. Each option must have '. | |||||
| 'a unique key.', | |||||
| $key, | |||||
| get_class($extension))); | |||||
| } | |||||
| if (isset($alias_map[$key])) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Configuration option ("%s") defined by extension "%s" '. | |||||
| 'conflicts with an alias for another option ("%s"). The '. | |||||
| 'key and aliases of each option must be unique.', | |||||
| $key, | |||||
| get_class($extension), | |||||
| $alias_map[$key]->getKey())); | |||||
| } | |||||
| $map[$key] = $option; | |||||
| foreach ($option->getAliases() as $alias) { | |||||
| $this->validateConfigOptionKey($alias, $extension, $key); | |||||
| if (isset($map[$alias])) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Configuration option ("%s") defined by extension "%s" '. | |||||
| 'has an alias ("%s") which conflicts with an existing '. | |||||
| 'option. The key and aliases of each option must be '. | |||||
| 'unique.', | |||||
| $key, | |||||
| get_class($extension), | |||||
| $alias)); | |||||
| } | |||||
| if (isset($alias_map[$alias])) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Configuration option ("%s") defined by extension "%s" '. | |||||
| 'has an alias ("%s") which conflicts with the alias of '. | |||||
| 'another configuration option ("%s"). The key and aliases '. | |||||
| 'of each option must be unique.', | |||||
| $key, | |||||
| get_class($extension), | |||||
| $alias, | |||||
| $alias_map[$alias]->getKey())); | |||||
| } | |||||
| $alias_map[$alias] = $option; | |||||
| } | |||||
| } | |||||
| } | |||||
| return $map; | |||||
| } | |||||
| private function validateConfigOptionKey( | |||||
| $key, | |||||
| ArcanistConfigurationEngineExtension $extension, | |||||
| $is_alias_of = null) { | |||||
| $is_ok = preg_match('(^[a-z][a-z0-9._-]{2,}\z)', $key); | |||||
| if (!$is_ok) { | |||||
| if ($is_alias_of === null) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Extension ("%s") defines invalid configuration with key "%s". '. | |||||
| 'Configuration keys: may only contain lowercase letters, '. | |||||
| 'numbers, hyphens, underscores, and periods; must start with a '. | |||||
| 'letter; and must be at least three characters long.', | |||||
| get_class($extension), | |||||
| $key)); | |||||
| } else { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Extension ("%s") defines invalid alias ("%s") for configuration '. | |||||
| 'key ("%s"). Configuration keys and aliases: may only contain '. | |||||
| 'lowercase letters, numbers, hyphens, underscores, and periods; '. | |||||
| 'must start with a letter; and must be at least three characters '. | |||||
| 'long.', | |||||
| get_class($extension), | |||||
| $key, | |||||
| $is_alias_of)); | |||||
| } | |||||
| } | |||||
| } | |||||
| private function newEngineExtensions() { | |||||
| return id(new PhutilClassMapQuery()) | |||||
| ->setAncestorClass('ArcanistConfigurationEngineExtension') | |||||
| ->setUniqueMethod('getExtensionKey') | |||||
| ->setContinueOnFailure(true) | |||||
| ->execute(); | |||||
| } | |||||
| } | } | ||||