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

Add "Clone As" to repositories and generate full clone commands in UI

Summary:
Ref T4175.

- Add a configurable name for the clone-as directory, so you can have "Bits & Pieces" clone as "bits~n~pieces/" or simliar.
- By default, use "reasonable" heruistics to choose such a name.
- Generate a copy/pasteable clone commmand with this directory name.

Test Plan: Looked at some repositories.

Reviewers: btrahan, chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T4175

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

+124 -10
+44 -10
src/applications/diffusion/controller/DiffusionRepositoryController.php
··· 176 176 if ($repository->isHosted()) { 177 177 $ssh_uri = $repository->getSSHCloneURIObject(); 178 178 if ($ssh_uri) { 179 - $clone_uri = $this->renderCloneURI( 179 + $clone_uri = $this->renderCloneCommand( 180 + $repository, 180 181 $ssh_uri, 181 182 $repository->getServeOverSSH(), 182 183 '/settings/panel/ssh/'); 183 184 184 - $view->addProperty(pht('Clone URI (SSH)'), $clone_uri); 185 + $view->addProperty( 186 + $repository->isSVN() 187 + ? pht('Checkout (SSH)') 188 + : pht('Clone (SSH)'), 189 + $clone_uri); 185 190 } 186 191 187 192 $http_uri = $repository->getHTTPCloneURIObject(); 188 193 if ($http_uri) { 189 - $clone_uri = $this->renderCloneURI( 194 + $clone_uri = $this->renderCloneCommand( 195 + $repository, 190 196 $http_uri, 191 197 $repository->getServeOverHTTP(), 192 198 PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth') 193 199 ? '/settings/panel/vcspassword/' 194 200 : null); 195 201 196 - $view->addProperty(pht('Clone URI (HTTP)'), $clone_uri); 202 + $view->addProperty( 203 + $repository->isSVN() 204 + ? pht('Checkout (HTTP)') 205 + : pht('Clone (HTTP)'), 206 + $clone_uri); 197 207 } 198 208 } else { 199 209 switch ($repository->getVersionControlSystem()) { 200 210 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 201 211 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 202 212 $view->addProperty( 203 - pht('Clone URI'), 204 - $this->renderCloneURI( 213 + pht('Clone'), 214 + $this->renderCloneCommand( 215 + $repository, 205 216 $repository->getPublicCloneURI())); 206 217 break; 207 218 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 208 219 $view->addProperty( 209 - pht('Repository Root'), 210 - $this->renderCloneURI( 220 + pht('Checkout'), 221 + $this->renderCloneCommand( 222 + $repository, 211 223 $repository->getPublicCloneURI())); 212 224 break; 213 225 } ··· 526 538 return $browse_panel; 527 539 } 528 540 529 - private function renderCloneURI( 541 + private function renderCloneCommand( 542 + PhabricatorRepository $repository, 530 543 $uri, 531 544 $serve_mode = null, 532 545 $manage_uri = null) { ··· 535 548 536 549 Javelin::initBehavior('select-on-click'); 537 550 551 + switch ($repository->getVersionControlSystem()) { 552 + case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 553 + $command = csprintf( 554 + 'git clone %s %s', 555 + $uri, 556 + $repository->getCloneName()); 557 + break; 558 + case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 559 + $command = csprintf( 560 + 'hg clone %s %s', 561 + $uri, 562 + $repository->getCloneName()); 563 + break; 564 + case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 565 + $command = csprintf( 566 + 'svn checkout %s %s', 567 + $uri, 568 + $repository->getCloneName()); 569 + break; 570 + } 571 + 538 572 $input = javelin_tag( 539 573 'input', 540 574 array( 541 575 'type' => 'text', 542 - 'value' => (string)$uri, 576 + 'value' => (string)$command, 543 577 'class' => 'diffusion-clone-uri', 544 578 'sigil' => 'select-on-click', 545 579 'readonly' => 'true',
+16
src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
··· 28 28 29 29 $v_name = $repository->getName(); 30 30 $v_desc = $repository->getDetail('description'); 31 + $v_clone_name = $repository->getDetail('clone-name'); 31 32 $e_name = true; 32 33 $errors = array(); 33 34 ··· 35 36 $v_name = $request->getStr('name'); 36 37 $v_desc = $request->getStr('description'); 37 38 $v_projects = $request->getArr('projectPHIDs'); 39 + $v_clone_name = $request->getStr('cloneName'); 38 40 39 41 if (!strlen($v_name)) { 40 42 $e_name = pht('Required'); ··· 50 52 $type_name = PhabricatorRepositoryTransaction::TYPE_NAME; 51 53 $type_desc = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION; 52 54 $type_edge = PhabricatorTransactions::TYPE_EDGE; 55 + $type_clone_name = PhabricatorRepositoryTransaction::TYPE_CLONE_NAME; 53 56 54 57 $xactions[] = id(clone $template) 55 58 ->setTransactionType($type_name) ··· 60 63 ->setNewValue($v_desc); 61 64 62 65 $xactions[] = id(clone $template) 66 + ->setTransactionType($type_clone_name) 67 + ->setNewValue($v_clone_name); 68 + 69 + $xactions[] = id(clone $template) 63 70 ->setTransactionType($type_edge) 64 71 ->setMetadataValue( 65 72 'edge:type', ··· 93 100 ->setLabel(pht('Name')) 94 101 ->setValue($v_name) 95 102 ->setError($e_name)) 103 + ->appendChild( 104 + id(new AphrontFormTextControl()) 105 + ->setName('cloneName') 106 + ->setLabel(pht('Clone/Checkout As')) 107 + ->setValue($v_clone_name) 108 + ->setCaption( 109 + pht( 110 + 'Optional directory name to use when cloning or checking out '. 111 + 'this repository.'))) 96 112 ->appendChild( 97 113 id(new PhabricatorRemarkupControl()) 98 114 ->setName('description')
+9
src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
··· 253 253 $view->addProperty(pht('Type'), $type); 254 254 $view->addProperty(pht('Callsign'), $repository->getCallsign()); 255 255 256 + 257 + $clone_name = $repository->getDetail('clone-name'); 258 + 259 + $view->addProperty( 260 + pht('Clone/Checkout As'), 261 + $clone_name 262 + ? $clone_name.'/' 263 + : phutil_tag('em', array(), $repository->getCloneName().'/')); 264 + 256 265 $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( 257 266 $repository->getPHID(), 258 267 PhabricatorEdgeConfig::TYPE_OBJECT_HAS_PROJECT);
+8
src/applications/repository/editor/PhabricatorRepositoryEditor.php
··· 31 31 $types[] = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; 32 32 $types[] = PhabricatorRepositoryTransaction::TYPE_CREDENTIAL; 33 33 $types[] = PhabricatorRepositoryTransaction::TYPE_DANGEROUS; 34 + $types[] = PhabricatorRepositoryTransaction::TYPE_CLONE_NAME; 34 35 35 36 $types[] = PhabricatorTransactions::TYPE_EDGE; 36 37 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; ··· 84 85 return $object->getCredentialPHID(); 85 86 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 86 87 return $object->shouldAllowDangerousChanges(); 88 + case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME: 89 + return $object->getDetail('clone-name'); 87 90 } 88 91 } 89 92 ··· 115 118 case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: 116 119 case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 117 120 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 121 + case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME: 118 122 return $xaction->getNewValue(); 119 123 case PhabricatorRepositoryTransaction::TYPE_NOTIFY: 120 124 case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: ··· 183 187 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 184 188 $object->setDetail('allow-dangerous-changes', $xaction->getNewValue()); 185 189 return; 190 + case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME: 191 + $object->setDetail('clone-name', $xaction->getNewValue()); 192 + return; 186 193 case PhabricatorRepositoryTransaction::TYPE_ENCODING: 187 194 // Make sure the encoding is valid by converting to UTF-8. This tests 188 195 // that the user has mbstring installed, and also that they didn't type ··· 294 301 case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: 295 302 case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 296 303 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 304 + case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME: 297 305 PhabricatorPolicyFilter::requireCapability( 298 306 $this->requireActor(), 299 307 $object,
+28
src/applications/repository/storage/PhabricatorRepository.php
··· 212 212 } 213 213 214 214 215 + /** 216 + * Get the name of the directory this repository should clone or checkout 217 + * into. For example, if the repository name is "Example Repository", a 218 + * reasonable name might be "example-repository". This is used to help users 219 + * get reasonable results when cloning repositories, since they generally do 220 + * not want to clone into directories called "X/" or "Example Repository/". 221 + * 222 + * @return string 223 + */ 224 + public function getCloneName() { 225 + $name = $this->getDetail('clone-name'); 226 + 227 + // Make some reasonable effort to produce reasonable default directory 228 + // names from repository names. 229 + if (!strlen($name)) { 230 + $name = $this->getName(); 231 + $name = phutil_utf8_strtolower($name); 232 + $name = preg_replace('@[/ -:]+@', '-', $name); 233 + $name = trim($name, '-'); 234 + if (!strlen($name)) { 235 + $name = $this->getCallsign(); 236 + } 237 + } 238 + 239 + return $name; 240 + } 241 + 242 + 215 243 /* -( Remote Command Execution )------------------------------------------- */ 216 244 217 245
+18
src/applications/repository/storage/PhabricatorRepositoryTransaction.php
··· 23 23 const TYPE_PUSH_POLICY = 'repo:push-policy'; 24 24 const TYPE_CREDENTIAL = 'repo:credential'; 25 25 const TYPE_DANGEROUS = 'repo:dangerous'; 26 + const TYPE_CLONE_NAME = 'repo:clone-name'; 26 27 27 28 // TODO: Clean up these legacy transaction types. 28 29 const TYPE_SSH_LOGIN = 'repo:ssh-login'; ··· 348 349 return pht( 349 350 '%s enabled protection against dangerous changes.', 350 351 $this->renderHandleLink($author_phid)); 352 + } 353 + case self::TYPE_CLONE_NAME: 354 + if (strlen($old) && !strlen($new)) { 355 + return pht( 356 + '%s removed the clone name of this repository.', 357 + $this->renderHandleLink($author_phid)); 358 + } else if (strlen($new) && !strlen($old)) { 359 + return pht( 360 + '%s set the clone name of this repository to "%s".', 361 + $this->renderHandleLink($author_phid), 362 + $new); 363 + } else { 364 + return pht( 365 + '%s changed the clone name of this repository from "%s" to "%s".', 366 + $this->renderHandleLink($author_phid), 367 + $old, 368 + $new); 351 369 } 352 370 } 353 371
+1
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 228 228 private function applyInternalEffects( 229 229 PhabricatorLiskDAO $object, 230 230 PhabricatorApplicationTransaction $xaction) { 231 + 231 232 switch ($xaction->getTransactionType()) { 232 233 case PhabricatorTransactions::TYPE_VIEW_POLICY: 233 234 $object->setViewPolicy($xaction->getNewValue());