@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

Make repository callsigns optional

Summary:
Ref T4245. This could still use a little UI smoothing, but:

- Don't require a callsign on the create flow (you can add one later in "Edit Basic Information" if you want).
- Allow existing callsigns to be removed.

Test Plan:
- Created a new repository with no callsign.
- Cloned it; pushed to it.
- Browsed around Diffusion a bunch.
- Visited a commit URI.
- Added a callsign to it.
- Removed the callsign again.
- Referenced it with `R22` in remarkup.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4245

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

+46 -67
+4
resources/sql/autopatches/20160218.callsigns.1.sql
··· 1 + /* Make callsigns nullable, and thus optional. */ 2 + 3 + ALTER TABLE {$NAMESPACE}_repository.repository 4 + CHANGE callsign callsign VARCHAR(32) COLLATE {$COLLATE_SORT};
+3 -58
src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
··· 149 149 150 150 // If we're creating a new repository, set all this core stuff. 151 151 if ($is_create) { 152 - $callsign = $form->getPage('name') 153 - ->getControl('callsign')->getValue(); 154 - 155 - // We must set this to a unique value to save the repository 156 - // initially, and it's immutable, so we don't bother using 157 - // transactions to apply this change. 158 - $repository->setCallsign($callsign); 159 - 160 152 $xactions[] = id(clone $template) 161 153 ->setTransactionType($type_name) 162 154 ->setNewValue( ··· 343 335 } 344 336 345 337 346 - /* -( Page: Name and Callsign )-------------------------------------------- */ 338 + /* -( Page: Name )--------------------------------------------------------- */ 347 339 348 340 349 341 private function buildNamePage() { ··· 359 351 ->addControl( 360 352 id(new AphrontFormTextControl()) 361 353 ->setName('name') 362 - ->setLabel(pht('Name')) 363 - ->setCaption(pht('Human-readable repository name.'))) 364 - ->addRemarkupInstructions( 365 - pht( 366 - '**Choose a "Callsign" for the repository.** This is a short, '. 367 - 'unique string which identifies commits elsewhere in Phabricator. '. 368 - 'For example, you might use `M` for your mobile app repository '. 369 - 'and `B` for your backend repository.'. 370 - "\n\n". 371 - '**Callsigns must be UPPERCASE**, and can not be edited after the '. 372 - 'repository is created. Generally, you should choose short '. 373 - 'callsigns.')) 374 - ->addControl( 375 - id(new AphrontFormTextControl()) 376 - ->setName('callsign') 377 - ->setLabel(pht('Callsign')) 378 - ->setCaption(pht('Short UPPERCASE identifier.'))); 354 + ->setLabel(pht('Name'))); 379 355 } 380 356 381 357 public function validateNamePage(PHUIFormPageView $page) { ··· 387 363 pht('You must choose a name for this repository.')); 388 364 } 389 365 390 - $c_call = $page->getControl('callsign'); 391 - $v_call = $c_call->getValue(); 392 - if (!strlen($v_call)) { 393 - $c_call->setError(pht('Required')); 394 - $page->addPageError( 395 - pht('You must choose a callsign for this repository.')); 396 - } else if (!preg_match('/^[A-Z]+\z/', $v_call)) { 397 - $c_call->setError(pht('Invalid')); 398 - $page->addPageError( 399 - pht('The callsign must contain only UPPERCASE letters.')); 400 - } else { 401 - $exists = false; 402 - try { 403 - $repo = id(new PhabricatorRepositoryQuery()) 404 - ->setViewer($this->getRequest()->getUser()) 405 - ->withCallsigns(array($v_call)) 406 - ->executeOne(); 407 - $exists = (bool)$repo; 408 - } catch (PhabricatorPolicyException $ex) { 409 - $exists = true; 410 - } 411 - if ($exists) { 412 - $c_call->setError(pht('Not Unique')); 413 - $page->addPageError( 414 - pht( 415 - 'Another repository already uses that callsign. You must choose '. 416 - 'a unique callsign.')); 417 - } 418 - } 419 - 420 - return $c_name->isValid() && 421 - $c_call->isValid(); 366 + return $c_name->isValid(); 422 367 } 423 368 424 369
+6 -1
src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
··· 284 284 $repository->getVersionControlSystem()); 285 285 286 286 $view->addProperty(pht('Type'), $type); 287 - $view->addProperty(pht('Callsign'), $repository->getCallsign()); 287 + 288 + $callsign = $repository->getCallsign(); 289 + if (!strlen($callsign)) { 290 + $callsign = phutil_tag('em', array(), pht('No Callsign')); 291 + } 292 + $view->addProperty(pht('Callsign'), $callsign); 288 293 289 294 $short_name = $repository->getRepositorySlug(); 290 295 if ($short_name === null) {
+33 -8
src/applications/repository/storage/PhabricatorRepository.php
··· 93 93 ), 94 94 self::CONFIG_COLUMN_SCHEMA => array( 95 95 'name' => 'sort255', 96 - 'callsign' => 'sort32', 96 + 'callsign' => 'sort32?', 97 97 'repositorySlug' => 'sort64?', 98 98 'versionControlSystem' => 'text32', 99 99 'uuid' => 'text64?', ··· 149 149 } 150 150 151 151 public function getMonogram() { 152 - return 'r'.$this->getCallsign(); 152 + $callsign = $this->getCallsign(); 153 + if (strlen($callsign)) { 154 + return "r{$callsign}"; 155 + } 156 + 157 + $id = $this->getID(); 158 + return "R{$id}"; 153 159 } 154 160 155 161 public function getDisplayName() { 156 - // TODO: This is intended to produce a human-readable name that is not 157 - // necessarily a global, unique identifier. Eventually, it may just return 158 - // a string like "skynet" instead of "rSKYNET". 162 + $slug = $this->getRepositorySlug(); 163 + if (strlen($slug)) { 164 + return $slug; 165 + } 166 + 159 167 return $this->getMonogram(); 160 168 } 161 169 ··· 699 707 } 700 708 701 709 public function getURI() { 702 - return '/diffusion/'.$this->getCallsign().'/'; 710 + $callsign = $this->getCallsign(); 711 + if (strlen($callsign)) { 712 + return "/diffusion/{$callsign}/"; 713 + } 714 + 715 + $id = $this->getID(); 716 + return "/diffusion/{$id}/"; 703 717 } 704 718 705 719 public function getPathURI($path) { ··· 708 722 709 723 public function getCommitURI($identifier) { 710 724 $callsign = $this->getCallsign(); 711 - return "/r{$callsign}{$identifier}"; 725 + if (strlen($callsign)) { 726 + return "/r{$callsign}{$identifier}"; 727 + } 728 + 729 + $id = $this->getID(); 730 + return "/R{$id}:{$identifier}"; 712 731 } 713 732 714 733 public static function parseRepositoryServicePath($request_path) { ··· 1063 1082 } 1064 1083 1065 1084 if ($need_scope) { 1066 - $scope = 'r'.$this->getCallsign(); 1085 + $callsign = $this->getCallsign(); 1086 + if ($callsign) { 1087 + $scope = "r{$callsign}"; 1088 + } else { 1089 + $id = $this->getID(); 1090 + $scope = "R{$id}:"; 1091 + } 1067 1092 $name = $scope.$name; 1068 1093 } 1069 1094