From 5a02012706b59a74cf7b2e76ee8b80563a4f1e0f Mon Sep 17 00:00:00 2001 From: Tal Shiri Date: Mon, 16 Jun 2014 15:28:04 -0700 Subject: [PATCH] Allow specifying runtime configuration with --set-config key=value Summary: This is useful for wrapper scripts that want to customize arcanist's behavior without affecting the global configuration. This can be implemented with arcanist_configuration entry in .arcconfig, however it is currently limited to per-project settings, and this feature makes writing wrapper scripts a little easier. Test Plan: arc diff --set-config editor=vim (yeah yeah, crappy test case) Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: epriestley, Korvin Differential Revision: https://secure.phabricator.com/D9442 --- scripts/arcanist.php | 46 +++++++++++++------ .../ArcanistConfigurationManager.php | 21 ++++++++- src/workflow/ArcanistBaseWorkflow.php | 1 + src/workflow/ArcanistHelpWorkflow.php | 4 ++ 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/scripts/arcanist.php b/scripts/arcanist.php index d23e8abd..1aca2d59 100755 --- a/scripts/arcanist.php +++ b/scripts/arcanist.php @@ -8,9 +8,9 @@ require_once dirname(__FILE__).'/__init_script__.php'; ini_set('memory_limit', -1); $original_argv = $argv; -$args = new PhutilArgumentParser($argv); -$args->parseStandardArguments(); -$args->parsePartial( +$base_args = new PhutilArgumentParser($argv); +$base_args->parseStandardArguments(); +$base_args->parsePartial( array( array( 'name' => 'load-phutil-library', @@ -40,20 +40,26 @@ $args->parsePartial( 'param' => 'timeout', 'help' => 'Set Conduit timeout (in seconds).', ), - )); + array( + 'name' => 'config', + 'param' => 'key=value', + 'repeat' => true, + 'help' => + 'Specify a runtime configuration value. This will take precedence '. + 'over static values, and only affect the current arcanist invocation.' + ), +)); -$config_trace_mode = $args->getArg('trace'); +$config_trace_mode = $base_args->getArg('trace'); -$force_conduit = $args->getArg('conduit-uri'); -$force_conduit_version = $args->getArg('conduit-version'); -$conduit_timeout = $args->getArg('conduit-timeout'); -$skip_arcconfig = $args->getArg('skip-arcconfig'); -$custom_arcrc = $args->getArg('arcrc-file'); -$load = $args->getArg('load-phutil-library'); -$help = $args->getArg('help'); - -$argv = $args->getUnconsumedArgumentVector(); -$args = array_values($argv); +$force_conduit = $base_args->getArg('conduit-uri'); +$force_conduit_version = $base_args->getArg('conduit-version'); +$conduit_timeout = $base_args->getArg('conduit-timeout'); +$skip_arcconfig = $base_args->getArg('skip-arcconfig'); +$custom_arcrc = $base_args->getArg('arcrc-file'); +$load = $base_args->getArg('load-phutil-library'); +$help = $base_args->getArg('help'); +$args = array_values($base_args->getUnconsumedArgumentVector()); $working_directory = getcwd(); $console = PhutilConsole::getConsole(); @@ -86,6 +92,8 @@ try { $global_config = $configuration_manager->readUserArcConfig(); $system_config = $configuration_manager->readSystemArcConfig(); + $runtime_config = $configuration_manager->applyRuntimeArcConfig($base_args); + if ($skip_arcconfig) { $working_copy = ArcanistWorkingCopyIdentity::newDummyWorkingCopy(); } else { @@ -142,6 +150,14 @@ try { $must_load = true, $lib_source = 'the "load" setting in ".arcconfig"', $working_copy); + + // Load libraries in ".arcconfig". Libraries here must load. + arcanist_load_libraries( + idx($runtime_config, 'load', array()), + $must_load = true, + $lib_source = 'the --config "load=[...]" argument', + $working_copy); + } $user_config = $configuration_manager->readUserConfigurationFile(); diff --git a/src/configuration/ArcanistConfigurationManager.php b/src/configuration/ArcanistConfigurationManager.php index 535c563f..482bee45 100644 --- a/src/configuration/ArcanistConfigurationManager.php +++ b/src/configuration/ArcanistConfigurationManager.php @@ -305,7 +305,26 @@ final class ArcanistConfigurationManager { return $system_config; } - public function readDefaultConfig() { + public function applyRuntimeArcConfig($args) { + $arcanist_settings = new ArcanistSettings(); + $options = $args->getArg('config'); + + foreach ($options as $opt) { + $opt_config = preg_split('/=/', $opt, 2); + if (count($opt_config) !== 2) { + throw new ArcanistUsageException("Argument was '{$opt}', but must be ". + "'name=value'. For example, history.immutable=true"); + } + + list($key, $value) = $opt_config; + $value = $arcanist_settings->willWriteValue($key, $value); + $this->setRuntimeConfig($key, $value); + } + + return $this->runtimeConfig; + } + + public function readDefaultConfig() { $settings = new ArcanistSettings(); return $settings->getDefaultSettings(); } diff --git a/src/workflow/ArcanistBaseWorkflow.php b/src/workflow/ArcanistBaseWorkflow.php index b9e2bf18..b7adcaea 100644 --- a/src/workflow/ArcanistBaseWorkflow.php +++ b/src/workflow/ArcanistBaseWorkflow.php @@ -594,6 +594,7 @@ abstract class ArcanistBaseWorkflow extends Phobject { $arc_config = $this->getArcanistConfiguration(); $command = $this->getCommand(); $spec += $arc_config->getCustomArgumentsForCommand($command); + return $spec; } diff --git a/src/workflow/ArcanistHelpWorkflow.php b/src/workflow/ArcanistHelpWorkflow.php index 36a22765..27789149 100644 --- a/src/workflow/ArcanistHelpWorkflow.php +++ b/src/workflow/ArcanistHelpWorkflow.php @@ -199,6 +199,10 @@ EOTEXT __--conduit-timeout__ __timeout__ Override the default Conduit timeout. Specified in seconds. + __--config__ __key=value__ + Specify a runtime configuration value. This will take precedence + over static values, and only affect the current arcanist invocation. + __--skip-arcconfig__ Skip the working copy configuration file