3 final class DiffusionMercurialServeSSHWorkflow
4 extends DiffusionMercurialSSHWorkflow
{
6 protected $didSeeWrite;
8 protected function didConstruct() {
13 'name' => 'repository',
27 protected function identifyRepository() {
28 $args = $this->getArgs();
29 $path = $args->getArg('repository');
30 return $this->loadRepositoryWithPath(
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);
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(
66 $err = id($this->newPassthruCommand())
67 ->setIOChannel($protocol_channel)
68 ->setCommandChannelFromExecFuture($future)
69 ->setWillWriteCallback(array($this, 'willWriteMessageCallback'))
72 if (!$err && $this->didSeeWrite
) {
73 $repository->writeStatusMessage(
74 PhabricatorRepositoryStatusMessage
::TYPE_NEEDS_UPDATE
,
75 PhabricatorRepositoryStatusMessage
::CODE_OKAY
);
81 public function willWriteMessageCallback(
82 PhabricatorSSHPassthruCommand
$command,
85 $command = $message['command'];
87 // Check if this is a readonly command.
90 if ($command == 'batch') {
91 $cmds = idx($message['arguments'], 'cmds');
92 if (DiffusionMercurialWireProtocol
::isReadOnlyBatchCommand($cmds)) {
95 } else if (DiffusionMercurialWireProtocol
::isReadOnlyCommand($command)) {
100 $this->requireWriteAccess();
101 $this->didSeeWrite
= true;
104 return $message['raw'];
107 protected function raiseWrongVCSException(
108 PhabricatorRepository
$repository) {
111 'This repository ("%s") is not a Mercurial repository. Use "%s" to '.
112 'interact with this repository.',
113 $repository->getDisplayName(),
114 $repository->getVersionControlSystem()));