Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php
12242 views
1
<?php
2
3
final class DiffusionMercurialServeSSHWorkflow
4
extends DiffusionMercurialSSHWorkflow {
5
6
protected $didSeeWrite;
7
8
protected function didConstruct() {
9
$this->setName('hg');
10
$this->setArguments(
11
array(
12
array(
13
'name' => 'repository',
14
'short' => 'R',
15
'param' => 'repo',
16
),
17
array(
18
'name' => 'stdio',
19
),
20
array(
21
'name' => 'command',
22
'wildcard' => true,
23
),
24
));
25
}
26
27
protected function identifyRepository() {
28
$args = $this->getArgs();
29
$path = $args->getArg('repository');
30
return $this->loadRepositoryWithPath(
31
$path,
32
PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL);
33
}
34
35
protected function executeRepositoryOperations() {
36
$repository = $this->getRepository();
37
$args = $this->getArgs();
38
39
if (!$args->getArg('stdio')) {
40
throw new Exception(pht('Expected `%s`!', 'hg ... --stdio'));
41
}
42
43
if ($args->getArg('command') !== array('serve')) {
44
throw new Exception(pht('Expected `%s`!', 'hg ... serve'));
45
}
46
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());
56
}
57
$command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
58
59
$future = id(new ExecFuture('%C', $command))
60
->setEnv($this->getEnvironment());
61
62
$io_channel = $this->getIOChannel();
63
$protocol_channel = new DiffusionMercurialWireClientSSHProtocolChannel(
64
$io_channel);
65
66
$err = id($this->newPassthruCommand())
67
->setIOChannel($protocol_channel)
68
->setCommandChannelFromExecFuture($future)
69
->setWillWriteCallback(array($this, 'willWriteMessageCallback'))
70
->execute();
71
72
if (!$err && $this->didSeeWrite) {
73
$repository->writeStatusMessage(
74
PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE,
75
PhabricatorRepositoryStatusMessage::CODE_OKAY);
76
}
77
78
return $err;
79
}
80
81
public function willWriteMessageCallback(
82
PhabricatorSSHPassthruCommand $command,
83
$message) {
84
85
$command = $message['command'];
86
87
// Check if this is a readonly command.
88
89
$is_readonly = false;
90
if ($command == 'batch') {
91
$cmds = idx($message['arguments'], 'cmds');
92
if (DiffusionMercurialWireProtocol::isReadOnlyBatchCommand($cmds)) {
93
$is_readonly = true;
94
}
95
} else if (DiffusionMercurialWireProtocol::isReadOnlyCommand($command)) {
96
$is_readonly = true;
97
}
98
99
if (!$is_readonly) {
100
$this->requireWriteAccess();
101
$this->didSeeWrite = true;
102
}
103
104
return $message['raw'];
105
}
106
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()));
115
}
116
117
}
118
119