mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-25 08:12:40 +01:00
Load and map repository objects for remote URIs
Summary: Ref T13546. Query and associate known Phabricator repositories to working copy remotes by normalizing and comparing URIs. This primarily gives us access to "permanentRefRules" so we can tell which branches have published changes. Test Plan: Ran "arc look remotes" in Git and Mercurial working copies, saw repositories map properly. Maniphest Tasks: T13546 Differential Revision: https://secure.phabricator.com/D21377
This commit is contained in:
parent
6bf7a40358
commit
50f7a853b5
9 changed files with 232 additions and 3 deletions
|
@ -422,6 +422,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistRefView' => 'ref/ArcanistRefView.php',
|
'ArcanistRefView' => 'ref/ArcanistRefView.php',
|
||||||
'ArcanistRemoteRef' => 'repository/remote/ArcanistRemoteRef.php',
|
'ArcanistRemoteRef' => 'repository/remote/ArcanistRemoteRef.php',
|
||||||
'ArcanistRemoteRefInspector' => 'repository/remote/ArcanistRemoteRefInspector.php',
|
'ArcanistRemoteRefInspector' => 'repository/remote/ArcanistRemoteRefInspector.php',
|
||||||
|
'ArcanistRemoteRepositoryRefsHardpointQuery' => 'repository/remote/ArcanistRemoteRepositoryRefsHardpointQuery.php',
|
||||||
'ArcanistRepositoryAPI' => 'repository/api/ArcanistRepositoryAPI.php',
|
'ArcanistRepositoryAPI' => 'repository/api/ArcanistRepositoryAPI.php',
|
||||||
'ArcanistRepositoryAPIMiscTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIMiscTestCase.php',
|
'ArcanistRepositoryAPIMiscTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIMiscTestCase.php',
|
||||||
'ArcanistRepositoryAPIStateTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIStateTestCase.php',
|
'ArcanistRepositoryAPIStateTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIStateTestCase.php',
|
||||||
|
@ -1455,6 +1456,7 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'ArcanistRemoteRef' => 'ArcanistRef',
|
'ArcanistRemoteRef' => 'ArcanistRef',
|
||||||
'ArcanistRemoteRefInspector' => 'ArcanistRefInspector',
|
'ArcanistRemoteRefInspector' => 'ArcanistRefInspector',
|
||||||
|
'ArcanistRemoteRepositoryRefsHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
||||||
'ArcanistRepositoryAPI' => 'Phobject',
|
'ArcanistRepositoryAPI' => 'Phobject',
|
||||||
'ArcanistRepositoryAPIMiscTestCase' => 'PhutilTestCase',
|
'ArcanistRepositoryAPIMiscTestCase' => 'PhutilTestCase',
|
||||||
'ArcanistRepositoryAPIStateTestCase' => 'PhutilTestCase',
|
'ArcanistRepositoryAPIStateTestCase' => 'PhutilTestCase',
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
final class ArcanistRepositoryRef
|
final class ArcanistRepositoryRef
|
||||||
extends ArcanistRef {
|
extends ArcanistRef {
|
||||||
|
|
||||||
|
private $parameters = array();
|
||||||
private $phid;
|
private $phid;
|
||||||
private $browseURI;
|
private $browseURI;
|
||||||
|
|
||||||
|
@ -24,6 +25,37 @@ final class ArcanistRepositoryRef
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function newFromConduit(array $map) {
|
||||||
|
$ref = new self();
|
||||||
|
$ref->parameters = $map;
|
||||||
|
|
||||||
|
$ref->phid = $map['phid'];
|
||||||
|
|
||||||
|
return $ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getURIs() {
|
||||||
|
$uris = idxv($this->parameters, array('attachments', 'uris', 'uris'));
|
||||||
|
|
||||||
|
if (!$uris) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($uris as $uri) {
|
||||||
|
$effective_uri = idxv($uri, array('fields', 'uri', 'effective'));
|
||||||
|
if ($effective_uri !== null) {
|
||||||
|
$results[] = $effective_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisplayName() {
|
||||||
|
return idxv($this->parameters, array('fields', 'name'));
|
||||||
|
}
|
||||||
|
|
||||||
public function newBrowseURI(array $params) {
|
public function newBrowseURI(array $params) {
|
||||||
PhutilTypeSpec::checkMap(
|
PhutilTypeSpec::checkMap(
|
||||||
$params,
|
$params,
|
||||||
|
@ -67,9 +99,13 @@ final class ArcanistRepositoryRef
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultBranch() {
|
public function getDefaultBranch() {
|
||||||
// TODO: This should read from the remote, and is not correct for
|
$branch = idxv($this->parameters, array('fields', 'defaultBranch'));
|
||||||
// Mercurial anyway, as "default" would be a better default branch.
|
|
||||||
return 'master';
|
if ($branch === null) {
|
||||||
|
return 'master';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1767,4 +1767,10 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
return new ArcanistGitRepositoryRemoteQuery();
|
return new ArcanistGitRepositoryRemoteQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function newNormalizedURI($uri) {
|
||||||
|
return new ArcanistRepositoryURINormalizer(
|
||||||
|
ArcanistRepositoryURINormalizer::TYPE_GIT,
|
||||||
|
$uri);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1025,4 +1025,10 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function newNormalizedURI($uri) {
|
||||||
|
return new ArcanistRepositoryURINormalizer(
|
||||||
|
ArcanistRepositoryURINormalizer::TYPE_MERCURIAL,
|
||||||
|
$uri);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -798,4 +798,13 @@ abstract class ArcanistRepositoryAPI extends Phobject {
|
||||||
return substr($hash, 0, 12);
|
return substr($hash, 0, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final public function getNormalizedURI($uri) {
|
||||||
|
$normalized_uri = $this->newNormalizedURI($uri);
|
||||||
|
return $normalized_uri->getNormalizedURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newNormalizedURI($uri) {
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,26 @@
|
||||||
final class ArcanistRemoteRef
|
final class ArcanistRemoteRef
|
||||||
extends ArcanistRef {
|
extends ArcanistRef {
|
||||||
|
|
||||||
|
private $repositoryAPI;
|
||||||
private $remoteName;
|
private $remoteName;
|
||||||
private $fetchURI;
|
private $fetchURI;
|
||||||
private $pushURI;
|
private $pushURI;
|
||||||
|
|
||||||
|
const HARDPOINT_REPOSITORYREFS = 'arc.remote.repositoryRefs';
|
||||||
|
|
||||||
public function getRefDisplayName() {
|
public function getRefDisplayName() {
|
||||||
return pht('Remote "%s"', $this->getRemoteName());
|
return pht('Remote "%s"', $this->getRemoteName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setRepositoryAPI(ArcanistRepositoryAPI $repository_api) {
|
||||||
|
$this->repositoryAPI = $repository_api;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRepositoryAPI() {
|
||||||
|
return $this->repositoryAPI;
|
||||||
|
}
|
||||||
|
|
||||||
public function setRemoteName($remote_name) {
|
public function setRemoteName($remote_name) {
|
||||||
$this->remoteName = $remote_name;
|
$this->remoteName = $remote_name;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -42,4 +54,39 @@ final class ArcanistRemoteRef
|
||||||
$view->setObjectName($this->getRemoteName());
|
$view->setObjectName($this->getRemoteName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function newHardpoints() {
|
||||||
|
$object_list = new ArcanistObjectListHardpoint();
|
||||||
|
return array(
|
||||||
|
$this->newTemplateHardpoint(self::HARDPOINT_REPOSITORYREFS, $object_list),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRepositoryRefs() {
|
||||||
|
return $this->getHardpoint(self::HARDPOINT_REPOSITORYREFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPushRepositoryRef() {
|
||||||
|
return $this->getRepositoryRefByURI($this->getPushURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFetchRepositoryRef() {
|
||||||
|
return $this->getRepositoryRefByURI($this->getFetchURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRepositoryRefByURI($uri) {
|
||||||
|
$api = $this->getRepositoryAPI();
|
||||||
|
|
||||||
|
$uri = $api->getNormalizedURI($uri);
|
||||||
|
foreach ($this->getRepositoryRefs() as $repository_ref) {
|
||||||
|
foreach ($repository_ref->getURIs() as $repository_uri) {
|
||||||
|
$repository_uri = $api->getNormalizedURI($repository_uri);
|
||||||
|
if ($repository_uri === $uri) {
|
||||||
|
return $repository_ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistRemoteRepositoryRefsHardpointQuery
|
||||||
|
extends ArcanistRuntimeHardpointQuery {
|
||||||
|
|
||||||
|
public function getHardpoints() {
|
||||||
|
return array(
|
||||||
|
ArcanistRemoteRef::HARDPOINT_REPOSITORYREFS,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function canLoadRef(ArcanistRef $ref) {
|
||||||
|
return ($ref instanceof ArcanistRemoteRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadHardpoint(array $refs, $hardpoint) {
|
||||||
|
$api = $this->getRepositoryAPI();
|
||||||
|
|
||||||
|
$uris = array();
|
||||||
|
foreach ($refs as $remote) {
|
||||||
|
$fetch_uri = $remote->getFetchURI();
|
||||||
|
if ($fetch_uri !== null) {
|
||||||
|
$uris[] = $fetch_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
$push_uri = $remote->getPushURI();
|
||||||
|
if ($push_uri !== null) {
|
||||||
|
$uris[] = $push_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$uris) {
|
||||||
|
yield $this->yieldValue($refs, array());
|
||||||
|
}
|
||||||
|
|
||||||
|
$uris = array_fuse($uris);
|
||||||
|
$uris = array_values($uris);
|
||||||
|
|
||||||
|
$search_future = $this->newConduitSearch(
|
||||||
|
'diffusion.repository.search',
|
||||||
|
array(
|
||||||
|
'uris' => $uris,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'uris' => true,
|
||||||
|
));
|
||||||
|
|
||||||
|
$repository_info = (yield $this->yieldFuture($search_future));
|
||||||
|
|
||||||
|
$repository_refs = array();
|
||||||
|
foreach ($repository_info as $raw_result) {
|
||||||
|
$repository_refs[] = ArcanistRepositoryRef::newFromConduit($raw_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri_map = array();
|
||||||
|
foreach ($repository_refs as $repository_ref) {
|
||||||
|
foreach ($repository_ref->getURIs() as $repository_uri) {
|
||||||
|
$repository_uri = $api->getNormalizedURI($repository_uri);
|
||||||
|
$uri_map[$repository_uri] = $repository_ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($refs as $key => $remote) {
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
$fetch_uri = $remote->getFetchURI();
|
||||||
|
if ($fetch_uri !== null) {
|
||||||
|
$fetch_uri = $api->getNormalizedURI($fetch_uri);
|
||||||
|
if (isset($uri_map[$fetch_uri])) {
|
||||||
|
$result[] = $uri_map[$fetch_uri];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$push_uri = $remote->getPushURI();
|
||||||
|
if ($push_uri !== null) {
|
||||||
|
$push_uri = $api->getNormalizedURI($push_uri);
|
||||||
|
if (isset($uri_map[$push_uri])) {
|
||||||
|
$result[] = $uri_map[$push_uri];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[$key] = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield $this->yieldMap($results);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,8 +11,13 @@ abstract class ArcanistRepositoryRemoteQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function execute() {
|
final public function execute() {
|
||||||
|
$api = $this->getRepositoryAPI();
|
||||||
$refs = $this->newRemoteRefs();
|
$refs = $this->newRemoteRefs();
|
||||||
|
|
||||||
|
foreach ($refs as $ref) {
|
||||||
|
$ref->setRepositoryAPI($api);
|
||||||
|
}
|
||||||
|
|
||||||
$names = $this->names;
|
$names = $this->names;
|
||||||
if ($names !== null) {
|
if ($names !== null) {
|
||||||
$names = array_fuse($names);
|
$names = array_fuse($names);
|
||||||
|
|
|
@ -140,6 +140,11 @@ EOTEXT
|
||||||
|
|
||||||
$remotes = $api->newRemoteRefQuery()
|
$remotes = $api->newRemoteRefQuery()
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
$this->loadHardpoints(
|
||||||
|
$remotes,
|
||||||
|
ArcanistRemoteRef::HARDPOINT_REPOSITORYREFS);
|
||||||
|
|
||||||
foreach ($remotes as $remote) {
|
foreach ($remotes as $remote) {
|
||||||
|
|
||||||
$view = $remote->newRefView();
|
$view = $remote->newRefView();
|
||||||
|
@ -154,6 +159,18 @@ EOTEXT
|
||||||
'Push URI: %s',
|
'Push URI: %s',
|
||||||
$push_uri));
|
$push_uri));
|
||||||
|
|
||||||
|
$push_repository = $remote->getPushRepositoryRef();
|
||||||
|
if ($push_repository) {
|
||||||
|
$push_display = $push_repository->getDisplayName();
|
||||||
|
} else {
|
||||||
|
$push_display = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
$view->appendLine(
|
||||||
|
pht(
|
||||||
|
'Push Repository: %s',
|
||||||
|
$push_display));
|
||||||
|
|
||||||
$fetch_uri = $remote->getFetchURI();
|
$fetch_uri = $remote->getFetchURI();
|
||||||
if ($fetch_uri === null) {
|
if ($fetch_uri === null) {
|
||||||
$fetch_uri = '-';
|
$fetch_uri = '-';
|
||||||
|
@ -164,6 +181,18 @@ EOTEXT
|
||||||
'Fetch URI: %s',
|
'Fetch URI: %s',
|
||||||
$fetch_uri));
|
$fetch_uri));
|
||||||
|
|
||||||
|
$fetch_repository = $remote->getFetchRepositoryRef();
|
||||||
|
if ($fetch_repository) {
|
||||||
|
$fetch_display = $fetch_repository->getDisplayName();
|
||||||
|
} else {
|
||||||
|
$fetch_display = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
$view->appendLine(
|
||||||
|
pht(
|
||||||
|
'Fetch Repository: %s',
|
||||||
|
$fetch_display));
|
||||||
|
|
||||||
echo tsprintf('%s', $view);
|
echo tsprintf('%s', $view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue