2013-01-22 00:27:42 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorConfigManagementSetWorkflow
|
|
|
|
extends PhabricatorConfigManagementWorkflow {
|
|
|
|
|
|
|
|
protected function didConstruct() {
|
|
|
|
$this
|
|
|
|
->setName('set')
|
|
|
|
->setExamples('**set** __key__ __value__')
|
2014-10-09 01:15:05 +02:00
|
|
|
->setSynopsis(pht('Set a local configuration value.'))
|
2013-01-22 00:27:42 +01:00
|
|
|
->setArguments(
|
|
|
|
array(
|
2014-10-09 01:15:05 +02:00
|
|
|
array(
|
|
|
|
'name' => 'database',
|
2015-05-22 09:27:56 +02:00
|
|
|
'help' => pht(
|
|
|
|
'Update configuration in the database instead of '.
|
|
|
|
'in local configuration.'),
|
2014-10-09 01:15:05 +02:00
|
|
|
),
|
2013-01-22 00:27:42 +01:00
|
|
|
array(
|
|
|
|
'name' => 'args',
|
|
|
|
'wildcard' => true,
|
|
|
|
),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function execute(PhutilArgumentParser $args) {
|
|
|
|
$console = PhutilConsole::getConsole();
|
|
|
|
$argv = $args->getArg('args');
|
|
|
|
if (count($argv) == 0) {
|
2015-05-22 09:27:56 +02:00
|
|
|
throw new PhutilArgumentUsageException(
|
|
|
|
pht('Specify a configuration key and a value to set it to.'));
|
2013-01-22 00:27:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$key = $argv[0];
|
|
|
|
|
|
|
|
if (count($argv) == 1) {
|
2015-05-22 09:27:56 +02:00
|
|
|
throw new PhutilArgumentUsageException(
|
|
|
|
pht(
|
|
|
|
"Specify a value to set the key '%s' to.",
|
|
|
|
$key));
|
2013-01-22 00:27:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$value = $argv[1];
|
|
|
|
|
|
|
|
if (count($argv) > 2) {
|
2015-05-22 09:27:56 +02:00
|
|
|
throw new PhutilArgumentUsageException(
|
|
|
|
pht(
|
|
|
|
'Too many arguments: expected one key and one value.'));
|
2013-01-22 00:27:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$options = PhabricatorApplicationConfigOptions::loadAllOptions();
|
|
|
|
if (empty($options[$key])) {
|
2015-05-22 09:27:56 +02:00
|
|
|
throw new PhutilArgumentUsageException(
|
|
|
|
pht(
|
|
|
|
"No such configuration key '%s'! Use `%s` to list all keys.",
|
|
|
|
$key,
|
|
|
|
'config list'));
|
2013-01-22 00:27:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$option = $options[$key];
|
|
|
|
|
Begin modularizing config options in a more modern way
Summary:
Ref T12845. Config options are "modular", but the modularity is very old, half-implemented, and doesn't use modern patterns.
Half the types are hard-coded, while half the types are semi-modular but in a weird hacky way where you prefix the type with `custom:...`.
The actual API is also weird and requires types to return a lot of `array($stuff, $thing, $other_thing, $more_stuff)` sorts of tuples.
Instead:
- Add a new replacement layer which uses modern modularity patterns and overrides the older stuff if available, so we can migrate things one at a time.
- New layer uses a more modern API -- no `return array($thing, $other_thing, ...)`, and more modern building blocks (like AphrontHTTPParameterType).
- New layer allows custom types to be deleted, which will ultimately let us deal with T12845.
Then, convert the `'int'` type to use the new layer.
Test Plan:
- Set, edited, tried-to-change-in-an-invalid-way, and deleted an `'int'` option from the web UI.
- Same from the CLI.
- Edited `config.json` to have an invalid value, verified that the error was detected and config was repaired.
Reviewers: chad, amckinley
Reviewed By: amckinley
Maniphest Tasks: T12845
Differential Revision: https://secure.phabricator.com/D18155
2017-06-26 17:45:31 +02:00
|
|
|
$type = $option->newOptionType();
|
|
|
|
if ($type) {
|
|
|
|
try {
|
|
|
|
$value = $type->newValueFromCommandLineValue(
|
|
|
|
$option,
|
|
|
|
$value);
|
2017-06-26 18:22:40 +02:00
|
|
|
$type->validateStoredValue($option, $value);
|
Begin modularizing config options in a more modern way
Summary:
Ref T12845. Config options are "modular", but the modularity is very old, half-implemented, and doesn't use modern patterns.
Half the types are hard-coded, while half the types are semi-modular but in a weird hacky way where you prefix the type with `custom:...`.
The actual API is also weird and requires types to return a lot of `array($stuff, $thing, $other_thing, $more_stuff)` sorts of tuples.
Instead:
- Add a new replacement layer which uses modern modularity patterns and overrides the older stuff if available, so we can migrate things one at a time.
- New layer uses a more modern API -- no `return array($thing, $other_thing, ...)`, and more modern building blocks (like AphrontHTTPParameterType).
- New layer allows custom types to be deleted, which will ultimately let us deal with T12845.
Then, convert the `'int'` type to use the new layer.
Test Plan:
- Set, edited, tried-to-change-in-an-invalid-way, and deleted an `'int'` option from the web UI.
- Same from the CLI.
- Edited `config.json` to have an invalid value, verified that the error was detected and config was repaired.
Reviewers: chad, amckinley
Reviewed By: amckinley
Maniphest Tasks: T12845
Differential Revision: https://secure.phabricator.com/D18155
2017-06-26 17:45:31 +02:00
|
|
|
} catch (PhabricatorConfigValidationException $ex) {
|
|
|
|
throw new PhutilArgumentUsageException($ex->getMessage());
|
|
|
|
}
|
|
|
|
} else {
|
2017-06-27 15:30:19 +02:00
|
|
|
// NOTE: For now, this handles both "wild" values and custom types.
|
Begin modularizing config options in a more modern way
Summary:
Ref T12845. Config options are "modular", but the modularity is very old, half-implemented, and doesn't use modern patterns.
Half the types are hard-coded, while half the types are semi-modular but in a weird hacky way where you prefix the type with `custom:...`.
The actual API is also weird and requires types to return a lot of `array($stuff, $thing, $other_thing, $more_stuff)` sorts of tuples.
Instead:
- Add a new replacement layer which uses modern modularity patterns and overrides the older stuff if available, so we can migrate things one at a time.
- New layer uses a more modern API -- no `return array($thing, $other_thing, ...)`, and more modern building blocks (like AphrontHTTPParameterType).
- New layer allows custom types to be deleted, which will ultimately let us deal with T12845.
Then, convert the `'int'` type to use the new layer.
Test Plan:
- Set, edited, tried-to-change-in-an-invalid-way, and deleted an `'int'` option from the web UI.
- Same from the CLI.
- Edited `config.json` to have an invalid value, verified that the error was detected and config was repaired.
Reviewers: chad, amckinley
Reviewed By: amckinley
Maniphest Tasks: T12845
Differential Revision: https://secure.phabricator.com/D18155
2017-06-26 17:45:31 +02:00
|
|
|
$type = $option->getType();
|
|
|
|
switch ($type) {
|
|
|
|
default:
|
|
|
|
$value = json_decode($value, true);
|
|
|
|
if (!is_array($value)) {
|
|
|
|
switch ($type) {
|
|
|
|
default:
|
2017-06-26 18:22:40 +02:00
|
|
|
$message = pht(
|
|
|
|
'Config key "%s" is of type "%s". Specify it in JSON.',
|
|
|
|
$key,
|
|
|
|
$type);
|
Begin modularizing config options in a more modern way
Summary:
Ref T12845. Config options are "modular", but the modularity is very old, half-implemented, and doesn't use modern patterns.
Half the types are hard-coded, while half the types are semi-modular but in a weird hacky way where you prefix the type with `custom:...`.
The actual API is also weird and requires types to return a lot of `array($stuff, $thing, $other_thing, $more_stuff)` sorts of tuples.
Instead:
- Add a new replacement layer which uses modern modularity patterns and overrides the older stuff if available, so we can migrate things one at a time.
- New layer uses a more modern API -- no `return array($thing, $other_thing, ...)`, and more modern building blocks (like AphrontHTTPParameterType).
- New layer allows custom types to be deleted, which will ultimately let us deal with T12845.
Then, convert the `'int'` type to use the new layer.
Test Plan:
- Set, edited, tried-to-change-in-an-invalid-way, and deleted an `'int'` option from the web UI.
- Same from the CLI.
- Edited `config.json` to have an invalid value, verified that the error was detected and config was repaired.
Reviewers: chad, amckinley
Reviewed By: amckinley
Maniphest Tasks: T12845
Differential Revision: https://secure.phabricator.com/D18155
2017-06-26 17:45:31 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
throw new PhutilArgumentUsageException($message);
|
2015-03-02 16:51:19 +01:00
|
|
|
}
|
Begin modularizing config options in a more modern way
Summary:
Ref T12845. Config options are "modular", but the modularity is very old, half-implemented, and doesn't use modern patterns.
Half the types are hard-coded, while half the types are semi-modular but in a weird hacky way where you prefix the type with `custom:...`.
The actual API is also weird and requires types to return a lot of `array($stuff, $thing, $other_thing, $more_stuff)` sorts of tuples.
Instead:
- Add a new replacement layer which uses modern modularity patterns and overrides the older stuff if available, so we can migrate things one at a time.
- New layer uses a more modern API -- no `return array($thing, $other_thing, ...)`, and more modern building blocks (like AphrontHTTPParameterType).
- New layer allows custom types to be deleted, which will ultimately let us deal with T12845.
Then, convert the `'int'` type to use the new layer.
Test Plan:
- Set, edited, tried-to-change-in-an-invalid-way, and deleted an `'int'` option from the web UI.
- Same from the CLI.
- Edited `config.json` to have an invalid value, verified that the error was detected and config was repaired.
Reviewers: chad, amckinley
Reviewed By: amckinley
Maniphest Tasks: T12845
Differential Revision: https://secure.phabricator.com/D18155
2017-06-26 17:45:31 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-01-22 00:27:42 +01:00
|
|
|
}
|
Begin modularizing config options in a more modern way
Summary:
Ref T12845. Config options are "modular", but the modularity is very old, half-implemented, and doesn't use modern patterns.
Half the types are hard-coded, while half the types are semi-modular but in a weird hacky way where you prefix the type with `custom:...`.
The actual API is also weird and requires types to return a lot of `array($stuff, $thing, $other_thing, $more_stuff)` sorts of tuples.
Instead:
- Add a new replacement layer which uses modern modularity patterns and overrides the older stuff if available, so we can migrate things one at a time.
- New layer uses a more modern API -- no `return array($thing, $other_thing, ...)`, and more modern building blocks (like AphrontHTTPParameterType).
- New layer allows custom types to be deleted, which will ultimately let us deal with T12845.
Then, convert the `'int'` type to use the new layer.
Test Plan:
- Set, edited, tried-to-change-in-an-invalid-way, and deleted an `'int'` option from the web UI.
- Same from the CLI.
- Edited `config.json` to have an invalid value, verified that the error was detected and config was repaired.
Reviewers: chad, amckinley
Reviewed By: amckinley
Maniphest Tasks: T12845
Differential Revision: https://secure.phabricator.com/D18155
2017-06-26 17:45:31 +02:00
|
|
|
|
2014-10-09 01:15:05 +02:00
|
|
|
$use_database = $args->getArg('database');
|
|
|
|
if ($option->getLocked() && $use_database) {
|
2015-05-22 09:27:56 +02:00
|
|
|
throw new PhutilArgumentUsageException(
|
|
|
|
pht(
|
2016-01-28 16:01:17 +01:00
|
|
|
'Config key "%s" is locked and can only be set in local '.
|
|
|
|
'configuration. To learn more, see "%s" in the documentation.',
|
|
|
|
$key,
|
|
|
|
pht('Configuration Guide: Locked and Hidden Configuration')));
|
2014-10-09 01:15:05 +02:00
|
|
|
}
|
2013-01-22 00:27:42 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
$option->getGroup()->validateOption($option, $value);
|
|
|
|
} catch (PhabricatorConfigValidationException $validation) {
|
|
|
|
// Convert this into a usage exception so we don't dump a stack trace.
|
|
|
|
throw new PhutilArgumentUsageException($validation->getMessage());
|
|
|
|
}
|
|
|
|
|
2014-10-09 01:15:05 +02:00
|
|
|
if ($use_database) {
|
|
|
|
$config_type = 'database';
|
2015-01-09 22:58:11 +01:00
|
|
|
$config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
|
|
|
|
$config_entry->setValue($value);
|
2017-03-16 19:55:16 +01:00
|
|
|
|
|
|
|
// If the entry has been deleted, resurrect it.
|
|
|
|
$config_entry->setIsDeleted(0);
|
|
|
|
|
2015-01-09 22:58:11 +01:00
|
|
|
$config_entry->save();
|
2014-10-09 01:15:05 +02:00
|
|
|
} else {
|
|
|
|
$config_type = 'local';
|
|
|
|
id(new PhabricatorConfigLocalSource())
|
|
|
|
->setKeys(array($key => $value));
|
|
|
|
}
|
2013-01-22 00:27:42 +01:00
|
|
|
|
|
|
|
$console->writeOut(
|
2015-05-22 09:27:56 +02:00
|
|
|
"%s\n",
|
|
|
|
pht("Set '%s' in %s configuration.", $key, $config_type));
|
2013-01-22 00:27:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|