[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorRepositoryManagementUpdateWorkflow 4 extends PhabricatorRepositoryManagementWorkflow { 5 6 private $verbose; 7 8 public function setVerbose($verbose) { 9 $this->verbose = $verbose; 10 return $this; 11 } 12 13 public function getVerbose() { 14 return $this->verbose; 15 } 16 17 public function didConstruct() { 18 $this 19 ->setName('update') 20 ->setExamples('**update** [options] __repository__') 21 ->setSynopsis( 22 pht( 23 'Update __repository__, named by callsign. '. 24 'This performs the __pull__, __discover__, __ref__ and __mirror__ '. 25 'operations and is primarily an internal workflow.')) 26 ->setArguments( 27 array( 28 array( 29 'name' => 'verbose', 30 'help' => 'Show additional debugging information.', 31 ), 32 array( 33 'name' => 'no-discovery', 34 'help' => 'Do not perform discovery.', 35 ), 36 array( 37 'name' => 'repos', 38 'wildcard' => true, 39 ), 40 )); 41 } 42 43 public function execute(PhutilArgumentParser $args) { 44 $this->setVerbose($args->getArg('verbose')); 45 $console = PhutilConsole::getConsole(); 46 47 $repos = $this->loadRepositories($args, 'repos'); 48 if (count($repos) !== 1) { 49 throw new PhutilArgumentUsageException( 50 pht('Specify exactly one repository to update, by callsign.')); 51 } 52 53 $repository = head($repos); 54 $callsign = $repository->getCallsign(); 55 56 $no_discovery = $args->getArg('no-discovery'); 57 58 id(new PhabricatorRepositoryPullEngine()) 59 ->setRepository($repository) 60 ->setVerbose($this->getVerbose()) 61 ->pullRepository(); 62 63 if ($no_discovery) { 64 return; 65 } 66 67 // TODO: It would be nice to discover only if we pulled something, but this 68 // isn't totally trivial. It's slightly more complicated with hosted 69 // repositories, too. 70 71 $lock_name = get_class($this).':'.$callsign; 72 $lock = PhabricatorGlobalLock::newLock($lock_name); 73 74 $lock->lock(); 75 76 try { 77 $repository->writeStatusMessage( 78 PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE, 79 null); 80 81 $this->discoverRepository($repository); 82 83 $this->checkIfRepositoryIsFullyImported($repository); 84 85 $this->updateRepositoryRefs($repository); 86 87 $this->mirrorRepository($repository); 88 89 $repository->writeStatusMessage( 90 PhabricatorRepositoryStatusMessage::TYPE_FETCH, 91 PhabricatorRepositoryStatusMessage::CODE_OKAY); 92 } catch (Exception $ex) { 93 $repository->writeStatusMessage( 94 PhabricatorRepositoryStatusMessage::TYPE_FETCH, 95 PhabricatorRepositoryStatusMessage::CODE_ERROR, 96 array( 97 'message' => pht( 98 'Error updating working copy: %s', $ex->getMessage()), 99 )); 100 101 $lock->unlock(); 102 throw $ex; 103 } 104 105 $lock->unlock(); 106 107 $console->writeOut( 108 pht( 109 'Updated repository **%s**.', 110 $repository->getMonogram())."\n"); 111 112 return 0; 113 } 114 115 private function discoverRepository(PhabricatorRepository $repository) { 116 $refs = id(new PhabricatorRepositoryDiscoveryEngine()) 117 ->setRepository($repository) 118 ->setVerbose($this->getVerbose()) 119 ->discoverCommits(); 120 121 return (bool)count($refs); 122 } 123 124 private function mirrorRepository(PhabricatorRepository $repository) { 125 try { 126 id(new PhabricatorRepositoryMirrorEngine()) 127 ->setRepository($repository) 128 ->pushToMirrors(); 129 } catch (Exception $ex) { 130 // TODO: We should report these into the UI properly, but for now just 131 // complain. These errors are much less severe than pull errors. 132 $proxy = new PhutilProxyException( 133 pht( 134 'Error while pushing "%s" repository to mirrors.', 135 $repository->getCallsign()), 136 $ex); 137 phlog($proxy); 138 } 139 } 140 141 private function updateRepositoryRefs(PhabricatorRepository $repository) { 142 id(new PhabricatorRepositoryRefEngine()) 143 ->setRepository($repository) 144 ->updateRefs(); 145 } 146 147 private function checkIfRepositoryIsFullyImported( 148 PhabricatorRepository $repository) { 149 150 // Check if the repository has the "Importing" flag set. We want to clear 151 // the flag if we can. 152 $importing = $repository->getDetail('importing'); 153 if (!$importing) { 154 // This repository isn't marked as "Importing", so we're done. 155 return; 156 } 157 158 // Look for any commit which hasn't imported. 159 $unparsed_commit = queryfx_one( 160 $repository->establishConnection('r'), 161 'SELECT * FROM %T WHERE repositoryID = %d AND (importStatus & %d) != %d 162 LIMIT 1', 163 id(new PhabricatorRepositoryCommit())->getTableName(), 164 $repository->getID(), 165 PhabricatorRepositoryCommit::IMPORTED_ALL, 166 PhabricatorRepositoryCommit::IMPORTED_ALL); 167 if ($unparsed_commit) { 168 // We found a commit which still needs to import, so we can't clear the 169 // flag. 170 return; 171 } 172 173 // Clear the "importing" flag. 174 $repository->openTransaction(); 175 $repository->beginReadLocking(); 176 $repository = $repository->reload(); 177 $repository->setDetail('importing', false); 178 $repository->save(); 179 $repository->endReadLocking(); 180 $repository->saveTransaction(); 181 } 182 183 184 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |