mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 23:02:42 +01:00
Detect tasks referenced in commit messages and either link or update the mentioned tasks. Refs T945
Summary: This takes the place of D2721 which I am going to abandon. Test Plan: * Make a commit with "Closes T###" in the summary field. See that the mentioned task gets closed. * Make a commit with "refs T###" in the summary. See that it gets added as a related commit via edges. Reviewers: 20after4 Reviewed By: epriestley CC: aran, Korvin, champo Maniphest Tasks: T945 Differential Revision: https://secure.phabricator.com/D3466
This commit is contained in:
parent
303ad93996
commit
346747c788
4 changed files with 144 additions and 4 deletions
|
@ -254,6 +254,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialFieldSpecification' => 'applications/differential/field/specification/DifferentialFieldSpecification.php',
|
||||
'DifferentialFieldSpecificationIncompleteException' => 'applications/differential/field/exception/DifferentialFieldSpecificationIncompleteException.php',
|
||||
'DifferentialFieldValidationException' => 'applications/differential/field/exception/DifferentialFieldValidationException.php',
|
||||
'DifferentialFreeformFieldSpecification' => 'applications/differential/field/specification/DifferentialFreeformFieldSpecification.php',
|
||||
'DifferentialGitSVNIDFieldSpecification' => 'applications/differential/field/specification/DifferentialGitSVNIDFieldSpecification.php',
|
||||
'DifferentialHostFieldSpecification' => 'applications/differential/field/specification/DifferentialHostFieldSpecification.php',
|
||||
'DifferentialHunk' => 'applications/differential/storage/DifferentialHunk.php',
|
||||
|
@ -1435,6 +1436,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialFieldParseException' => 'Exception',
|
||||
'DifferentialFieldSpecificationIncompleteException' => 'Exception',
|
||||
'DifferentialFieldValidationException' => 'Exception',
|
||||
'DifferentialFreeformFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DifferentialGitSVNIDFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DifferentialHostFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DifferentialHunk' => 'DifferentialDAO',
|
||||
|
@ -1477,9 +1479,9 @@ phutil_register_library_map(array(
|
|||
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
|
||||
'DifferentialRevisionViewController' => 'DifferentialController',
|
||||
'DifferentialSubscribeController' => 'DifferentialController',
|
||||
'DifferentialSummaryFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DifferentialSummaryFieldSpecification' => 'DifferentialFreeformFieldSpecification',
|
||||
'DifferentialTestPlanFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DifferentialTitleFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DifferentialTitleFieldSpecification' => 'DifferentialFreeformFieldSpecification',
|
||||
'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification',
|
||||
'DiffusionBranchTableController' => 'DiffusionController',
|
||||
'DiffusionBranchTableView' => 'DiffusionView',
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
abstract class DifferentialFreeformFieldSpecification
|
||||
extends DifferentialFieldSpecification {
|
||||
|
||||
public function didParseCommit(
|
||||
PhabricatorRepository $repository,
|
||||
PhabricatorRepositoryCommit $commit,
|
||||
PhabricatorRepositoryCommitData $data) {
|
||||
|
||||
$user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'phid = %s',
|
||||
$data->getCommitDetail('authorPHID'));
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
$prefixes = array(
|
||||
'resolves' => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
||||
'fixes' => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
||||
'wontfix' => ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
|
||||
'wontfixes' => ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
|
||||
'spite' => ManiphestTaskStatus::STATUS_CLOSED_SPITE,
|
||||
'spites' => ManiphestTaskStatus::STATUS_CLOSED_SPITE,
|
||||
'invalidate' => ManiphestTaskStatus::STATUS_CLOSED_INVALID,
|
||||
'invaldiates' => ManiphestTaskStatus::STATUS_CLOSED_INVALID,
|
||||
'close' => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
||||
'closes' => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
||||
'ref' => null,
|
||||
'refs' => null,
|
||||
'references' => null,
|
||||
'cf.' => null,
|
||||
);
|
||||
|
||||
$suffixes = array(
|
||||
'as resolved' => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
||||
'as fixed' => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
|
||||
'as wontfix' => ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
|
||||
'as spite' => ManiphestTaskStatus::STATUS_CLOSED_SPITE,
|
||||
'out of spite' => ManiphestTaskStatus::STATUS_CLOSED_SPITE,
|
||||
'as invalid' => ManiphestTaskStatus::STATUS_CLOSED_INVALID,
|
||||
'' => null,
|
||||
);
|
||||
|
||||
$prefix_regex = array();
|
||||
foreach ($prefixes as $prefix => $resolution) {
|
||||
$prefix_regex[] = preg_quote($prefix, '/');
|
||||
}
|
||||
$prefix_regex = implode('|', $prefix_regex);
|
||||
|
||||
$suffix_regex = array();
|
||||
foreach ($suffixes as $suffix => $resolution) {
|
||||
$suffix_regex[] = preg_quote($suffix, '/');
|
||||
}
|
||||
$suffix_regex = implode('|', $suffix_regex);
|
||||
|
||||
$matches = null;
|
||||
$ok = preg_match_all(
|
||||
"/({$prefix_regex})\s+T(\d+)\s+({$suffix_regex})/i",
|
||||
$this->renderValueForCommitMessage($is_edit = false),
|
||||
$matches,
|
||||
PREG_SET_ORDER);
|
||||
|
||||
if (!$ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($matches as $set) {
|
||||
$prefix = strtolower($set[1]);
|
||||
$task_id = (int)$set[2];
|
||||
$suffix = strtolower($set[3]);
|
||||
|
||||
$status = idx($suffixes, $suffix);
|
||||
if (!$status) {
|
||||
$status = idx($prefixes, $prefix);
|
||||
}
|
||||
|
||||
$tasks = id(new ManiphestTaskQuery())
|
||||
->withTaskIDs(array($task_id))
|
||||
->execute();
|
||||
$task = idx($tasks, $task_id);
|
||||
|
||||
if (!$task) {
|
||||
// Task doesn't exist, or the user can't see it.
|
||||
continue;
|
||||
}
|
||||
|
||||
id(new PhabricatorEdgeEditor())
|
||||
->setUser($user)
|
||||
->addEdge(
|
||||
$task->getPHID(),
|
||||
PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT,
|
||||
$commit->getPHID())
|
||||
->save();
|
||||
|
||||
if (!$status) {
|
||||
// Text like "Ref T123", don't change the task status.
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($task->getStatus() != ManiphestTaskStatus::STATUS_OPEN) {
|
||||
// Task is already closed.
|
||||
continue;
|
||||
}
|
||||
|
||||
$commit_name = $repository->formatCommitName(
|
||||
$commit->getCommitIdentifier());
|
||||
|
||||
$call = new ConduitCall(
|
||||
'maniphest.update',
|
||||
array(
|
||||
'id' => $task->getID(),
|
||||
'status' => $status,
|
||||
'comments' => "Closed by commit {$commit_name}.",
|
||||
));
|
||||
|
||||
$call->setUser($user);
|
||||
$call->execute();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
final class DifferentialSummaryFieldSpecification
|
||||
extends DifferentialFieldSpecification {
|
||||
extends DifferentialFreeformFieldSpecification {
|
||||
|
||||
private $summary = '';
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
final class DifferentialTitleFieldSpecification
|
||||
extends DifferentialFieldSpecification {
|
||||
extends DifferentialFreeformFieldSpecification {
|
||||
|
||||
private $title;
|
||||
private $error = true;
|
||||
|
|
Loading…
Reference in a new issue