1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 21:40:55 +01:00

Allow Commits to be attached to Tasks using edges

Summary: Use Edges to attach Commits and Tasks. Note, no "edit attached commits" interface from tasks yet since the search backend needs a little work to list commits in a sensible way.

Test Plan: Attached commits to tasks. Looked at commits, looked at tasks.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T904

Differential Revision: https://secure.phabricator.com/D2105
This commit is contained in:
epriestley 2012-04-04 17:34:25 -07:00
parent cc586b0afa
commit 05b4c90bfd
7 changed files with 98 additions and 8 deletions

View file

@ -270,7 +270,11 @@ final class DiffusionCommitController extends DiffusionController {
assert_instances_of($parents, 'PhabricatorRepositoryCommit');
$user = $this->getRequest()->getUser();
$phids = array();
$task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$commit->getPHID(),
PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK);
$phids = $task_phids;
if ($data->getCommitDetail('authorPHID')) {
$phids[] = $data->getCommitDetail('authorPHID');
}
@ -333,6 +337,7 @@ final class DiffusionCommitController extends DiffusionController {
$props['Parents'] = implode(' · ', $parent_links);
}
$request = $this->getDiffusionRequest();
$contains = DiffusionContainsQuery::newFromDiffusionRequest($request);
@ -345,6 +350,15 @@ final class DiffusionCommitController extends DiffusionController {
$props['Branches'] = $branches;
}
if ($task_phids) {
$task_list = array();
foreach ($task_phids as $phid) {
$task_list[] = $handles[$phid]->renderLink();
}
$task_list = implode('<br />', $task_list);
$props['Tasks'] = $task_list;
}
return $props;
}
@ -634,18 +648,13 @@ final class DiffusionCommitController extends DiffusionController {
require_celerity_resource('phabricator-object-selector-css');
require_celerity_resource('javelin-behavior-phabricator-object-selector');
/*
TODO: Implement this.
$action = new AphrontHeadsupActionView();
$action->setName('Edit Maniphest Tasks');
$action->setURI('/search/attach/'.$commit->getPHID().'/TASK/');
$action->setURI('/search/attach/'.$commit->getPHID().'/TASK/edge/');
$action->setWorkflow(true);
$action->setClass('attach-maniphest');
$actions[] = $action;
*/
if ($user->getIsAdmin()) {
$action = new AphrontHeadsupActionView();
$action->setName('MetaMTA Transcripts');

View file

@ -36,6 +36,8 @@ phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/edges/constants/config');
phutil_require_module('phabricator', 'infrastructure/edges/query/edge');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'storage/queryfx');

View file

@ -51,7 +51,11 @@ final class ManiphestTaskDetailController extends ManiphestController {
'taskID = %d ORDER BY id ASC',
$task->getID());
$phids = array();
$commit_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$task->getPHID(),
PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT);
$phids = array_fill_keys($commit_phids, true);
foreach ($transactions as $transaction) {
foreach ($transaction->extractPHIDs() as $phid) {
$phids[$phid] = true;
@ -168,6 +172,15 @@ final class ManiphestTaskDetailController extends ManiphestController {
$dict['Revisions'] = $rev_links;
}
if ($commit_phids) {
$commit_links = array();
foreach ($commit_phids as $phid) {
$commit_links[] = $handles[$phid]->renderLink();
}
$commit_links = implode('<br />', $commit_links);
$dict['Commits'] = $commit_links;
}
$file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
if ($file_infos) {
$file_phids = array_keys($file_infos);

View file

@ -23,6 +23,8 @@ phutil_require_module('phabricator', 'applications/markup/engine');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/edges/constants/config');
phutil_require_module('phabricator', 'infrastructure/edges/query/edge');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/form/base');

View file

@ -29,6 +29,7 @@ final class PhabricatorSearchAttachController
const ACTION_ATTACH = 'attach';
const ACTION_MERGE = 'merge';
const ACTION_DEPENDENCIES = 'dependencies';
const ACTION_EDGE = 'edge';
public function willProcessRequest(array $data) {
$this->phid = $data['phid'];
@ -64,6 +65,16 @@ final class PhabricatorSearchAttachController
case self::ACTION_MERGE:
return $this->performMerge($object, $handle, $phids);
case self::ACTION_EDGE:
$edge_type = $this->getEdgeType($object_type, $attach_type);
$editor = id(new PhabricatorEdgeEditor());
foreach ($phids as $phid) {
$editor->addEdge($this->phid, $edge_type, $phid);
}
$editor->save();
return id(new AphrontReloadResponse())->setURI($handle->getURI());
case self::ACTION_DEPENDENCIES:
case self::ACTION_ATTACH:
$two_way = true;
@ -94,6 +105,13 @@ final class PhabricatorSearchAttachController
case self::ACTION_DEPENDENCIES:
$phids = $object->getAttachedPHIDs($attach_type);
break;
case self::ACTION_EDGE:
$edge_type = $this->getEdgeType($object_type, $attach_type);
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$this->phid,
$edge_type);
break;
default:
$phids = array();
break;
@ -202,9 +220,14 @@ final class PhabricatorSearchAttachController
$noun = 'Tasks';
$selected = 'assigned';
break;
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$noun = 'Commits';
$selected = 'created';
break;
}
switch ($this->action) {
case self::ACTION_EDGE:
case self::ACTION_ATTACH:
$dialog_title = "Manage Attached {$noun}";
$header_text = "Currently Attached {$noun}";
@ -272,4 +295,24 @@ final class PhabricatorSearchAttachController
}
}
private function getEdgeType($src_type, $dst_type) {
$t_cmit = PhabricatorPHIDConstants::PHID_TYPE_CMIT;
$t_task = PhabricatorPHIDConstants::PHID_TYPE_TASK;
$map = array(
$t_cmit => array(
$t_task => PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK,
),
$t_task => array(
$t_cmit => PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT,
),
);
if (empty($map[$src_type][$dst_type])) {
throw new Exception("Unknown edge type!");
}
return $map[$src_type][$dst_type];
}
}

View file

@ -19,6 +19,9 @@ phutil_require_module('phabricator', 'applications/phid/graph');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/search/controller/base');
phutil_require_module('phabricator', 'applications/search/editor/attach');
phutil_require_module('phabricator', 'infrastructure/edges/constants/config');
phutil_require_module('phabricator', 'infrastructure/edges/editor/edge');
phutil_require_module('phabricator', 'infrastructure/edges/query/edge');
phutil_require_module('phabricator', 'view/control/objectselector');
phutil_require_module('phutil', 'utils');

View file

@ -92,6 +92,24 @@ final class PhabricatorEdgeQuery extends PhabricatorQuery {
/* -( Executing the Query )------------------------------------------------ */
/**
* Convenience method for loading destination PHIDs with one source and one
* edge type. Equivalent to building a full query, but simplifies a common
* use case.
*
* @param phid Source PHID.
* @param const Edge type.
* @return list<phid> List of destination PHIDs.
*/
public static function loadDestinationPHIDs($src_phid, $edge_type) {
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($src_phid))
->withEdgeTypes(array($edge_type))
->execute();
return array_keys($edges[$src_phid][$edge_type]);
}
/**
* Load specified edges.
*