1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 16:52:41 +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:
epriestley 2012-09-11 10:37:30 -07:00
parent 303ad93996
commit 346747c788
4 changed files with 144 additions and 4 deletions

View file

@ -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',

View file

@ -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();
}
}
}

View file

@ -17,7 +17,7 @@
*/
final class DifferentialSummaryFieldSpecification
extends DifferentialFieldSpecification {
extends DifferentialFreeformFieldSpecification {
private $summary = '';

View file

@ -17,7 +17,7 @@
*/
final class DifferentialTitleFieldSpecification
extends DifferentialFieldSpecification {
extends DifferentialFreeformFieldSpecification {
private $title;
private $error = true;