Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / repository / engine / PhabricatorRepositoryMirrorEngine.php
blob32689d3a7756dac57b58a4266567e7cf7e4769fc
1 <?php
3 /**
4 * Pushes a repository to its mirrors.
5 */
6 final class PhabricatorRepositoryMirrorEngine
7 extends PhabricatorRepositoryEngine {
9 public function pushToMirrors() {
10 $viewer = $this->getViewer();
11 $repository = $this->getRepository();
13 if (!$repository->canMirror()) {
14 return;
17 if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
18 $this->log(
19 pht('This software is running in silent mode; declining to mirror.'));
20 return;
23 $uris = id(new PhabricatorRepositoryURIQuery())
24 ->setViewer($viewer)
25 ->withRepositories(array($repository))
26 ->execute();
28 $io_mirror = PhabricatorRepositoryURI::IO_MIRROR;
30 $exceptions = array();
31 foreach ($uris as $mirror) {
32 if ($mirror->getIsDisabled()) {
33 continue;
36 $io_type = $mirror->getEffectiveIOType();
37 if ($io_type != $io_mirror) {
38 continue;
41 try {
42 $this->pushRepositoryToMirror($repository, $mirror);
43 } catch (Exception $ex) {
44 $exceptions[] = $ex;
48 if ($exceptions) {
49 throw new PhutilAggregateException(
50 pht(
51 'Exceptions occurred while mirroring the "%s" repository.',
52 $repository->getDisplayName()),
53 $exceptions);
57 private function pushRepositoryToMirror(
58 PhabricatorRepository $repository,
59 PhabricatorRepositoryURI $mirror_uri) {
61 $this->log(
62 pht(
63 'Pushing to remote "%s"...',
64 $mirror_uri->getEffectiveURI()));
66 if ($repository->isGit()) {
67 $this->pushToGitRepository($repository, $mirror_uri);
68 } else if ($repository->isHg()) {
69 $this->pushToHgRepository($repository, $mirror_uri);
70 } else {
71 throw new Exception(pht('Unsupported VCS!'));
75 private function pushToGitRepository(
76 PhabricatorRepository $repository,
77 PhabricatorRepositoryURI $mirror_uri) {
79 // See T5965. Test if we have any refs to mirror. If we have nothing, git
80 // will exit with an error ("No refs in common and none specified; ...")
81 // when we run "git push --mirror".
83 // If we don't have any refs, we just bail out. (This is arguably sort of
84 // the wrong behavior: to mirror an empty repository faithfully we should
85 // delete everything in the remote.)
87 list($stdout) = $repository->execxLocalCommand(
88 'for-each-ref --count 1 --');
89 if (!strlen($stdout)) {
90 return;
93 $argv = array(
94 'push --verbose --mirror -- %P',
95 $mirror_uri->getURIEnvelope(),
98 $future = $mirror_uri->newCommandEngine()
99 ->setArgv($argv)
100 ->newFuture();
102 $future
103 ->setCWD($repository->getLocalPath())
104 ->resolvex();
107 private function pushToHgRepository(
108 PhabricatorRepository $repository,
109 PhabricatorRepositoryURI $mirror_uri) {
111 $argv = array(
112 'push --verbose --rev tip -- %P',
113 $mirror_uri->getURIEnvelope(),
116 $future = $mirror_uri->newCommandEngine()
117 ->setArgv($argv)
118 ->newFuture();
120 try {
121 $future
122 ->setCWD($repository->getLocalPath())
123 ->resolvex();
124 } catch (CommandException $ex) {
125 if (preg_match('/no changes found/', $ex->getStdout())) {
126 // mercurial says nothing changed, but that's good
127 } else {
128 throw $ex;