Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/config/controller/PhabricatorConfigConsoleController.php
12256 views
1
<?php
2
3
final class PhabricatorConfigConsoleController
4
extends PhabricatorConfigController {
5
6
public function handleRequest(AphrontRequest $request) {
7
$viewer = $request->getViewer();
8
9
$menu = id(new PHUIObjectItemListView())
10
->setViewer($viewer)
11
->setBig(true);
12
13
$menu->addItem(
14
id(new PHUIObjectItemView())
15
->setHeader(pht('Settings'))
16
->setHref($this->getApplicationURI('settings/'))
17
->setImageIcon('fa-wrench')
18
->setClickable(true)
19
->addAttribute(
20
pht(
21
'Review and modify configuration settings.')));
22
23
$menu->addItem(
24
id(new PHUIObjectItemView())
25
->setHeader(pht('Setup Issues'))
26
->setHref($this->getApplicationURI('issue/'))
27
->setImageIcon('fa-exclamation-triangle')
28
->setClickable(true)
29
->addAttribute(
30
pht(
31
'Show unresolved issues with setup and configuration.')));
32
33
$menu->addItem(
34
id(new PHUIObjectItemView())
35
->setHeader(pht('Services'))
36
->setHref($this->getApplicationURI('cluster/databases/'))
37
->setImageIcon('fa-server')
38
->setClickable(true)
39
->addAttribute(
40
pht(
41
'View status information for databases, caches, repositories, '.
42
'and other services.')));
43
44
$menu->addItem(
45
id(new PHUIObjectItemView())
46
->setHeader(pht('Extensions/Modules'))
47
->setHref($this->getApplicationURI('module/'))
48
->setImageIcon('fa-gear')
49
->setClickable(true)
50
->addAttribute(
51
pht(
52
'Show installed extensions and modules.')));
53
54
$crumbs = $this->buildApplicationCrumbs()
55
->addTextCrumb(pht('Console'))
56
->setBorder(true);
57
58
$box = id(new PHUIObjectBoxView())
59
->setHeaderText(pht('Configuration'))
60
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
61
->setObjectList($menu);
62
63
$versions = $this->newLibraryVersionTable($viewer);
64
$binary_versions = $this->newBinaryVersionTable();
65
66
$launcher_view = id(new PHUILauncherView())
67
->appendChild($box)
68
->appendChild($versions)
69
->appendChild($binary_versions);
70
71
$view = id(new PHUITwoColumnView())
72
->setFooter($launcher_view);
73
74
return $this->newPage()
75
->setTitle(pht('Configuration'))
76
->setCrumbs($crumbs)
77
->appendChild($view);
78
}
79
80
public function newLibraryVersionTable() {
81
$viewer = $this->getViewer();
82
83
$versions = $this->loadVersions($viewer);
84
85
$rows = array();
86
foreach ($versions as $name => $info) {
87
$branchpoint = $info['branchpoint'];
88
if ($branchpoint !== null && strlen($branchpoint)) {
89
$branchpoint = substr($branchpoint, 0, 12);
90
} else {
91
$branchpoint = null;
92
}
93
94
$version = $info['hash'];
95
if ($version !== null && strlen($version)) {
96
$version = substr($version, 0, 12);
97
} else {
98
$version = pht('Unknown');
99
}
100
101
102
$epoch = $info['epoch'];
103
if ($epoch) {
104
$epoch = phabricator_date($epoch, $viewer);
105
} else {
106
$epoch = null;
107
}
108
109
$rows[] = array(
110
$name,
111
$version,
112
$epoch,
113
$branchpoint,
114
);
115
}
116
117
$table_view = id(new AphrontTableView($rows))
118
->setHeaders(
119
array(
120
pht('Library'),
121
pht('Version'),
122
pht('Date'),
123
pht('Branchpoint'),
124
))
125
->setColumnClasses(
126
array(
127
'pri',
128
null,
129
null,
130
'wide',
131
));
132
133
return id(new PHUIObjectBoxView())
134
->setHeaderText(pht('Version Information'))
135
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
136
->appendChild($table_view);
137
}
138
139
private function loadVersions(PhabricatorUser $viewer) {
140
$specs = array(
141
'phabricator',
142
'arcanist',
143
);
144
145
$all_libraries = PhutilBootloader::getInstance()->getAllLibraries();
146
// This puts the core libraries at the top:
147
$other_libraries = array_diff($all_libraries, $specs);
148
$specs = array_merge($specs, $other_libraries);
149
150
$log_futures = array();
151
$remote_futures = array();
152
153
foreach ($specs as $lib) {
154
$root = dirname(phutil_get_library_root($lib));
155
156
$log_command = csprintf(
157
'git log --format=%s -n 1 --',
158
'%H %ct');
159
160
$remote_command = csprintf(
161
'git remote -v');
162
163
$log_futures[$lib] = id(new ExecFuture('%C', $log_command))
164
->setCWD($root);
165
166
$remote_futures[$lib] = id(new ExecFuture('%C', $remote_command))
167
->setCWD($root);
168
}
169
170
$all_futures = array_merge($log_futures, $remote_futures);
171
172
id(new FutureIterator($all_futures))
173
->resolveAll();
174
175
// A repository may have a bunch of remotes, but we're only going to look
176
// for remotes we host to try to figure out where this repository branched.
177
$upstream_pattern = '(github\.com/phacility/|secure\.phabricator\.com/)';
178
179
$upstream_futures = array();
180
$lib_upstreams = array();
181
foreach ($specs as $lib) {
182
$remote_future = $remote_futures[$lib];
183
184
list($err, $stdout) = $remote_future->resolve();
185
if ($err) {
186
// If this fails for whatever reason, just move on.
187
continue;
188
}
189
190
// These look like this, with a tab separating the first two fields:
191
// remote-name http://remote.uri/ (push)
192
193
$upstreams = array();
194
195
$remotes = phutil_split_lines($stdout, false);
196
foreach ($remotes as $remote) {
197
$remote_pattern = '/^([^\t]+)\t([^ ]+) \(([^)]+)\)\z/';
198
$matches = null;
199
if (!preg_match($remote_pattern, $remote, $matches)) {
200
continue;
201
}
202
203
// Remote URIs are either "push" or "fetch": we only care about "fetch"
204
// URIs.
205
$type = $matches[3];
206
if ($type != 'fetch') {
207
continue;
208
}
209
210
$uri = $matches[2];
211
$is_upstream = preg_match($upstream_pattern, $uri);
212
if (!$is_upstream) {
213
continue;
214
}
215
216
$name = $matches[1];
217
$upstreams[$name] = $name;
218
}
219
220
// If we have several suitable upstreams, try to pick the one named
221
// "origin", if it exists. Otherwise, just pick the first one.
222
if (isset($upstreams['origin'])) {
223
$upstream = $upstreams['origin'];
224
} else if ($upstreams) {
225
$upstream = head($upstreams);
226
} else {
227
$upstream = null;
228
}
229
230
if (!$upstream) {
231
continue;
232
}
233
234
$lib_upstreams[$lib] = $upstream;
235
236
$merge_base_command = csprintf(
237
'git merge-base HEAD %s/master --',
238
$upstream);
239
240
$root = dirname(phutil_get_library_root($lib));
241
242
$upstream_futures[$lib] = id(new ExecFuture('%C', $merge_base_command))
243
->setCWD($root);
244
}
245
246
if ($upstream_futures) {
247
id(new FutureIterator($upstream_futures))
248
->resolveAll();
249
}
250
251
$results = array();
252
foreach ($log_futures as $lib => $future) {
253
list($err, $stdout) = $future->resolve();
254
if (!$err) {
255
list($hash, $epoch) = explode(' ', $stdout);
256
} else {
257
$hash = null;
258
$epoch = null;
259
}
260
261
$result = array(
262
'hash' => $hash,
263
'epoch' => $epoch,
264
'upstream' => null,
265
'branchpoint' => null,
266
);
267
268
$upstream_future = idx($upstream_futures, $lib);
269
if ($upstream_future) {
270
list($err, $stdout) = $upstream_future->resolve();
271
if (!$err) {
272
$branchpoint = trim($stdout);
273
if (strlen($branchpoint)) {
274
// We only list a branchpoint if it differs from HEAD.
275
if ($branchpoint != $hash) {
276
$result['upstream'] = $lib_upstreams[$lib];
277
$result['branchpoint'] = trim($stdout);
278
}
279
}
280
}
281
}
282
283
$results[$lib] = $result;
284
}
285
286
return $results;
287
}
288
289
private function newBinaryVersionTable() {
290
$rows = array();
291
292
$rows[] = array(
293
'php',
294
phpversion(),
295
php_sapi_name(),
296
);
297
298
$binaries = PhutilBinaryAnalyzer::getAllBinaries();
299
foreach ($binaries as $binary) {
300
if (!$binary->isBinaryAvailable()) {
301
$binary_version = pht('Not Available');
302
$binary_path = null;
303
} else {
304
$binary_version = $binary->getBinaryVersion();
305
$binary_path = $binary->getBinaryPath();
306
}
307
308
$rows[] = array(
309
$binary->getBinaryName(),
310
$binary_version,
311
$binary_path,
312
);
313
}
314
315
$table_view = id(new AphrontTableView($rows))
316
->setHeaders(
317
array(
318
pht('Binary'),
319
pht('Version'),
320
pht('Path'),
321
))
322
->setColumnClasses(
323
array(
324
'pri',
325
null,
326
'wide',
327
));
328
329
return id(new PHUIObjectBoxView())
330
->setHeaderText(pht('Other Version Information'))
331
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
332
->appendChild($table_view);
333
}
334
335
336
}
337
338