Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / diffusion / ssh / DiffusionMercurialServeSSHWorkflow.php
blob221d1696b266c4041003c87f9d18c3bcecac7e69
1 <?php
3 final class DiffusionMercurialServeSSHWorkflow
4 extends DiffusionMercurialSSHWorkflow {
6 protected $didSeeWrite;
8 protected function didConstruct() {
9 $this->setName('hg');
10 $this->setArguments(
11 array(
12 array(
13 'name' => 'repository',
14 'short' => 'R',
15 'param' => 'repo',
17 array(
18 'name' => 'stdio',
20 array(
21 'name' => 'command',
22 'wildcard' => true,
24 ));
27 protected function identifyRepository() {
28 $args = $this->getArgs();
29 $path = $args->getArg('repository');
30 return $this->loadRepositoryWithPath(
31 $path,
32 PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL);
35 protected function executeRepositoryOperations() {
36 $repository = $this->getRepository();
37 $args = $this->getArgs();
39 if (!$args->getArg('stdio')) {
40 throw new Exception(pht('Expected `%s`!', 'hg ... --stdio'));
43 if ($args->getArg('command') !== array('serve')) {
44 throw new Exception(pht('Expected `%s`!', 'hg ... serve'));
47 if ($this->shouldProxy()) {
48 // NOTE: For now, we're always requesting a writable node. The request
49 // may not actually need one, but we can't currently determine whether
50 // it is read-only or not at this phase of evaluation.
51 $command = $this->getProxyCommand(true);
52 } else {
53 $command = csprintf(
54 'hg -R %s serve --stdio',
55 $repository->getLocalPath());
57 $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
59 $future = id(new ExecFuture('%C', $command))
60 ->setEnv($this->getEnvironment());
62 $io_channel = $this->getIOChannel();
63 $protocol_channel = new DiffusionMercurialWireClientSSHProtocolChannel(
64 $io_channel);
66 $err = id($this->newPassthruCommand())
67 ->setIOChannel($protocol_channel)
68 ->setCommandChannelFromExecFuture($future)
69 ->setWillWriteCallback(array($this, 'willWriteMessageCallback'))
70 ->execute();
72 if (!$err && $this->didSeeWrite) {
73 $repository->writeStatusMessage(
74 PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE,
75 PhabricatorRepositoryStatusMessage::CODE_OKAY);
78 return $err;
81 public function willWriteMessageCallback(
82 PhabricatorSSHPassthruCommand $command,
83 $message) {
85 $command = $message['command'];
87 // Check if this is a readonly command.
89 $is_readonly = false;
90 if ($command == 'batch') {
91 $cmds = idx($message['arguments'], 'cmds');
92 if (DiffusionMercurialWireProtocol::isReadOnlyBatchCommand($cmds)) {
93 $is_readonly = true;
95 } else if (DiffusionMercurialWireProtocol::isReadOnlyCommand($command)) {
96 $is_readonly = true;
99 if (!$is_readonly) {
100 $this->requireWriteAccess();
101 $this->didSeeWrite = true;
104 return $message['raw'];
107 protected function raiseWrongVCSException(
108 PhabricatorRepository $repository) {
109 throw new Exception(
110 pht(
111 'This repository ("%s") is not a Mercurial repository. Use "%s" to '.
112 'interact with this repository.',
113 $repository->getDisplayName(),
114 $repository->getVersionControlSystem()));