diff --git a/src/config/ArcanistConfigurationEngine.php b/src/config/ArcanistConfigurationEngine.php --- a/src/config/ArcanistConfigurationEngine.php +++ b/src/config/ArcanistConfigurationEngine.php @@ -178,6 +178,22 @@ ArcanistConfigurationEngineExtension $extension, $is_alias_of = null) { + $reserved = array( + // The presence of this key is used to detect old "~/.arcrc" files, so + // configuration options may not use it. + 'config', + ); + $reserved = array_fuse($reserved); + + if (isset($reserved[$key])) { + throw new Exception( + pht( + 'Extension ("%s") defines invalid configuration with key "%s". '. + 'This key is reserved.', + get_class($extension), + $key)); + } + $is_ok = preg_match('(^[a-z][a-z0-9._-]{2,}\z)', $key); if (!$is_ok) { if ($is_alias_of === null) { diff --git a/src/config/source/ArcanistFilesystemConfigurationSource.php b/src/config/source/ArcanistFilesystemConfigurationSource.php --- a/src/config/source/ArcanistFilesystemConfigurationSource.php +++ b/src/config/source/ArcanistFilesystemConfigurationSource.php @@ -16,6 +16,8 @@ } } + $values = $this->didReadFilesystemValues($values); + parent::__construct($values); } @@ -29,4 +31,8 @@ abstract public function getFileKindDisplayName(); + protected function didReadFilesystemValues(array $values) { + return $values; + } + } \ No newline at end of file diff --git a/src/config/source/ArcanistUserConfigurationSource.php b/src/config/source/ArcanistUserConfigurationSource.php --- a/src/config/source/ArcanistUserConfigurationSource.php +++ b/src/config/source/ArcanistUserConfigurationSource.php @@ -7,4 +7,42 @@ return pht('User Config File'); } + public function didReadFilesystemValues(array $values) { + // Before toolsets, the "~/.arcrc" file had separate top-level keys for + // "config", "hosts", and "aliases". Transform this older file format into + // a more modern format. + + if (!isset($values['config'])) { + // This isn't an older file, so just return the values unmodified. + return $values; + } + + // Make the keys in "config" top-level keys. Then add in whatever other + // top level keys exist, other than "config", preferring keys that already + // exist in the "config" dictionary. + + // For example, this older configuration file: + // + // { + // "hosts": ..., + // "config": {x: ..., y: ...}, + // "aliases": ... + // } + // + // ...becomes this modern file: + // + // { + // "x": ..., + // "y": ..., + // "hosts": ..., + // "aliases": ... + // } + + $result = $values['config']; + unset($values['config']); + $result += $values; + + return $result; + } + } \ No newline at end of file