mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 13:30:55 +01:00
Support ID-based repository URIs, and canonicalize repository URIs
Summary: Ref T4245. Make `/diffusion/123/` work, but redirect the user to `/diffusion/XYZ/` if the repository has a callsign. (Right now, every repository has a callsign, so this always redirects.) Also redirect `/R123:abcdef` if the repository has a callsign. Also also, move the Pull garbage collector somewhere more sensible. Test Plan: - Added test coverage. - Visited `/diffusion/1/`, was redirected. - Visited `/diffusion/R1:abcdef`, was redirected. - Browsed Diffusion normally. Reviewers: chad Reviewed By: chad Maniphest Tasks: T4245 Differential Revision: https://secure.phabricator.com/D15301
This commit is contained in:
parent
78fba426f6
commit
c2b8dd28d8
6 changed files with 113 additions and 4 deletions
|
@ -689,7 +689,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionPreCommitRefRepositoryHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefRepositoryHeraldField.php',
|
'DiffusionPreCommitRefRepositoryHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefRepositoryHeraldField.php',
|
||||||
'DiffusionPreCommitRefRepositoryProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefRepositoryProjectsHeraldField.php',
|
'DiffusionPreCommitRefRepositoryProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefRepositoryProjectsHeraldField.php',
|
||||||
'DiffusionPreCommitRefTypeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefTypeHeraldField.php',
|
'DiffusionPreCommitRefTypeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefTypeHeraldField.php',
|
||||||
'DiffusionPullEventGarbageCollector' => 'applications/diffusion/DiffusionPullEventGarbageCollector.php',
|
'DiffusionPullEventGarbageCollector' => 'applications/diffusion/garbagecollector/DiffusionPullEventGarbageCollector.php',
|
||||||
'DiffusionPushCapability' => 'applications/diffusion/capability/DiffusionPushCapability.php',
|
'DiffusionPushCapability' => 'applications/diffusion/capability/DiffusionPushCapability.php',
|
||||||
'DiffusionPushEventViewController' => 'applications/diffusion/controller/DiffusionPushEventViewController.php',
|
'DiffusionPushEventViewController' => 'applications/diffusion/controller/DiffusionPushEventViewController.php',
|
||||||
'DiffusionPushLogController' => 'applications/diffusion/controller/DiffusionPushLogController.php',
|
'DiffusionPushLogController' => 'applications/diffusion/controller/DiffusionPushLogController.php',
|
||||||
|
|
|
@ -64,7 +64,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DiffusionPushLogListController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DiffusionPushLogListController',
|
||||||
'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController',
|
'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController',
|
||||||
),
|
),
|
||||||
'(?P<repositoryCallsign>[A-Z]+)/' => array(
|
'(?:'.
|
||||||
|
'(?P<repositoryCallsign>[A-Z]+)'.
|
||||||
|
'|'.
|
||||||
|
'(?P<repositoryID>[1-9]\d*)'.
|
||||||
|
')/' => array(
|
||||||
'' => 'DiffusionRepositoryController',
|
'' => 'DiffusionRepositoryController',
|
||||||
|
|
||||||
'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController',
|
'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController',
|
||||||
|
@ -115,8 +119,9 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
||||||
// catch-all for serving repositories over HTTP. We must accept
|
// catch-all for serving repositories over HTTP. We must accept
|
||||||
// requests without the trailing "/" because SVN commands don't
|
// requests without the trailing "/" because SVN commands don't
|
||||||
// necessarily include it.
|
// necessarily include it.
|
||||||
'(?P<repositoryCallsign>[A-Z]+)(?:/.*)?' =>
|
'(?:(?P<repositoryCallsign>[A-Z]+)|(?P<repositoryID>[1-9]\d*))'.
|
||||||
'DiffusionRepositoryDefaultController',
|
'(?:/.*)?'
|
||||||
|
=> 'DiffusionRepositoryDefaultController',
|
||||||
|
|
||||||
'inline/' => array(
|
'inline/' => array(
|
||||||
'edit/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
|
'edit/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
|
||||||
|
|
|
@ -64,6 +64,20 @@ abstract class DiffusionController extends PhabricatorController {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the client is making a request like "/diffusion/1/...", but the
|
||||||
|
// repository has a different canonical path like "/diffusion/XYZ/...",
|
||||||
|
// redirect them to the canonical path.
|
||||||
|
|
||||||
|
$request_path = $request->getPath();
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
|
||||||
|
$canonical_path = $repository->getCanonicalPath($request_path);
|
||||||
|
if ($canonical_path !== null) {
|
||||||
|
if ($canonical_path != $request_path) {
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($canonical_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->diffusionRequest = $drequest;
|
$this->diffusionRequest = $drequest;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -687,6 +687,55 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
return "/r{$callsign}{$identifier}";
|
return "/r{$callsign}{$identifier}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCanonicalPath($request_path) {
|
||||||
|
$standard_pattern =
|
||||||
|
'(^'.
|
||||||
|
'(?P<prefix>/diffusion/)'.
|
||||||
|
'(?P<identifier>[^/]+)'.
|
||||||
|
'(?P<suffix>(?:/.*)?)'.
|
||||||
|
'\z)';
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
if (preg_match($standard_pattern, $request_path, $matches)) {
|
||||||
|
$prefix = $matches['prefix'];
|
||||||
|
|
||||||
|
$callsign = $this->getCallsign();
|
||||||
|
if ($callsign) {
|
||||||
|
$identifier = $callsign;
|
||||||
|
} else {
|
||||||
|
$identifier = $this->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
$suffix = $matches['suffix'];
|
||||||
|
if (!strlen($suffix)) {
|
||||||
|
$suffix = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $prefix.$identifier.$suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
$commit_pattern =
|
||||||
|
'(^'.
|
||||||
|
'(?P<prefix>/)'.
|
||||||
|
'(?P<monogram>'.
|
||||||
|
'(?:'.
|
||||||
|
'r(?P<repositoryCallsign>[A-Z]+)'.
|
||||||
|
'|'.
|
||||||
|
'R(?P<repositoryID>[1-9]\d*):'.
|
||||||
|
')'.
|
||||||
|
'(?P<commit>[a-f0-9]+)'.
|
||||||
|
')'.
|
||||||
|
'\z)';
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
if (preg_match($commit_pattern, $request_path, $matches)) {
|
||||||
|
$commit = $matches['commit'];
|
||||||
|
return $this->getCommitURI($commit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function generateURI(array $params) {
|
public function generateURI(array $params) {
|
||||||
$req_branch = false;
|
$req_branch = false;
|
||||||
$req_commit = false;
|
$req_commit = false;
|
||||||
|
|
|
@ -9,6 +9,47 @@ final class PhabricatorRepositoryURITestCase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRepositoryURICanonicalization() {
|
||||||
|
$repo = id(new PhabricatorRepository())
|
||||||
|
->makeEphemeral()
|
||||||
|
->setID(123);
|
||||||
|
|
||||||
|
$tests = array(
|
||||||
|
'/diffusion/123' => '/diffusion/123/',
|
||||||
|
'/diffusion/123/' => '/diffusion/123/',
|
||||||
|
'/diffusion/123/browse/master/' => '/diffusion/123/browse/master/',
|
||||||
|
'/kangaroo/' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($tests as $input => $expect) {
|
||||||
|
$this->assertEqual(
|
||||||
|
$expect,
|
||||||
|
$repo->getCanonicalPath($input),
|
||||||
|
pht('Canonical Path (ID, No Callsign): %s', $input));
|
||||||
|
}
|
||||||
|
|
||||||
|
$repo->setCallsign('XYZ');
|
||||||
|
|
||||||
|
$tests = array(
|
||||||
|
'/diffusion/123' => '/diffusion/XYZ/',
|
||||||
|
'/diffusion/123/' => '/diffusion/XYZ/',
|
||||||
|
'/diffusion/123/browse/master/' => '/diffusion/XYZ/browse/master/',
|
||||||
|
'/diffusion/XYZ' => '/diffusion/XYZ/',
|
||||||
|
'/diffusion/XYZ/' => '/diffusion/XYZ/',
|
||||||
|
'/diffusion/XYZ/browse/master/' => '/diffusion/XYZ/browse/master/',
|
||||||
|
'/diffusion/ABC/' => '/diffusion/XYZ/',
|
||||||
|
'/kangaroo/' => null,
|
||||||
|
'/R1:abcdef' => '/rXYZabcdef',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($tests as $input => $expect) {
|
||||||
|
$this->assertEqual(
|
||||||
|
$expect,
|
||||||
|
$repo->getCanonicalPath($input),
|
||||||
|
pht('Canonical Path (ID, Callsign): %s', $input));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testURIGeneration() {
|
public function testURIGeneration() {
|
||||||
$svn = PhabricatorRepositoryType::REPOSITORY_TYPE_SVN;
|
$svn = PhabricatorRepositoryType::REPOSITORY_TYPE_SVN;
|
||||||
$git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
$git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
||||||
|
|
Loading…
Reference in a new issue