diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1488,8 +1488,8 @@ 'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php', 'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php', 'ManiphestNameIndex' => 'applications/maniphest/storage/ManiphestNameIndex.php', - 'ManiphestPointsConfigOptionType' => 'applications/maniphest/config/ManiphestPointsConfigOptionType.php', - 'ManiphestPriorityConfigOptionType' => 'applications/maniphest/config/ManiphestPriorityConfigOptionType.php', + 'ManiphestPointsConfigType' => 'applications/maniphest/config/ManiphestPointsConfigType.php', + 'ManiphestPrioritiesConfigType' => 'applications/maniphest/config/ManiphestPrioritiesConfigType.php', 'ManiphestPriorityEmailCommand' => 'applications/maniphest/command/ManiphestPriorityEmailCommand.php', 'ManiphestPrioritySearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestPrioritySearchConduitAPIMethod.php', 'ManiphestProjectNameFulltextEngineExtension' => 'applications/maniphest/engineextension/ManiphestProjectNameFulltextEngineExtension.php', @@ -1500,11 +1500,11 @@ 'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php', 'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php', 'ManiphestSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestSearchConduitAPIMethod.php', - 'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php', 'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php', 'ManiphestStatusSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php', + 'ManiphestStatusesConfigType' => 'applications/maniphest/config/ManiphestStatusesConfigType.php', 'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php', - 'ManiphestSubtypesConfigOptionsType' => 'applications/maniphest/config/ManiphestSubtypesConfigOptionsType.php', + 'ManiphestSubtypesConfigType' => 'applications/maniphest/config/ManiphestSubtypesConfigType.php', 'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php', 'ManiphestTaskAssignHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignHeraldAction.php', 'ManiphestTaskAssignOtherHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignOtherHeraldAction.php', @@ -6603,8 +6603,8 @@ 'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension', 'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod', 'ManiphestNameIndex' => 'ManiphestDAO', - 'ManiphestPointsConfigOptionType' => 'PhabricatorConfigJSONOptionType', - 'ManiphestPriorityConfigOptionType' => 'PhabricatorConfigJSONOptionType', + 'ManiphestPointsConfigType' => 'PhabricatorJSONConfigType', + 'ManiphestPrioritiesConfigType' => 'PhabricatorJSONConfigType', 'ManiphestPriorityEmailCommand' => 'ManiphestEmailCommand', 'ManiphestPrioritySearchConduitAPIMethod' => 'ManiphestConduitAPIMethod', 'ManiphestProjectNameFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension', @@ -6615,11 +6615,11 @@ 'ManiphestReportController' => 'ManiphestController', 'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'ManiphestSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', - 'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType', 'ManiphestStatusEmailCommand' => 'ManiphestEmailCommand', 'ManiphestStatusSearchConduitAPIMethod' => 'ManiphestConduitAPIMethod', + 'ManiphestStatusesConfigType' => 'PhabricatorJSONConfigType', 'ManiphestSubpriorityController' => 'ManiphestController', - 'ManiphestSubtypesConfigOptionsType' => 'PhabricatorConfigJSONOptionType', + 'ManiphestSubtypesConfigType' => 'PhabricatorJSONConfigType', 'ManiphestTask' => array( 'ManiphestDAO', 'PhabricatorSubscribableInterface', diff --git a/src/applications/config/controller/PhabricatorConfigEditController.php b/src/applications/config/controller/PhabricatorConfigEditController.php --- a/src/applications/config/controller/PhabricatorConfigEditController.php +++ b/src/applications/config/controller/PhabricatorConfigEditController.php @@ -290,6 +290,11 @@ } catch (PhabricatorConfigValidationException $ex) { $errors[] = $ex->getMessage(); $xaction = null; + } catch (Exception $ex) { + // NOTE: Some older validators throw bare exceptions. Purely in good + // taste, it would be nice to convert these at some point. + $errors[] = $ex->getMessage(); + $xaction = null; } return array( diff --git a/src/applications/maniphest/config/ManiphestPointsConfigOptionType.php b/src/applications/maniphest/config/ManiphestPointsConfigOptionType.php deleted file mode 100644 --- a/src/applications/maniphest/config/ManiphestPointsConfigOptionType.php +++ /dev/null @@ -1,10 +0,0 @@ - array( 'name' => pht('Unbreak Now!'), + 'keywords' => array('unbreak'), 'short' => pht('Unbreak!'), 'color' => 'pink', - 'keywords' => array('unbreak'), ), 90 => array( 'name' => pht('Needs Triage'), + 'keywords' => array('triage'), 'short' => pht('Triage'), 'color' => 'violet', - 'keywords' => array('triage'), ), 80 => array( 'name' => pht('High'), + 'keywords' => array('high'), 'short' => pht('High'), 'color' => 'red', - 'keywords' => array('high'), ), 50 => array( 'name' => pht('Normal'), + 'keywords' => array('normal'), 'short' => pht('Normal'), 'color' => 'orange', - 'keywords' => array('normal'), ), 25 => array( 'name' => pht('Low'), + 'keywords' => array('low'), 'short' => pht('Low'), 'color' => 'yellow', - 'keywords' => array('low'), ), 0 => array( 'name' => pht('Wishlist'), + 'keywords' => array('wish', 'wishlist'), 'short' => pht('Wish'), 'color' => 'sky', - 'keywords' => array('wish', 'wishlist'), ), ); - $status_type = 'custom:ManiphestStatusConfigOptionType'; + $status_type = 'maniphest.statuses'; $status_defaults = array( 'open' => array( 'name' => pht('Open'), @@ -265,7 +265,7 @@ ); $fields_json = id(new PhutilJSON())->encodeFormatted($fields_example); - $points_type = 'custom:ManiphestPointsConfigOptionType'; + $points_type = 'maniphest.points'; $points_example_1 = array( 'enabled' => true, @@ -299,7 +299,7 @@ EOTEXT )); - $subtype_type = 'custom:ManiphestSubtypesConfigOptionsType'; + $subtype_type = 'maniphest.subtypes'; $subtype_default_key = PhabricatorEditEngineSubtype::SUBTYPE_DEFAULT; $subtype_example = array( array( @@ -349,6 +349,32 @@ , $subtype_default_key)); + $priorities_description = $this->deformat(pht(<<.// List of unique keywords which identify + this priority, like "high" or "low". Each priority must have at least one + keyword and two priorities may not share the same keyword. + - `short` //Optional string.// Alternate shorter name, used in UIs where + there is less space available. + - `color` //Optional string.// Color for this priority, like "red" or + "blue". + - `disabled` //Optional bool.// Set to true to prevent users from choosing + this priority when creating or editing tasks. Existing tasks will not be + affected, and can be batch edited to a different priority or left to + eventually die out. + +You can choose the default priority for newly created tasks with +"maniphest.default-priority". +EOTEXT + )); + return array( $this->newOption('maniphest.custom-field-definitions', 'wild', array()) @@ -367,30 +393,7 @@ $priority_type, $priority_defaults) ->setSummary(pht('Configure Maniphest priority names.')) - ->setDescription( - pht( - 'Allows you to edit or override the default priorities available '. - 'in Maniphest, like "High", "Normal" and "Low". The configuration '. - 'should contain a map of priority constants to priority '. - 'specifications (see defaults below for examples).'. - "\n\n". - 'The keys you can define for a priority are:'. - "\n\n". - ' - `name` Name of the priority.'."\n". - ' - `short` Alternate shorter name, used in UIs where there is '. - ' not much space available.'."\n". - ' - `color` A color for this priority, like "red" or "blue".'. - ' - `keywords` An optional list of keywords which can '. - ' be used to select this priority when using `!priority` '. - ' commands in email.'."\n". - ' - `disabled` Optional boolean to prevent users from choosing '. - ' this priority when creating or editing tasks. Existing '. - ' tasks will be unaffected, and can be batch edited to a '. - ' different priority or left to eventually die out.'. - "\n\n". - 'You can choose which priority is the default for newly created '. - 'tasks with `%s`.', - 'maniphest.default-priority')), + ->setDescription($priorities_description), $this->newOption('maniphest.statuses', $status_type, $status_defaults) ->setSummary(pht('Configure Maniphest task statuses.')) ->setDescription($status_description) diff --git a/src/applications/maniphest/constants/ManiphestTaskPriority.php b/src/applications/maniphest/constants/ManiphestTaskPriority.php --- a/src/applications/maniphest/constants/ManiphestTaskPriority.php +++ b/src/applications/maniphest/constants/ManiphestTaskPriority.php @@ -203,6 +203,7 @@ $config)); } + $all_keywords = array(); foreach ($config as $key => $value) { if (!ctype_digit((string)$key)) { throw new Exception( @@ -223,9 +224,9 @@ $value, array( 'name' => 'string', + 'keywords' => 'list', 'short' => 'optional string', 'color' => 'optional string', - 'keywords' => 'list', 'disabled' => 'optional bool', )); @@ -242,6 +243,18 @@ 'low', 'critical')); } + + if (isset($all_keywords[$keyword])) { + throw new Exception( + pht( + 'Two different task priorities ("%s" and "%s") have the same '. + 'keyword ("%s"). Keywords must uniquely identify priorities.', + $value['name'], + $all_keywords[$keyword], + $keyword)); + } + + $all_keywords[$keyword] = $value['name']; } } }