diff --git a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php index c766eed65..c2b87629f 100644 --- a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php +++ b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php @@ -1,368 +1,374 @@ array( 'name' => pht('Unbreak Now!'), 'short' => pht('Unbreak!'), 'color' => 'indigo', 'keywords' => array('unbreak'), ), 90 => array( 'name' => pht('Needs Triage'), 'short' => pht('Triage'), 'color' => 'violet', 'keywords' => array('triage'), ), 80 => array( 'name' => pht('High'), 'short' => pht('High'), 'color' => 'red', 'keywords' => array('high'), ), 50 => array( 'name' => pht('Normal'), 'short' => pht('Normal'), 'color' => 'orange', 'keywords' => array('normal'), ), 25 => array( 'name' => pht('Low'), 'short' => pht('Low'), 'color' => 'yellow', 'keywords' => array('low'), ), 0 => array( 'name' => pht('Wishlist'), 'short' => pht('Wish'), 'color' => 'sky', 'keywords' => array('wish', 'wishlist'), ), ); $status_type = 'custom:ManiphestStatusConfigOptionType'; $status_defaults = array( 'open' => array( 'name' => pht('Open'), 'special' => ManiphestTaskStatus::SPECIAL_DEFAULT, + 'prefixes' => array( + 'open', + 'opens', + 'reopen', + 'reopens', + ), ), 'resolved' => array( 'name' => pht('Resolved'), 'name.full' => pht('Closed, Resolved'), 'closed' => true, 'special' => ManiphestTaskStatus::SPECIAL_CLOSED, 'prefixes' => array( 'closed', 'closes', 'close', 'fix', 'fixes', 'fixed', 'resolve', 'resolves', 'resolved', ), 'suffixes' => array( 'as resolved', 'as fixed', ), 'keywords' => array('closed', 'fixed', 'resolved'), ), 'wontfix' => array( 'name' => pht('Wontfix'), 'name.full' => pht('Closed, Wontfix'), 'closed' => true, 'prefixes' => array( 'wontfix', 'wontfixes', 'wontfixed', ), 'suffixes' => array( 'as wontfix', ), ), 'invalid' => array( 'name' => pht('Invalid'), 'name.full' => pht('Closed, Invalid'), 'closed' => true, 'prefixes' => array( 'invalidate', 'invalidates', 'invalidated', ), 'suffixes' => array( 'as invalid', ), ), 'duplicate' => array( 'name' => pht('Duplicate'), 'name.full' => pht('Closed, Duplicate'), 'transaction.icon' => 'fa-files-o', 'special' => ManiphestTaskStatus::SPECIAL_DUPLICATE, 'closed' => true, ), 'spite' => array( 'name' => pht('Spite'), 'name.full' => pht('Closed, Spite'), 'name.action' => pht('Spited'), 'transaction.icon' => 'fa-thumbs-o-down', 'silly' => true, 'closed' => true, 'prefixes' => array( 'spite', 'spites', 'spited', ), 'suffixes' => array( 'out of spite', 'as spite', ), ), ); $status_description = $this->deformat(pht(<<.// Allows you to specify a list of text prefixes which will trigger a task transition into this status when mentioned in a commit message. For example, providing "closes" here will allow users to move tasks to this status by writing `Closes T123` in commit messages. - `suffixes` //Optional list.// Allows you to specify a list of text suffixes which will trigger a task transition into this status when mentioned in a commit message, after a valid prefix. For example, providing "as invalid" here will allow users to move tasks to this status by writing `Closes T123 as invalid`, even if another status is selected by the "Closes" prefix. - `keywords` //Optional list.// Allows you to specify a list of keywords which can be used with `!status` commands in email to select this status. Statuses will appear in the UI in the order specified. Note the status marked `special` as `duplicate` is not settable directly and will not appear in UI elements, and that any status marked `silly` does not appear if Phabricator is configured with `phabricator.serious-business` set to true. Examining the default configuration and examples below will probably be helpful in understanding these options. EOTEXT )); $status_example = array( 'open' => array( 'name' => 'Open', 'special' => 'default', ), 'closed' => array( 'name' => 'Closed', 'special' => 'closed', 'closed' => true, ), 'duplicate' => array( 'name' => 'Duplicate', 'special' => 'duplicate', 'closed' => true, ), ); $json = new PhutilJSON(); $status_example = $json->encodeFormatted($status_example); // This is intentionally blank for now, until we can move more Maniphest // logic to custom fields. $default_fields = array(); foreach ($default_fields as $key => $enabled) { $default_fields[$key] = array( 'disabled' => !$enabled, ); } $custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType'; return array( $this->newOption('maniphest.custom-field-definitions', 'wild', array()) ->setSummary(pht('Custom Maniphest fields.')) ->setDescription( pht( 'Array of custom fields for Maniphest tasks. For details on '. 'adding custom fields to Maniphest, see "Configuring Custom '. 'Fields" in the documentation.')) ->addExample( '{"mycompany:estimated-hours": {"name": "Estimated Hours", '. '"type": "int", "caption": "Estimated number of hours this will '. 'take."}}', pht('Valid Setting')), $this->newOption('maniphest.fields', $custom_field_type, $default_fields) ->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass()) ->setDescription(pht('Select and reorder task fields.')), $this->newOption('maniphest.priorities', 'wild', $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\n". 'You can choose which priority is the default for newly created '. 'tasks with `maniphest.default-priority`.')), $this->newOption('maniphest.statuses', $status_type, $status_defaults) ->setSummary(pht('Configure Maniphest task statuses.')) ->setDescription($status_description) ->addExample($status_example, pht('Minimal Valid Config')), $this->newOption('maniphest.default-priority', 'int', 90) ->setSummary(pht('Default task priority for create flows.')) ->setDescription( pht( 'Choose a default priority for newly created tasks. You can '. 'review and adjust available priorities by using the '. '{{maniphest.priorities}} configuration option. The default value '. '(`90`) corresponds to the default "Needs Triage" priority.')), $this->newOption( 'metamta.maniphest.subject-prefix', 'string', '[Maniphest]') ->setDescription(pht('Subject prefix for Maniphest mail.')), $this->newOption( 'metamta.maniphest.public-create-email', 'string', null) ->setLocked(true) ->setLockedMessage(pht( 'This configuration is deprecated. See description for details.')) ->setSummary(pht('DEPRECATED - Allow filing bugs via email.')) ->setDescription( pht( 'This config has been deprecated in favor of [[ '. '/applications/view/PhabricatorManiphestApplication/ | '. 'application settings ]], which allow for multiple email '. 'addresses and other functionality.'."\n\n". 'You can configure an email address like '. '"bugs@phabricator.example.com" which will automatically create '. 'Maniphest tasks when users send email to it. This relies on the '. '"From" address to authenticate users, so it is is not completely '. 'secure. To set this up, enter a complete email address like '. '"bugs@phabricator.example.com" and then configure mail to that '. 'address so it routed to Phabricator (if you\'ve already '. 'configured reply handlers, you\'re probably already done). See '. '"Configuring Inbound Email" in the documentation for more '. 'information.')), $this->newOption( 'metamta.maniphest.default-public-author', 'string', null) ->setLocked(true) ->setLockedMessage(pht( 'This configuration is deprecated. See description for details.')) ->setSummary(pht( 'DEPRECATED - Username anonymous bugs are filed under.')) ->setDescription( pht( 'This config has been deprecated in favor of [[ '. '/applications/view/PhabricatorManiphestApplication/ | '. 'application settings ]], which allow for multiple email '. 'addresses each with its own default author, and other '. 'functionality.'."\n\n". 'If you enable `metamta.maniphest.public-create-email` and create '. 'an email address like "bugs@phabricator.example.com", it will '. 'default to rejecting mail which doesn\'t come from a known user. '. 'However, you might want to let anyone send email to this '. 'address; to do so, set a default author here (a Phabricator '. 'username). A typical use of this might be to create a "System '. 'Agent" user called "bugs" and use that name here. If you specify '. 'a valid username, mail will always be accepted and used to '. 'create a task, even if the sender is not a system user. The '. 'original email address will be stored in an `From Email` field '. 'on the task.')), $this->newOption( 'maniphest.priorities.unbreak-now', 'int', 100) ->setSummary(pht('Priority used to populate "Unbreak Now" on home.')) ->setDescription( pht( 'Temporary setting. If set, this priority is used to populate the '. '"Unbreak Now" panel on the home page. You should adjust this if '. 'you adjust priorities using `maniphest.priorities`.')), $this->newOption( 'maniphest.priorities.needs-triage', 'int', 90) ->setSummary(pht('Priority used to populate "Needs Triage" on home.')) ->setDescription( pht( 'Temporary setting. If set, this priority is used to populate the '. '"Needs Triage" panel on the home page. You should adjust this if '. 'you adjust priorities using `maniphest.priorities`.')), ); } } diff --git a/src/applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php b/src/applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php index 77d8ddd73..cd64c23d2 100644 --- a/src/applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php +++ b/src/applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php @@ -1,63 +1,73 @@ array(), 'T123' => array(), 'Fixes T123' => array( array( 'match' => 'Fixes T123', 'prefix' => 'Fixes', 'infix' => '', 'monograms' => array('T123'), 'suffix' => '', 'offset' => 0, ), ), 'Fixes T123, T124, and also some other bugs.' => array( array( 'match' => 'Fixes T123, T124, ', 'prefix' => 'Fixes', 'infix' => '', 'monograms' => array('T123', 'T124'), 'suffix' => '', 'offset' => 0, ), ), 'Closes T1 as wontfix' => array( array( 'match' => 'Closes T1 as wontfix', 'prefix' => 'Closes', 'infix' => '', 'monograms' => array('T1'), 'suffix' => 'as wontfix', 'offset' => 0, ), ), 'Fixes task T9' => array( array( 'match' => 'Fixes task T9', 'prefix' => 'Fixes', 'infix' => 'task', 'monograms' => array('T9'), 'suffix' => '', 'offset' => 0, ), ), 'Fixes t2apps' => array(), 'fixes a bug' => array(), 'Prefixes T2' => array(), + 'Reopens T123' => array( + array( + 'match' => 'Reopens T123', + 'prefix' => 'Reopens', + 'infix' => '', + 'monograms' => array('T123'), + 'suffix' => '', + 'offset' => 0, + ), + ), ); foreach ($map as $input => $expect) { $parser = new ManiphestCustomFieldStatusParser(); $output = $parser->parseCorpus($input); $this->assertEqual($expect, $output, $input); } } }