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(); | |||||
} | |||||
} | } |