@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Support slightly prettier repository URIs in Diffusion

Summary: Fixes T4245. When a repository has a short name, use `/source/shortname/` as its primary URI.

Test Plan:
- Cloned Git repositories from shortnames via HTTP and SSH.
- Cloned Mercurial repositories from shortnames via HTTP and SSH.
- Cloned Subversion repositories from shortnames via SSH.
- Browsed Git, Mercurial and Subversion repositories.
- Added and removed short names to various repositories.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4245

Differential Revision: https://secure.phabricator.com/D16851

+110 -100
+52 -51
src/applications/diffusion/application/PhabricatorDiffusionApplication.php
··· 46 46 } 47 47 48 48 public function getRoutes() { 49 + $repository_routes = array( 50 + '/' => array( 51 + '' => 'DiffusionRepositoryController', 52 + 'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController', 53 + 'change/(?P<dblob>.*)' => 'DiffusionChangeController', 54 + 'history/(?P<dblob>.*)' => 'DiffusionHistoryController', 55 + 'browse/(?P<dblob>.*)' => 'DiffusionBrowseController', 56 + 'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController', 57 + 'diff/' => 'DiffusionDiffController', 58 + 'tags/(?P<dblob>.*)' => 'DiffusionTagListController', 59 + 'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController', 60 + 'refs/(?P<dblob>.*)' => 'DiffusionRefTableController', 61 + 'lint/(?P<dblob>.*)' => 'DiffusionLintController', 62 + 'commit/(?P<commit>[a-z0-9]+)/branches/' 63 + => 'DiffusionCommitBranchesController', 64 + 'commit/(?P<commit>[a-z0-9]+)/tags/' 65 + => 'DiffusionCommitTagsController', 66 + 'commit/(?P<commit>[a-z0-9]+)/edit/' 67 + => 'DiffusionCommitEditController', 68 + 'manage/(?:(?P<panel>[^/]+)/)?' 69 + => 'DiffusionRepositoryManagePanelsController', 70 + 'uri/' => array( 71 + 'view/(?P<id>[0-9]\d*)/' => 'DiffusionRepositoryURIViewController', 72 + 'disable/(?P<id>[0-9]\d*)/' 73 + => 'DiffusionRepositoryURIDisableController', 74 + $this->getEditRoutePattern('edit/') 75 + => 'DiffusionRepositoryURIEditController', 76 + 'credential/(?P<id>[0-9]\d*)/(?P<action>edit|remove)/' 77 + => 'DiffusionRepositoryURICredentialController', 78 + ), 79 + 'edit/' => array( 80 + 'activate/' => 'DiffusionRepositoryEditActivateController', 81 + 'dangerous/' => 'DiffusionRepositoryEditDangerousController', 82 + 'delete/' => 'DiffusionRepositoryEditDeleteController', 83 + 'update/' => 'DiffusionRepositoryEditUpdateController', 84 + 'testautomation/' => 'DiffusionRepositoryTestAutomationController', 85 + ), 86 + 'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController', 87 + ), 88 + 89 + // NOTE: This must come after the rules above; it just gives us a 90 + // catch-all for serving repositories over HTTP. We must accept requests 91 + // without the trailing "/" because SVN commands don't necessarily 92 + // include it. 93 + '(?:/.*)?' => 'DiffusionRepositoryDefaultController', 94 + ); 95 + 49 96 return array( 50 97 '/(?:'. 51 98 'r(?P<repositoryCallsign>[A-Z]+)'. ··· 54 101 ')(?P<commit>[a-f0-9]+)' 55 102 => 'DiffusionCommitController', 56 103 104 + '/source/(?P<repositoryShortName>[^/.]+)(?P<dotgit>\.git)?' 105 + => $repository_routes, 106 + 57 107 '/diffusion/' => array( 58 108 $this->getQueryRoutePattern() 59 109 => 'DiffusionRepositoryListController', ··· 63 113 '(?:query/(?P<queryKey>[^/]+)/)?' => 'DiffusionPushLogListController', 64 114 'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController', 65 115 ), 66 - '(?:'. 67 - '(?P<repositoryCallsign>[A-Z]+)'. 68 - '|'. 69 - '(?P<repositoryID>[1-9]\d*)'. 70 - ')/' => array( 71 - '' => 'DiffusionRepositoryController', 72 - 73 - 'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController', 74 - 'change/(?P<dblob>.*)' => 'DiffusionChangeController', 75 - 'history/(?P<dblob>.*)' => 'DiffusionHistoryController', 76 - 'browse/(?P<dblob>.*)' => 'DiffusionBrowseController', 77 - 'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController', 78 - 'diff/' => 'DiffusionDiffController', 79 - 'tags/(?P<dblob>.*)' => 'DiffusionTagListController', 80 - 'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController', 81 - 'refs/(?P<dblob>.*)' => 'DiffusionRefTableController', 82 - 'lint/(?P<dblob>.*)' => 'DiffusionLintController', 83 - 'commit/(?P<commit>[a-z0-9]+)/branches/' 84 - => 'DiffusionCommitBranchesController', 85 - 'commit/(?P<commit>[a-z0-9]+)/tags/' 86 - => 'DiffusionCommitTagsController', 87 - 'commit/(?P<commit>[a-z0-9]+)/edit/' 88 - => 'DiffusionCommitEditController', 89 - 'manage/(?:(?P<panel>[^/]+)/)?' 90 - => 'DiffusionRepositoryManagePanelsController', 91 - 'uri/' => array( 92 - 'view/(?P<id>[0-9]\d*)/' => 'DiffusionRepositoryURIViewController', 93 - 'disable/(?P<id>[0-9]\d*)/' 94 - => 'DiffusionRepositoryURIDisableController', 95 - $this->getEditRoutePattern('edit/') 96 - => 'DiffusionRepositoryURIEditController', 97 - 'credential/(?P<id>[0-9]\d*)/(?P<action>edit|remove)/' 98 - => 'DiffusionRepositoryURICredentialController', 99 - ), 100 - 'edit/' => array( 101 - 'activate/' => 'DiffusionRepositoryEditActivateController', 102 - 'dangerous/' => 'DiffusionRepositoryEditDangerousController', 103 - 'delete/' => 'DiffusionRepositoryEditDeleteController', 104 - 'update/' => 'DiffusionRepositoryEditUpdateController', 105 - 'testautomation/' => 'DiffusionRepositoryTestAutomationController', 106 - ), 107 - 'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController', 108 - ), 109 - 110 - // NOTE: This must come after the rule above; it just gives us a 111 - // catch-all for serving repositories over HTTP. We must accept 112 - // requests without the trailing "/" because SVN commands don't 113 - // necessarily include it. 114 - '(?:(?P<repositoryCallsign>[A-Z]+)|(?P<repositoryID>[1-9]\d*))'. 115 - '(?:/.*)?' 116 - => 'DiffusionRepositoryDefaultController', 116 + '(?P<repositoryCallsign>[A-Z]+)' => $repository_routes, 117 + '(?P<repositoryID>[1-9]\d*)' => $repository_routes, 117 118 118 119 'inline/' => array( 119 120 'edit/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
+5
src/applications/diffusion/controller/DiffusionController.php
··· 90 90 protected function getRepositoryIdentifierFromRequest( 91 91 AphrontRequest $request) { 92 92 93 + $short_name = $request->getURIData('repositoryShortName'); 94 + if (strlen($short_name)) { 95 + return $short_name; 96 + } 97 + 93 98 $identifier = $request->getURIData('repositoryCallsign'); 94 99 if (strlen($identifier)) { 95 100 return $identifier;
+1
src/applications/diffusion/controller/DiffusionLastModifiedController.php
··· 16 16 $drequest = $this->getDiffusionRequest(); 17 17 18 18 $paths = $request->getStr('paths'); 19 + 19 20 try { 20 21 $paths = phutil_json_decode($paths); 21 22 } catch (PhutilJSONParserException $ex) {
+10 -1
src/applications/diffusion/controller/DiffusionServeController.php
··· 88 88 } 89 89 } 90 90 91 + // If the request was for a path like "/source/libphutil.git" but the 92 + // repository is not a Git repository, reject the request. 93 + $type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT; 94 + if ($request->getURIData('dotgit') && ($vcs !== $type_git)) { 95 + return null; 96 + } 97 + 91 98 return $vcs; 92 99 } 93 100 ··· 607 614 $request = $this->getRequest(); 608 615 $request_path = $request->getRequestURI()->getPath(); 609 616 610 - $info = PhabricatorRepository::parseRepositoryServicePath($request_path); 617 + $info = PhabricatorRepository::parseRepositoryServicePath( 618 + $request_path, 619 + $repository->getVersionControlSystem()); 611 620 $base_path = $info['path']; 612 621 613 622 // For Git repositories, strip an optional directory component if it
+3 -1
src/applications/diffusion/gitlfs/DiffusionGitLFSAuthenticateWorkflow.php
··· 15 15 } 16 16 17 17 protected function identifyRepository() { 18 - return $this->loadRepositoryWithPath($this->getLFSPathArgument()); 18 + return $this->loadRepositoryWithPath( 19 + $this->getLFSPathArgument(), 20 + PhabricatorRepositoryType::REPOSITORY_TYPE_GIT); 19 21 } 20 22 21 23 private function getLFSPathArgument() {
+3 -1
src/applications/diffusion/ssh/DiffusionGitSSHWorkflow.php
··· 17 17 protected function identifyRepository() { 18 18 $args = $this->getArgs(); 19 19 $path = head($args->getArg('dir')); 20 - return $this->loadRepositoryWithPath($path); 20 + return $this->loadRepositoryWithPath( 21 + $path, 22 + PhabricatorRepositoryType::REPOSITORY_TYPE_GIT); 21 23 } 22 24 23 25 protected function waitForGitClient() {
+3 -1
src/applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php
··· 27 27 protected function identifyRepository() { 28 28 $args = $this->getArgs(); 29 29 $path = $args->getArg('repository'); 30 - return $this->loadRepositoryWithPath($path); 30 + return $this->loadRepositoryWithPath( 31 + $path, 32 + PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL); 31 33 } 32 34 33 35 protected function executeRepositoryOperations() {
+6 -5
src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
··· 161 161 } 162 162 } 163 163 164 - protected function loadRepositoryWithPath($path) { 164 + protected function loadRepositoryWithPath($path, $vcs) { 165 165 $viewer = $this->getUser(); 166 166 167 - $info = PhabricatorRepository::parseRepositoryServicePath($path); 167 + $info = PhabricatorRepository::parseRepositoryServicePath($path, $vcs); 168 168 if ($info === null) { 169 169 throw new Exception( 170 170 pht( 171 - 'Unrecognized repository path "%s". Expected a path like "%s" '. 172 - 'or "%s".', 171 + 'Unrecognized repository path "%s". Expected a path like "%s", '. 172 + '"%s", or "%s".', 173 173 $path, 174 174 '/diffusion/X/', 175 - '/diffusion/123/')); 175 + '/diffusion/123/', 176 + '/source/thaumaturgy.git')); 176 177 } 177 178 178 179 $identifier = $info['identifier'];
+3 -1
src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php
··· 117 117 $uri = $struct[2]['value']; 118 118 $path = $this->getPathFromSubversionURI($uri); 119 119 120 - return $this->loadRepositoryWithPath($path); 120 + return $this->loadRepositoryWithPath( 121 + $path, 122 + PhabricatorRepositoryType::REPOSITORY_TYPE_SVN); 121 123 } 122 124 } 123 125
+22 -37
src/applications/repository/storage/PhabricatorRepository.php
··· 563 563 } 564 564 565 565 public function getURI() { 566 + $short_name = $this->getRepositorySlug(); 567 + if (strlen($short_name)) { 568 + return "/source/{$short_name}/"; 569 + } 570 + 566 571 $callsign = $this->getCallsign(); 567 572 if (strlen($callsign)) { 568 573 return "/diffusion/{$callsign}/"; ··· 573 578 } 574 579 575 580 public function getPathURI($path) { 576 - return $this->getURI().$path; 581 + return $this->getURI().ltrim($path, '/'); 577 582 } 578 583 579 584 public function getCommitURI($identifier) { ··· 586 591 return "/R{$id}:{$identifier}"; 587 592 } 588 593 589 - public static function parseRepositoryServicePath($request_path) { 594 + public static function parseRepositoryServicePath($request_path, $vcs) { 595 + 590 596 // NOTE: In Mercurial over SSH, the path will begin without a leading "/", 591 597 // so we're matching it optionally. 592 598 599 + if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) { 600 + $maybe_git = '(?:\\.git)?'; 601 + } else { 602 + $maybe_git = null; 603 + } 604 + 593 605 $patterns = array( 594 606 '(^'. 595 - '(?P<base>/?diffusion/(?P<identifier>[A-Z]+|[0-9]\d*))'. 596 - '(?P<path>(?:/.*)?)'. 607 + '(?P<base>/?(?:diffusion|source)/(?P<identifier>[^/.]+))'. 608 + $maybe_git. 609 + '(?P<path>(?:/|.*)?)'. 597 610 '\z)', 598 611 ); 599 612 ··· 624 637 public function getCanonicalPath($request_path) { 625 638 $standard_pattern = 626 639 '(^'. 627 - '(?P<prefix>/diffusion/)'. 640 + '(?P<prefix>/(?:diffusion|source)/)'. 628 641 '(?P<identifier>[^/]+)'. 629 642 '(?P<suffix>(?:/.*)?)'. 630 643 '\z)'; 631 644 632 645 $matches = null; 633 646 if (preg_match($standard_pattern, $request_path, $matches)) { 634 - $prefix = $matches['prefix']; 635 - 636 - $callsign = $this->getCallsign(); 637 - if ($callsign) { 638 - $identifier = $callsign; 639 - } else { 640 - $identifier = $this->getID(); 641 - } 642 - 643 647 $suffix = $matches['suffix']; 644 - if (!strlen($suffix)) { 645 - $suffix = '/'; 646 - } 647 - 648 - return $prefix.$identifier.$suffix; 648 + return $this->getPathURI($suffix); 649 649 } 650 650 651 651 $commit_pattern = ··· 724 724 return $this->getCommitURI($commit); 725 725 } 726 726 727 - 728 - $identifier = $this->getID(); 729 - 730 - $callsign = $this->getCallsign(); 731 - if ($callsign !== null) { 732 - $identifier = $callsign; 733 - } 734 - 735 - if (strlen($identifier)) { 736 - $identifier = phutil_escape_uri_path_component($identifier); 737 - } 738 - 739 727 if (strlen($path)) { 740 728 $path = ltrim($path, '/'); 741 729 $path = str_replace(array(';', '$'), array(';;', '$$'), $path); ··· 766 754 case 'lint': 767 755 case 'pathtree': 768 756 case 'refs': 769 - $uri = "/diffusion/{$identifier}/{$action}/{$path}{$commit}{$line}"; 757 + $uri = $this->getPathURI("/{$action}/{$path}{$commit}{$line}"); 770 758 break; 771 759 case 'branch': 772 760 if (strlen($path)) { 773 - $uri = "/diffusion/{$identifier}/repository/{$path}"; 761 + $uri = $this->getPathURI("/repository/{$path}"); 774 762 } else { 775 - $uri = "/diffusion/{$identifier}/"; 763 + $uri = $this->getPathURI(); 776 764 } 777 765 break; 778 766 case 'external': ··· 2107 2095 public function newBuiltinURIs() { 2108 2096 $has_callsign = ($this->getCallsign() !== null); 2109 2097 $has_shortname = ($this->getRepositorySlug() !== null); 2110 - 2111 - // TODO: For now, never enable these because they don't work yet. 2112 - $has_shortname = false; 2113 2098 2114 2099 $identifier_map = array( 2115 2100 PhabricatorRepositoryURI::BUILTIN_IDENTIFIER_CALLSIGN => $has_callsign,
+2 -2
src/applications/repository/storage/PhabricatorRepositoryURI.php
··· 125 125 $other_uris = $repository->getURIs(); 126 126 127 127 $identifier_value = array( 128 - self::BUILTIN_IDENTIFIER_CALLSIGN => 3, 129 - self::BUILTIN_IDENTIFIER_SHORTNAME => 2, 128 + self::BUILTIN_IDENTIFIER_SHORTNAME => 3, 129 + self::BUILTIN_IDENTIFIER_CALLSIGN => 2, 130 130 self::BUILTIN_IDENTIFIER_ID => 1, 131 131 ); 132 132