mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-10 14:51:06 +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');
|
assert_instances_of($parents, 'PhabricatorRepositoryCommit');
|
||||||
$user = $this->getRequest()->getUser();
|
$user = $this->getRequest()->getUser();
|
||||||
|
|
||||||
$phids = array();
|
$task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||||
|
$commit->getPHID(),
|
||||||
|
PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK);
|
||||||
|
|
||||||
|
$phids = $task_phids;
|
||||||
if ($data->getCommitDetail('authorPHID')) {
|
if ($data->getCommitDetail('authorPHID')) {
|
||||||
$phids[] = $data->getCommitDetail('authorPHID');
|
$phids[] = $data->getCommitDetail('authorPHID');
|
||||||
}
|
}
|
||||||
|
@ -333,6 +337,7 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$props['Parents'] = implode(' · ', $parent_links);
|
$props['Parents'] = implode(' · ', $parent_links);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$request = $this->getDiffusionRequest();
|
$request = $this->getDiffusionRequest();
|
||||||
|
|
||||||
$contains = DiffusionContainsQuery::newFromDiffusionRequest($request);
|
$contains = DiffusionContainsQuery::newFromDiffusionRequest($request);
|
||||||
|
@ -345,6 +350,15 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
$props['Branches'] = $branches;
|
$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;
|
return $props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,18 +648,13 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
require_celerity_resource('phabricator-object-selector-css');
|
require_celerity_resource('phabricator-object-selector-css');
|
||||||
require_celerity_resource('javelin-behavior-phabricator-object-selector');
|
require_celerity_resource('javelin-behavior-phabricator-object-selector');
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: Implement this.
|
|
||||||
|
|
||||||
$action = new AphrontHeadsupActionView();
|
$action = new AphrontHeadsupActionView();
|
||||||
$action->setName('Edit Maniphest Tasks');
|
$action->setName('Edit Maniphest Tasks');
|
||||||
$action->setURI('/search/attach/'.$commit->getPHID().'/TASK/');
|
$action->setURI('/search/attach/'.$commit->getPHID().'/TASK/edge/');
|
||||||
$action->setWorkflow(true);
|
$action->setWorkflow(true);
|
||||||
$action->setClass('attach-maniphest');
|
$action->setClass('attach-maniphest');
|
||||||
$actions[] = $action;
|
$actions[] = $action;
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ($user->getIsAdmin()) {
|
if ($user->getIsAdmin()) {
|
||||||
$action = new AphrontHeadsupActionView();
|
$action = new AphrontHeadsupActionView();
|
||||||
$action->setName('MetaMTA Transcripts');
|
$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/constants/repositorytype');
|
||||||
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
||||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
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/env');
|
||||||
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||||
phutil_require_module('phabricator', 'storage/queryfx');
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
|
@ -51,7 +51,11 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||||
'taskID = %d ORDER BY id ASC',
|
'taskID = %d ORDER BY id ASC',
|
||||||
$task->getID());
|
$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 ($transactions as $transaction) {
|
||||||
foreach ($transaction->extractPHIDs() as $phid) {
|
foreach ($transaction->extractPHIDs() as $phid) {
|
||||||
$phids[$phid] = true;
|
$phids[$phid] = true;
|
||||||
|
@ -168,6 +172,15 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||||
$dict['Revisions'] = $rev_links;
|
$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);
|
$file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
|
||||||
if ($file_infos) {
|
if ($file_infos) {
|
||||||
$file_phids = array_keys($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/constants');
|
||||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
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/env');
|
||||||
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||||
phutil_require_module('phabricator', 'view/form/base');
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
|
|
|
@ -29,6 +29,7 @@ final class PhabricatorSearchAttachController
|
||||||
const ACTION_ATTACH = 'attach';
|
const ACTION_ATTACH = 'attach';
|
||||||
const ACTION_MERGE = 'merge';
|
const ACTION_MERGE = 'merge';
|
||||||
const ACTION_DEPENDENCIES = 'dependencies';
|
const ACTION_DEPENDENCIES = 'dependencies';
|
||||||
|
const ACTION_EDGE = 'edge';
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
public function willProcessRequest(array $data) {
|
||||||
$this->phid = $data['phid'];
|
$this->phid = $data['phid'];
|
||||||
|
@ -64,6 +65,16 @@ final class PhabricatorSearchAttachController
|
||||||
case self::ACTION_MERGE:
|
case self::ACTION_MERGE:
|
||||||
return $this->performMerge($object, $handle, $phids);
|
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_DEPENDENCIES:
|
||||||
case self::ACTION_ATTACH:
|
case self::ACTION_ATTACH:
|
||||||
$two_way = true;
|
$two_way = true;
|
||||||
|
@ -94,6 +105,13 @@ final class PhabricatorSearchAttachController
|
||||||
case self::ACTION_DEPENDENCIES:
|
case self::ACTION_DEPENDENCIES:
|
||||||
$phids = $object->getAttachedPHIDs($attach_type);
|
$phids = $object->getAttachedPHIDs($attach_type);
|
||||||
break;
|
break;
|
||||||
|
case self::ACTION_EDGE:
|
||||||
|
$edge_type = $this->getEdgeType($object_type, $attach_type);
|
||||||
|
|
||||||
|
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||||
|
$this->phid,
|
||||||
|
$edge_type);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$phids = array();
|
$phids = array();
|
||||||
break;
|
break;
|
||||||
|
@ -202,9 +220,14 @@ final class PhabricatorSearchAttachController
|
||||||
$noun = 'Tasks';
|
$noun = 'Tasks';
|
||||||
$selected = 'assigned';
|
$selected = 'assigned';
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
|
||||||
|
$noun = 'Commits';
|
||||||
|
$selected = 'created';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->action) {
|
switch ($this->action) {
|
||||||
|
case self::ACTION_EDGE:
|
||||||
case self::ACTION_ATTACH:
|
case self::ACTION_ATTACH:
|
||||||
$dialog_title = "Manage Attached {$noun}";
|
$dialog_title = "Manage Attached {$noun}";
|
||||||
$header_text = "Currently 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/phid/handle/data');
|
||||||
phutil_require_module('phabricator', 'applications/search/controller/base');
|
phutil_require_module('phabricator', 'applications/search/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/search/editor/attach');
|
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('phabricator', 'view/control/objectselector');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -92,6 +92,24 @@ final class PhabricatorEdgeQuery extends PhabricatorQuery {
|
||||||
/* -( Executing the Query )------------------------------------------------ */
|
/* -( 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.
|
* Load specified edges.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue