1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-20 20:40:56 +01:00

Allow repository lookup by remote URI

Summary: This helps us move away from arcanist projects in normal use, by allowing us to identify repositories based on the remote URI.

Test Plan: Used `repository.query` to query some repos by remote URI.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Differential Revision: https://secure.phabricator.com/D8069
This commit is contained in:
epriestley 2014-01-25 14:02:38 -08:00
parent ce45c57057
commit e34a44a7ed
4 changed files with 77 additions and 0 deletions

View file

@ -21,6 +21,7 @@ final class ConduitAPI_repository_query_Method
'phids' => 'optional list<phid>',
'callsigns' => 'optional list<string>',
'vcsTypes' => 'optional list<string>',
'remoteURIs' => 'optional list<string>',
);
}
@ -57,6 +58,11 @@ final class ConduitAPI_repository_query_Method
$query->withTypes($vcs_types);
}
$remote_uris = $request->getValue('remoteURIs', array());
if ($remote_uris) {
$query->withRemoteURIs($remote_uris);
}
$repositories = $query->execute();
$results = array();

View file

@ -40,6 +40,7 @@ final class PhabricatorRepositoryURINormalizer extends Phobject {
const TYPE_GIT = 'git';
const TYPE_SVN = 'svn';
const TYPE_MERCURIAL = 'hg';
private $type;
private $uri;
@ -48,6 +49,7 @@ final class PhabricatorRepositoryURINormalizer extends Phobject {
switch ($type) {
case self::TYPE_GIT:
case self::TYPE_SVN:
case self::TYPE_MERCURIAL:
break;
default:
throw new Exception(pht('Unknown URI type "%s"!'));
@ -79,6 +81,7 @@ final class PhabricatorRepositoryURINormalizer extends Phobject {
return $this->uri;
case self::TYPE_SVN:
case self::TYPE_MERCURIAL:
$uri = new PhutilURI($this->uri);
if ($uri->getProtocol()) {
return $uri->getPath();
@ -101,6 +104,7 @@ final class PhabricatorRepositoryURINormalizer extends Phobject {
$path = preg_replace('/\.git$/', '', $path);
break;
case self::TYPE_SVN:
case self::TYPE_MERCURIAL:
break;
}

View file

@ -9,6 +9,7 @@ final class PhabricatorRepositoryQuery
private $types;
private $uuids;
private $nameContains;
private $remoteURIs;
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
@ -70,6 +71,11 @@ final class PhabricatorRepositoryQuery
return $this;
}
public function withRemoteURIs(array $uris) {
$this->remoteURIs = $uris;
return $this;
}
public function needCommitCounts($need_counts) {
$this->needCommitCounts = $need_counts;
return $this;
@ -90,6 +96,7 @@ final class PhabricatorRepositoryQuery
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepository();
$conn_r = $table->establishConnection('r');
@ -159,6 +166,7 @@ final class PhabricatorRepositoryQuery
throw new Exception("Unknown status '{$status}'!");
}
// TODO: This should also be denormalized.
$hosted = $this->hosted;
switch ($hosted) {
case self::HOSTED_PHABRICATOR:
@ -178,6 +186,17 @@ final class PhabricatorRepositoryQuery
}
}
// TODO: Denormalize this, too.
if ($this->remoteURIs) {
$try_uris = $this->getNormalizedPaths();
$try_uris = array_fuse($try_uris);
foreach ($repositories as $key => $repository) {
if (!isset($try_uris[$repository->getNormalizedPath()])) {
unset($repositories[$key]);
}
}
}
return $repositories;
}
@ -389,4 +408,28 @@ final class PhabricatorRepositoryQuery
return 'PhabricatorApplicationDiffusion';
}
private function getNormalizedPaths() {
$normalized_uris = array();
// Since we don't know which type of repository this URI is in the general
// case, just generate all the normalizations. We could refine this in some
// cases: if the query specifies VCS types, or the URI is a git-style URI
// or an `svn+ssh` URI, we could deduce how to normalize it. However, this
// would be more complicated and it's not clear if it matters in practice.
foreach ($this->remoteURIs as $uri) {
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_GIT,
$uri);
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_SVN,
$uri);
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_MERCURIAL,
$uri);
}
return array_unique(mpull($normalized_uris, 'getNormalizedPath'));
}
}

View file

@ -485,6 +485,30 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
return '/diffusion/'.$this->getCallsign().'/';
}
public function getNormalizedPath() {
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$normalized_uri = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_GIT,
$this->getURI());
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$normalized_uri = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_SVN,
$this->getURI());
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$normalized_uri = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_MERCURIAL,
$this->getURI());
break;
default:
throw new Exception("Unrecognized version control system.");
}
return $normalized_uri->getNormalizedPath();
}
public function isTracked() {
return $this->getDetail('tracking-enabled', false);
}