Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/config/check/PhabricatorBinariesSetupCheck.php
12256 views
1
<?php
2
3
final class PhabricatorBinariesSetupCheck extends PhabricatorSetupCheck {
4
5
public function getDefaultGroup() {
6
return self::GROUP_OTHER;
7
}
8
9
protected function executeChecks() {
10
if (phutil_is_windows()) {
11
$bin_name = 'where';
12
} else {
13
$bin_name = 'which';
14
}
15
16
if (!Filesystem::binaryExists($bin_name)) {
17
$message = pht(
18
"Without '%s', this software can not test for the availability ".
19
"of other binaries.",
20
$bin_name);
21
$this->raiseWarning($bin_name, $message);
22
23
// We need to return here if we can't find the 'which' / 'where' binary
24
// because the other tests won't be valid.
25
return;
26
}
27
28
if (!Filesystem::binaryExists('diff')) {
29
$message = pht(
30
"Without '%s', this software will not be able to generate or render ".
31
"diffs in multiple applications.",
32
'diff');
33
$this->raiseWarning('diff', $message);
34
} else {
35
$tmp_a = new TempFile();
36
$tmp_b = new TempFile();
37
$tmp_c = new TempFile();
38
39
Filesystem::writeFile($tmp_a, 'A');
40
Filesystem::writeFile($tmp_b, 'A');
41
Filesystem::writeFile($tmp_c, 'B');
42
43
list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_b);
44
if ($err) {
45
$this->newIssue('bin.diff.same')
46
->setName(pht("Unexpected '%s' Behavior", 'diff'))
47
->setMessage(
48
pht(
49
"The '%s' binary on this system has unexpected behavior: ".
50
"it was expected to exit without an error code when passed ".
51
"identical files, but exited with code %d.",
52
'diff',
53
$err));
54
}
55
56
list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_c);
57
if (!$err) {
58
$this->newIssue('bin.diff.diff')
59
->setName(pht("Unexpected 'diff' Behavior"))
60
->setMessage(
61
pht(
62
"The '%s' binary on this system has unexpected behavior: ".
63
"it was expected to exit with a nonzero error code when passed ".
64
"differing files, but did not.",
65
'diff'));
66
}
67
}
68
69
$table = new PhabricatorRepository();
70
$vcses = queryfx_all(
71
$table->establishConnection('r'),
72
'SELECT DISTINCT versionControlSystem FROM %T',
73
$table->getTableName());
74
75
foreach ($vcses as $vcs) {
76
switch ($vcs['versionControlSystem']) {
77
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
78
$binary = 'git';
79
break;
80
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
81
$binary = 'svn';
82
break;
83
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
84
$binary = 'hg';
85
break;
86
default:
87
$binary = null;
88
break;
89
}
90
if (!$binary) {
91
continue;
92
}
93
94
if (!Filesystem::binaryExists($binary)) {
95
$message = pht(
96
'You have at least one repository configured which uses this '.
97
'version control system. It will not work without the VCS binary.');
98
$this->raiseWarning($binary, $message);
99
continue;
100
}
101
102
$version = PhutilBinaryAnalyzer::getForBinary($binary)
103
->getBinaryVersion();
104
105
switch ($vcs['versionControlSystem']) {
106
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
107
$bad_versions = array();
108
break;
109
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
110
$bad_versions = array(
111
// We need 1.5 for "--depth", see T7228.
112
'< 1.5' => pht(
113
'The minimum supported version of Subversion is 1.5, which '.
114
'was released in 2008.'),
115
'= 1.7.1' => pht(
116
'This version of Subversion has a bug where `%s` does not work '.
117
'for files added in rN (Subversion issue #2873), fixed in 1.7.2.',
118
'svn diff -c N'),
119
);
120
break;
121
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
122
$bad_versions = array(
123
// We need 2.4 for utilizing `{p1node}` keyword in templates, see
124
// D21679 and D21681.
125
'< 2.4' => pht(
126
'The minimum supported version of Mercurial is 2.4, which was '.
127
'released in 2012.'),
128
);
129
break;
130
}
131
132
if ($version === null) {
133
$this->raiseUnknownVersionWarning($binary);
134
} else {
135
$version_details = array();
136
137
foreach ($bad_versions as $spec => $details) {
138
list($operator, $bad_version) = explode(' ', $spec, 2);
139
$is_bad = version_compare($version, $bad_version, $operator);
140
if ($is_bad) {
141
$version_details[] = pht(
142
'(%s%s) %s',
143
$operator,
144
$bad_version,
145
$details);
146
}
147
}
148
149
if ($version_details) {
150
$this->raiseBadVersionWarning(
151
$binary,
152
$version,
153
$version_details);
154
}
155
}
156
}
157
158
}
159
160
private function raiseWarning($bin, $message) {
161
if (phutil_is_windows()) {
162
$preamble = pht(
163
"The '%s' binary could not be found. Set the webserver's %s ".
164
"environmental variable to include the directory where it resides, or ".
165
"add that directory to '%s' in configuration.",
166
$bin,
167
'PATH',
168
'environment.append-paths');
169
} else {
170
$preamble = pht(
171
"The '%s' binary could not be found. Symlink it into '%s', or set the ".
172
"webserver's %s environmental variable to include the directory where ".
173
"it resides, or add that directory to '%s' in configuration.",
174
$bin,
175
'support/bin/',
176
'PATH',
177
'environment.append-paths');
178
}
179
180
$this->newIssue('bin.'.$bin)
181
->setShortName(pht("'%s' Missing", $bin))
182
->setName(pht("Missing '%s' Binary", $bin))
183
->setSummary(
184
pht("The '%s' binary could not be located or executed.", $bin))
185
->setMessage($preamble.' '.$message)
186
->addPhabricatorConfig('environment.append-paths');
187
}
188
189
private function raiseUnknownVersionWarning($binary) {
190
$summary = pht(
191
'Unable to determine the version number of "%s".',
192
$binary);
193
194
$message = pht(
195
'Unable to determine the version number of "%s". Usually, this means '.
196
'the program changed its version format string recently and this '.
197
'software does not know how to parse the new one yet, but might '.
198
'indicate that you have a very old (or broken) binary.'.
199
"\n\n".
200
'Because we can not determine the version number, checks against '.
201
'minimum and known-bad versions will be skipped, so we might fail '.
202
'to detect an incompatible binary.'.
203
"\n\n".
204
'You may be able to resolve this issue by updating this server, since '.
205
'a newer version of the software is likely to be able to parse the '.
206
'newer version string.'.
207
"\n\n".
208
'If updating the software does not fix this, you can report the issue '.
209
'to the upstream so we can adjust the parser.'.
210
"\n\n".
211
'If you are confident you have a recent version of "%s" installed and '.
212
'working correctly, it is usually safe to ignore this warning.',
213
$binary,
214
$binary);
215
216
$this->newIssue('bin.'.$binary.'.unknown-version')
217
->setShortName(pht("Unknown '%s' Version", $binary))
218
->setName(pht("Unknown '%s' Version", $binary))
219
->setSummary($summary)
220
->setMessage($message)
221
->addLink(
222
PhabricatorEnv::getDoclink('Contributing Bug Reports'),
223
pht('Report this Issue to the Upstream'));
224
}
225
226
private function raiseBadVersionWarning($binary, $version, array $problems) {
227
$summary = pht(
228
'This server has a known bad version of "%s".',
229
$binary);
230
231
$message = array();
232
233
$message[] = pht(
234
'This server has a known bad version of "%s" installed ("%s"). This '.
235
'version is not supported, or contains important bugs or security '.
236
'vulnerabilities which are fixed in a newer version.',
237
$binary,
238
$version);
239
240
$message[] = pht('You should upgrade this software.');
241
242
$message[] = pht('The known issues with this old version are:');
243
244
foreach ($problems as $problem) {
245
$message[] = $problem;
246
}
247
248
$message = implode("\n\n", $message);
249
250
$this->newIssue("bin.{$binary}.bad-version")
251
->setName(pht('Unsupported/Insecure "%s" Version', $binary))
252
->setSummary($summary)
253
->setMessage($message);
254
}
255
256
}
257
258