Skip to content

Commit 05b4c90

Browse files
author
epriestley
committed
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
1 parent cc586b0 commit 05b4c90

File tree

7 files changed

+98
-8
lines changed

7 files changed

+98
-8
lines changed

src/applications/diffusion/controller/commit/DiffusionCommitController.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,11 @@ private function getCommitProperties(
270270
assert_instances_of($parents, 'PhabricatorRepositoryCommit');
271271
$user = $this->getRequest()->getUser();
272272

273-
$phids = array();
273+
$task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
274+
$commit->getPHID(),
275+
PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK);
276+
277+
$phids = $task_phids;
274278
if ($data->getCommitDetail('authorPHID')) {
275279
$phids[] = $data->getCommitDetail('authorPHID');
276280
}
@@ -333,6 +337,7 @@ private function getCommitProperties(
333337
$props['Parents'] = implode(' · ', $parent_links);
334338
}
335339

340+
336341
$request = $this->getDiffusionRequest();
337342

338343
$contains = DiffusionContainsQuery::newFromDiffusionRequest($request);
@@ -345,6 +350,15 @@ private function getCommitProperties(
345350
$props['Branches'] = $branches;
346351
}
347352

353+
if ($task_phids) {
354+
$task_list = array();
355+
foreach ($task_phids as $phid) {
356+
$task_list[] = $handles[$phid]->renderLink();
357+
}
358+
$task_list = implode('<br />', $task_list);
359+
$props['Tasks'] = $task_list;
360+
}
361+
348362
return $props;
349363
}
350364

@@ -634,18 +648,13 @@ private function renderHeadsupActionList(
634648
require_celerity_resource('phabricator-object-selector-css');
635649
require_celerity_resource('javelin-behavior-phabricator-object-selector');
636650

637-
/*
638-
TODO: Implement this.
639-
640651
$action = new AphrontHeadsupActionView();
641652
$action->setName('Edit Maniphest Tasks');
642-
$action->setURI('/search/attach/'.$commit->getPHID().'/TASK/');
653+
$action->setURI('/search/attach/'.$commit->getPHID().'/TASK/edge/');
643654
$action->setWorkflow(true);
644655
$action->setClass('attach-maniphest');
645656
$actions[] = $action;
646657

647-
*/
648-
649658
if ($user->getIsAdmin()) {
650659
$action = new AphrontHeadsupActionView();
651660
$action->setName('MetaMTA Transcripts');

src/applications/diffusion/controller/commit/__init__.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
3737
phutil_require_module('phabricator', 'applications/repository/storage/repository');
3838
phutil_require_module('phabricator', 'infrastructure/celerity/api');
39+
phutil_require_module('phabricator', 'infrastructure/edges/constants/config');
40+
phutil_require_module('phabricator', 'infrastructure/edges/query/edge');
3941
phutil_require_module('phabricator', 'infrastructure/env');
4042
phutil_require_module('phabricator', 'infrastructure/javelin/api');
4143
phutil_require_module('phabricator', 'storage/queryfx');

src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ public function processRequest() {
5151
'taskID = %d ORDER BY id ASC',
5252
$task->getID());
5353

54-
$phids = array();
54+
$commit_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
55+
$task->getPHID(),
56+
PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT);
57+
58+
$phids = array_fill_keys($commit_phids, true);
5559
foreach ($transactions as $transaction) {
5660
foreach ($transaction->extractPHIDs() as $phid) {
5761
$phids[$phid] = true;
@@ -168,6 +172,15 @@ public function processRequest() {
168172
$dict['Revisions'] = $rev_links;
169173
}
170174

175+
if ($commit_phids) {
176+
$commit_links = array();
177+
foreach ($commit_phids as $phid) {
178+
$commit_links[] = $handles[$phid]->renderLink();
179+
}
180+
$commit_links = implode('<br />', $commit_links);
181+
$dict['Commits'] = $commit_links;
182+
}
183+
171184
$file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
172185
if ($file_infos) {
173186
$file_phids = array_keys($file_infos);

src/applications/maniphest/controller/taskdetail/__init__.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
phutil_require_module('phabricator', 'applications/phid/constants');
2424
phutil_require_module('phabricator', 'applications/phid/handle/data');
2525
phutil_require_module('phabricator', 'infrastructure/celerity/api');
26+
phutil_require_module('phabricator', 'infrastructure/edges/constants/config');
27+
phutil_require_module('phabricator', 'infrastructure/edges/query/edge');
2628
phutil_require_module('phabricator', 'infrastructure/env');
2729
phutil_require_module('phabricator', 'infrastructure/javelin/api');
2830
phutil_require_module('phabricator', 'view/form/base');

src/applications/search/controller/attach/PhabricatorSearchAttachController.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ final class PhabricatorSearchAttachController
2929
const ACTION_ATTACH = 'attach';
3030
const ACTION_MERGE = 'merge';
3131
const ACTION_DEPENDENCIES = 'dependencies';
32+
const ACTION_EDGE = 'edge';
3233

3334
public function willProcessRequest(array $data) {
3435
$this->phid = $data['phid'];
@@ -64,6 +65,16 @@ public function processRequest() {
6465
case self::ACTION_MERGE:
6566
return $this->performMerge($object, $handle, $phids);
6667

68+
case self::ACTION_EDGE:
69+
$edge_type = $this->getEdgeType($object_type, $attach_type);
70+
71+
$editor = id(new PhabricatorEdgeEditor());
72+
foreach ($phids as $phid) {
73+
$editor->addEdge($this->phid, $edge_type, $phid);
74+
}
75+
$editor->save();
76+
77+
return id(new AphrontReloadResponse())->setURI($handle->getURI());
6778
case self::ACTION_DEPENDENCIES:
6879
case self::ACTION_ATTACH:
6980
$two_way = true;
@@ -94,6 +105,13 @@ public function processRequest() {
94105
case self::ACTION_DEPENDENCIES:
95106
$phids = $object->getAttachedPHIDs($attach_type);
96107
break;
108+
case self::ACTION_EDGE:
109+
$edge_type = $this->getEdgeType($object_type, $attach_type);
110+
111+
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
112+
$this->phid,
113+
$edge_type);
114+
break;
97115
default:
98116
$phids = array();
99117
break;
@@ -202,9 +220,14 @@ private function getStrings() {
202220
$noun = 'Tasks';
203221
$selected = 'assigned';
204222
break;
223+
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
224+
$noun = 'Commits';
225+
$selected = 'created';
226+
break;
205227
}
206228

207229
switch ($this->action) {
230+
case self::ACTION_EDGE:
208231
case self::ACTION_ATTACH:
209232
$dialog_title = "Manage Attached {$noun}";
210233
$header_text = "Currently Attached {$noun}";
@@ -272,4 +295,24 @@ private function detectGraphCycles(
272295
}
273296
}
274297

298+
private function getEdgeType($src_type, $dst_type) {
299+
$t_cmit = PhabricatorPHIDConstants::PHID_TYPE_CMIT;
300+
$t_task = PhabricatorPHIDConstants::PHID_TYPE_TASK;
301+
302+
$map = array(
303+
$t_cmit => array(
304+
$t_task => PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK,
305+
),
306+
$t_task => array(
307+
$t_cmit => PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT,
308+
),
309+
);
310+
311+
if (empty($map[$src_type][$dst_type])) {
312+
throw new Exception("Unknown edge type!");
313+
}
314+
315+
return $map[$src_type][$dst_type];
316+
}
317+
275318
}

src/applications/search/controller/attach/__init__.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
phutil_require_module('phabricator', 'applications/phid/handle/data');
2020
phutil_require_module('phabricator', 'applications/search/controller/base');
2121
phutil_require_module('phabricator', 'applications/search/editor/attach');
22+
phutil_require_module('phabricator', 'infrastructure/edges/constants/config');
23+
phutil_require_module('phabricator', 'infrastructure/edges/editor/edge');
24+
phutil_require_module('phabricator', 'infrastructure/edges/query/edge');
2225
phutil_require_module('phabricator', 'view/control/objectselector');
2326

2427
phutil_require_module('phutil', 'utils');

src/infrastructure/edges/query/edge/PhabricatorEdgeQuery.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,24 @@ public function needEdgeData($need) {
9292
/* -( Executing the Query )------------------------------------------------ */
9393

9494

95+
/**
96+
* Convenience method for loading destination PHIDs with one source and one
97+
* edge type. Equivalent to building a full query, but simplifies a common
98+
* use case.
99+
*
100+
* @param phid Source PHID.
101+
* @param const Edge type.
102+
* @return list<phid> List of destination PHIDs.
103+
*/
104+
public static function loadDestinationPHIDs($src_phid, $edge_type) {
105+
$edges = id(new PhabricatorEdgeQuery())
106+
->withSourcePHIDs(array($src_phid))
107+
->withEdgeTypes(array($edge_type))
108+
->execute();
109+
return array_keys($edges[$src_phid][$edge_type]);
110+
}
111+
112+
95113
/**
96114
* Load specified edges.
97115
*

0 commit comments

Comments
 (0)