mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 05:50: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:
parent
cc586b0afa
commit
05b4c90bfd
7 changed files with 98 additions and 8 deletions
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue