@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.

Verify that SVN repository roots really are repository roots

Summary: Fixes T3238. Ref T4327. Although the instructions are fairly clear on this, it's easy to miss them. Make sure the root the user enters matches the real root.

Test Plan: Added unit tests. Used `bin/repository discover` to hit the check explicitly.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3238, T4327

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

+134 -5
+4 -2
src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
··· 473 473 "| `svn://svn.example.net/svnroot/` |\n". 474 474 "| `file:///local/path/to/svnroot/` |\n". 475 475 "\n\n". 476 - "Make sure you specify the root of the repository, not a ". 477 - "subdirectory."); 476 + "You **MUST** specify the root of the repository, not a ". 477 + "subdirectory. (If you want to import only part of a Subversion ". 478 + "repository, use the //Import Only// option at the end of this ". 479 + "workflow.)"); 478 480 } else { 479 481 throw new Exception("Unsupported VCS!"); 480 482 }
+12
src/applications/repository/data/PhabricatorRepositoryURINormalizer.php
··· 39 39 final class PhabricatorRepositoryURINormalizer extends Phobject { 40 40 41 41 const TYPE_GIT = 'git'; 42 + const TYPE_SVN = 'svn'; 43 + 42 44 private $type; 43 45 private $uri; 44 46 45 47 public function __construct($type, $uri) { 46 48 switch ($type) { 47 49 case self::TYPE_GIT: 50 + case self::TYPE_SVN: 48 51 break; 49 52 default: 50 53 throw new Exception(pht('Unknown URI type "%s"!')); ··· 75 78 } 76 79 77 80 return $this->uri; 81 + case self::TYPE_SVN: 82 + $uri = new PhutilURI($this->uri); 83 + if ($uri->getProtocol()) { 84 + return $uri->getPath(); 85 + } 86 + 87 + return $this->uri; 78 88 } 79 89 } 80 90 ··· 89 99 switch ($this->type) { 90 100 case self::TYPE_GIT: 91 101 $path = preg_replace('/\.git$/', '', $path); 102 + break; 103 + case self::TYPE_SVN: 92 104 break; 93 105 } 94 106
+19 -1
src/applications/repository/data/__tests__/PhabricatorRepositoryURINormalizerTestCase.php
··· 25 25 $this->assertEqual( 26 26 $expect, 27 27 $normal->getNormalizedPath(), 28 - pht('Normalized path for "%s".', $input)); 28 + pht('Normalized Git path for "%s".', $input)); 29 29 } 30 30 } 31 + 32 + public function testSVNURINormalizer() { 33 + $cases = array( 34 + 'file:///path/to/repo' => 'path/to/repo', 35 + 'file:///path/to/repo/' => 'path/to/repo', 36 + ); 37 + 38 + $type_svn = PhabricatorRepositoryURINormalizer::TYPE_SVN; 39 + 40 + foreach ($cases as $input => $expect) { 41 + $normal = new PhabricatorRepositoryURINormalizer($type_svn, $input); 42 + $this->assertEqual( 43 + $expect, 44 + $normal->getNormalizedPath(), 45 + pht('Normalized SVN path for "%s".', $input)); 46 + } 47 + } 48 + 31 49 }
+41
src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
··· 225 225 private function discoverSubversionCommits() { 226 226 $repository = $this->getRepository(); 227 227 228 + if (!$repository->isHosted()) { 229 + $this->verifySubversionRoot($repository); 230 + } 231 + 228 232 $upper_bound = null; 229 233 $limit = 1; 230 234 $refs = array(); ··· 286 290 $refs = array_reverse($refs); 287 291 288 292 return $refs; 293 + } 294 + 295 + 296 + private function verifySubversionRoot(PhabricatorRepository $repository) { 297 + list($xml) = $repository->execxRemoteCommand( 298 + 'info --xml %s', 299 + $repository->getSubversionPathURI()); 300 + 301 + $xml = phutil_utf8ize($xml); 302 + $xml = new SimpleXMLElement($xml); 303 + 304 + $remote_root = (string)($xml->entry[0]->repository[0]->root[0]); 305 + $expect_root = $repository->getSubversionPathURI(); 306 + 307 + $normal_type_svn = PhabricatorRepositoryURINormalizer::TYPE_SVN; 308 + 309 + $remote_normal = id(new PhabricatorRepositoryURINormalizer( 310 + $normal_type_svn, 311 + $remote_root))->getNormalizedPath(); 312 + 313 + $expect_normal = id(new PhabricatorRepositoryURINormalizer( 314 + $normal_type_svn, 315 + $expect_root))->getNormalizedPath(); 316 + 317 + if ($remote_normal != $expect_normal) { 318 + throw new Exception( 319 + pht( 320 + 'Repository "%s" does not have a correctly configured remote URI. '. 321 + 'The remote URI for a Subversion repository MUST point at the '. 322 + 'repository root. The root for this repository is "%s", but the '. 323 + 'configured URI is "%s". To resolve this error, set the remote URI '. 324 + 'to point at the repository root. If you want to import only part '. 325 + 'of a Subversion repository, use the "Import Only" option.', 326 + $repository->getCallsign(), 327 + $remote_root, 328 + $expect_root)); 329 + } 289 330 } 290 331 291 332
+9 -1
src/applications/repository/engine/__tests__/PhabricatorWorkingCopyTestCase.php
··· 11 11 } 12 12 13 13 protected function buildBareRepository($callsign) { 14 + $existing_repository = id(new PhabricatorRepositoryQuery()) 15 + ->withCallsigns(array($callsign)) 16 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 17 + ->executeOne(); 18 + if ($existing_repository) { 19 + $existing_repository->delete(); 20 + } 21 + 14 22 $data_dir = dirname(__FILE__).'/data/'; 15 23 16 24 $types = array( ··· 84 92 85 93 id(new PhabricatorRepositoryDiscoveryEngine()) 86 94 ->setRepository($repository) 87 - ->discoverCommits($repository); 95 + ->discoverCommits(); 88 96 89 97 return $repository; 90 98 }
+49 -1
src/applications/repository/worker/__tests__/PhabricatorChangeParserTestCase.php
··· 962 962 963 963 id(new PhabricatorRepositoryDiscoveryEngine()) 964 964 ->setRepository($repository) 965 - ->discoverCommits($repository); 965 + ->discoverCommits(); 966 966 967 967 $viewer = PhabricatorUser::getOmnipotentUser(); 968 968 ··· 1055 1055 ), 1056 1056 )); 1057 1057 } 1058 + 1059 + public function testSubversionValidRootParser() { 1060 + // First, automatically configure the root correctly. 1061 + $repository = $this->buildBareRepository('CHD'); 1062 + id(new PhabricatorRepositoryPullEngine()) 1063 + ->setRepository($repository) 1064 + ->pullRepository(); 1065 + 1066 + $caught = null; 1067 + try { 1068 + id(new PhabricatorRepositoryDiscoveryEngine()) 1069 + ->setRepository($repository) 1070 + ->discoverCommits(); 1071 + } catch (Exception $ex) { 1072 + $caught = $ex; 1073 + } 1074 + 1075 + $this->assertEqual( 1076 + false, 1077 + ($caught instanceof Exception), 1078 + pht('Natural SVN root should work properly.')); 1079 + 1080 + 1081 + // This time, artificially break the root. We expect this to fail. 1082 + $repository = $this->buildBareRepository('CHD'); 1083 + $repository->setDetail( 1084 + 'remote-uri', 1085 + $repository->getDetail('remote-uri').'trunk/'); 1086 + 1087 + id(new PhabricatorRepositoryPullEngine()) 1088 + ->setRepository($repository) 1089 + ->pullRepository(); 1090 + 1091 + $caught = null; 1092 + try { 1093 + id(new PhabricatorRepositoryDiscoveryEngine()) 1094 + ->setRepository($repository) 1095 + ->discoverCommits(); 1096 + } catch (Exception $ex) { 1097 + $caught = $ex; 1098 + } 1099 + 1100 + $this->assertEqual( 1101 + true, 1102 + ($caught instanceof Exception), 1103 + pht('Artificial SVN root should fail.')); 1104 + } 1105 + 1058 1106 1059 1107 private function expectChanges( 1060 1108 PhabricatorRepository $repository,