mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-01 09:28:22 +01:00
When creating or updating a revision, infer the repository from the diff
Summary: Ref T603. When a diff is attached to a revision, try to guess the repository if possible. In cases where we succeed, this automatically gives us intuitive policy behavior (i.e., you can see a revision if you can see the repository the change is against). I pulled this into a funky little "Lookup" class for two reasons: - It's used in two places; - I anticipate that we might need to add some sort of `explainWhy()` method if users find the heuristics confusing. Test Plan: Created and updated revisions, saw them pick up the correct repository association. Ran Herald dry run against associable and nonassociable revisions, saw correct values populate. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T603 Differential Revision: https://secure.phabricator.com/D7147
This commit is contained in:
parent
fb4c9b6345
commit
874a9b7fe3
5 changed files with 129 additions and 17 deletions
|
@ -395,6 +395,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialRemarkupRule' => 'applications/differential/remarkup/DifferentialRemarkupRule.php',
|
'DifferentialRemarkupRule' => 'applications/differential/remarkup/DifferentialRemarkupRule.php',
|
||||||
'DifferentialReplyHandler' => 'applications/differential/mail/DifferentialReplyHandler.php',
|
'DifferentialReplyHandler' => 'applications/differential/mail/DifferentialReplyHandler.php',
|
||||||
'DifferentialRepositoryFieldSpecification' => 'applications/differential/field/specification/DifferentialRepositoryFieldSpecification.php',
|
'DifferentialRepositoryFieldSpecification' => 'applications/differential/field/specification/DifferentialRepositoryFieldSpecification.php',
|
||||||
|
'DifferentialRepositoryLookup' => 'applications/differential/query/DifferentialRepositoryLookup.php',
|
||||||
'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
|
'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
|
||||||
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php',
|
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php',
|
||||||
'DifferentialReviewRequestMail' => 'applications/differential/mail/DifferentialReviewRequestMail.php',
|
'DifferentialReviewRequestMail' => 'applications/differential/mail/DifferentialReviewRequestMail.php',
|
||||||
|
@ -2470,6 +2471,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
'DifferentialRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
||||||
'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
|
'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
|
||||||
'DifferentialRepositoryFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialRepositoryFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
|
'DifferentialRepositoryLookup' => 'Phobject',
|
||||||
'DifferentialResultsTableView' => 'AphrontView',
|
'DifferentialResultsTableView' => 'AphrontView',
|
||||||
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialReviewRequestMail' => 'DifferentialMail',
|
'DifferentialReviewRequestMail' => 'DifferentialMail',
|
||||||
|
|
|
@ -126,6 +126,16 @@ final class DifferentialRevisionEditor extends PhabricatorEditor {
|
||||||
}
|
}
|
||||||
$this->diff = $diff;
|
$this->diff = $diff;
|
||||||
$this->comments = $comments;
|
$this->comments = $comments;
|
||||||
|
|
||||||
|
$repository = id(new DifferentialRepositoryLookup())
|
||||||
|
->setViewer($this->getActor())
|
||||||
|
->setDiff($diff)
|
||||||
|
->lookupRepository();
|
||||||
|
|
||||||
|
if ($repository) {
|
||||||
|
$this->getRevision()->setRepositoryPHID($repository->getPHID());
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guess which tracked repository a diff comes from.
|
||||||
|
*/
|
||||||
|
final class DifferentialRepositoryLookup extends Phobject {
|
||||||
|
|
||||||
|
private $viewer;
|
||||||
|
private $diff;
|
||||||
|
|
||||||
|
public function setDiff(DifferentialDiff $diff) {
|
||||||
|
$this->diff = $diff;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
|
$this->viewer = $viewer;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function lookupRepository() {
|
||||||
|
$viewer = $this->viewer;
|
||||||
|
$diff = $this->diff;
|
||||||
|
|
||||||
|
// Look for an explicit Arcanist project.
|
||||||
|
if ($diff->getArcanistProjectPHID()) {
|
||||||
|
$project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere(
|
||||||
|
'phid = %s',
|
||||||
|
$diff->getArcanistProjectPHID());
|
||||||
|
if ($project && $project->getRepositoryID()) {
|
||||||
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($project->getRepositoryID()))
|
||||||
|
->execute();
|
||||||
|
if ($repositories) {
|
||||||
|
return head($repositories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a repository UUID.
|
||||||
|
if ($diff->getRepositoryUUID()) {
|
||||||
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withUUIDs($diff->getRepositoryUUID())
|
||||||
|
->execute();
|
||||||
|
if ($repositories) {
|
||||||
|
return head($repositories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the base commit in Git and Mercurial.
|
||||||
|
$vcs = $diff->getSourceControlSystem();
|
||||||
|
$vcs_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
||||||
|
$vcs_hg = PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL;
|
||||||
|
if ($vcs == $vcs_git || $vcs == $vcs_hg) {
|
||||||
|
$base = $diff->getSourceControlBaseRevision();
|
||||||
|
if ($base) {
|
||||||
|
$commits = id(new DiffusionCommitQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIdentifiers(array($base))
|
||||||
|
->execute();
|
||||||
|
$commits = mgroup($commits, 'getRepositoryID');
|
||||||
|
if (count($commits) == 1) {
|
||||||
|
$repository_id = key($commits);
|
||||||
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($repository_id))
|
||||||
|
->execute();
|
||||||
|
if ($repositories) {
|
||||||
|
return head($repositories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Compare SVN remote URIs? Compare Git/Hg remote URIs? Add
|
||||||
|
// an explicit option to `.arcconfig`?
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -106,29 +106,33 @@ final class HeraldDifferentialRevisionAdapter extends HeraldAdapter {
|
||||||
|
|
||||||
public function loadRepository() {
|
public function loadRepository() {
|
||||||
if ($this->repository === null) {
|
if ($this->repository === null) {
|
||||||
$diff = $this->diff;
|
$this->repository = false;
|
||||||
|
|
||||||
$repository = false;
|
|
||||||
|
|
||||||
// TODO: (T603) Implement policy stuff in Herald.
|
// TODO: (T603) Implement policy stuff in Herald.
|
||||||
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
|
|
||||||
if ($diff->getRepositoryUUID()) {
|
$revision = $this->revision;
|
||||||
$repository = id(new PhabricatorRepository())->loadOneWhere(
|
if ($revision->getRepositoryPHID()) {
|
||||||
'uuid = %s',
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
$diff->getRepositoryUUID());
|
->setViewer($viewer)
|
||||||
}
|
->withPHIDs(array($revision->getRepositoryPHID()))
|
||||||
|
->execute();
|
||||||
if (!$repository && $diff->getArcanistProjectPHID()) {
|
if ($repositories) {
|
||||||
$project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere(
|
$this->repository = head($repositories);
|
||||||
'phid = %s',
|
return $this->repository;
|
||||||
$diff->getArcanistProjectPHID());
|
|
||||||
if ($project && $project->getRepositoryID()) {
|
|
||||||
$repository = id(new PhabricatorRepository())->load(
|
|
||||||
$project->getRepositoryID());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$repository = id(new DifferentialRepositoryLookup())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setDiff($this->diff)
|
||||||
|
->lookupRepository();
|
||||||
|
if ($repository) {
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
return $this->repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = false;
|
||||||
}
|
}
|
||||||
return $this->repository;
|
return $this->repository;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorRepositoryQuery
|
||||||
private $phids;
|
private $phids;
|
||||||
private $callsigns;
|
private $callsigns;
|
||||||
private $types;
|
private $types;
|
||||||
|
private $uuids;
|
||||||
|
|
||||||
const STATUS_OPEN = 'status-open';
|
const STATUS_OPEN = 'status-open';
|
||||||
const STATUS_CLOSED = 'status-closed';
|
const STATUS_CLOSED = 'status-closed';
|
||||||
|
@ -47,6 +48,11 @@ final class PhabricatorRepositoryQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withUUIDs(array $uuids) {
|
||||||
|
$this->uuids = $uuids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function needCommitCounts($need_counts) {
|
public function needCommitCounts($need_counts) {
|
||||||
$this->needCommitCounts = $need_counts;
|
$this->needCommitCounts = $need_counts;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -299,6 +305,13 @@ final class PhabricatorRepositoryQuery
|
||||||
$this->types);
|
$this->types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->uuids) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'r.uuid IN (%Ls)',
|
||||||
|
$this->uuids);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
Loading…
Add table
Reference in a new issue