2012-12-30 15:37:49 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorSetupCheck {
|
|
|
|
|
|
|
|
private $issues;
|
|
|
|
|
|
|
|
abstract protected function executeChecks();
|
|
|
|
|
2013-01-23 00:16:26 +01:00
|
|
|
public function getExecutionOrder() {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-12-30 15:37:49 +01:00
|
|
|
final protected function newIssue($key) {
|
|
|
|
$issue = id(new PhabricatorSetupIssue())
|
|
|
|
->setIssueKey($key);
|
|
|
|
$this->issues[$key] = $issue;
|
|
|
|
|
|
|
|
return $issue;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function getIssues() {
|
|
|
|
return $this->issues;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function runSetupChecks() {
|
|
|
|
$this->issues = array();
|
|
|
|
$this->executeChecks();
|
|
|
|
}
|
|
|
|
|
|
|
|
final public static function getOpenSetupIssueCount() {
|
|
|
|
$cache = PhabricatorCaches::getSetupCache();
|
|
|
|
return $cache->getKey('phabricator.setup.issues');
|
|
|
|
}
|
|
|
|
|
|
|
|
final public static function setOpenSetupIssueCount($count) {
|
|
|
|
$cache = PhabricatorCaches::getSetupCache();
|
|
|
|
$cache->setKey('phabricator.setup.issues', $count);
|
|
|
|
}
|
|
|
|
|
2013-02-22 18:21:01 +01:00
|
|
|
final public static function countUnignoredIssues(array $all_issues) {
|
|
|
|
assert_instances_of($all_issues, 'PhabricatorSetupIssue');
|
|
|
|
$count = 0;
|
|
|
|
foreach ($all_issues as $issue) {
|
|
|
|
if (!$issue->getIsIgnored()) {
|
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $count;
|
|
|
|
}
|
|
|
|
|
2013-01-18 01:25:38 +01:00
|
|
|
final public static function getConfigNeedsRepair() {
|
|
|
|
$cache = PhabricatorCaches::getSetupCache();
|
|
|
|
return $cache->getKey('phabricator.setup.needs-repair');
|
|
|
|
}
|
|
|
|
|
|
|
|
final public static function setConfigNeedsRepair($needs_repair) {
|
|
|
|
$cache = PhabricatorCaches::getSetupCache();
|
|
|
|
$cache->setKey('phabricator.setup.needs-repair', $needs_repair);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public static function deleteSetupCheckCache() {
|
|
|
|
$cache = PhabricatorCaches::getSetupCache();
|
|
|
|
$cache->deleteKeys(
|
|
|
|
array(
|
|
|
|
'phabricator.setup.needs-repair',
|
|
|
|
'phabricator.setup.issues',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2012-12-30 15:37:49 +01:00
|
|
|
final public static function willProcessRequest() {
|
|
|
|
$issue_count = self::getOpenSetupIssueCount();
|
2013-01-18 01:25:38 +01:00
|
|
|
if ($issue_count === null) {
|
|
|
|
$issues = self::runAllChecks();
|
2013-01-23 00:16:26 +01:00
|
|
|
foreach ($issues as $issue) {
|
|
|
|
if ($issue->getIsFatal()) {
|
|
|
|
$view = id(new PhabricatorSetupIssueView())
|
|
|
|
->setIssue($issue);
|
|
|
|
return id(new PhabricatorConfigResponse())
|
|
|
|
->setView($view);
|
|
|
|
}
|
|
|
|
}
|
2013-02-22 18:21:01 +01:00
|
|
|
self::setOpenSetupIssueCount(self::countUnignoredIssues($issues));
|
2012-12-30 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
2013-01-18 01:25:38 +01:00
|
|
|
// Try to repair configuration unless we have a clean bill of health on it.
|
|
|
|
// We need to keep doing this on every page load until all the problems
|
|
|
|
// are fixed, which is why it's separate from setup checks (which run
|
|
|
|
// once per restart).
|
|
|
|
$needs_repair = self::getConfigNeedsRepair();
|
|
|
|
if ($needs_repair !== false) {
|
|
|
|
$needs_repair = self::repairConfig();
|
|
|
|
self::setConfigNeedsRepair($needs_repair);
|
|
|
|
}
|
2012-12-30 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
final public static function runAllChecks() {
|
|
|
|
$symbols = id(new PhutilSymbolLoader())
|
|
|
|
->setAncestorClass('PhabricatorSetupCheck')
|
|
|
|
->setConcreteOnly(true)
|
|
|
|
->selectAndLoadSymbols();
|
|
|
|
|
|
|
|
$checks = array();
|
|
|
|
foreach ($symbols as $symbol) {
|
|
|
|
$checks[] = newv($symbol['name'], array());
|
|
|
|
}
|
|
|
|
|
2013-01-23 00:16:26 +01:00
|
|
|
$checks = msort($checks, 'getExecutionOrder');
|
|
|
|
|
2012-12-30 15:37:49 +01:00
|
|
|
$issues = array();
|
|
|
|
foreach ($checks as $check) {
|
|
|
|
$check->runSetupChecks();
|
|
|
|
foreach ($check->getIssues() as $key => $issue) {
|
|
|
|
if (isset($issues[$key])) {
|
|
|
|
throw new Exception(
|
|
|
|
"Two setup checks raised an issue with key '{$key}'!");
|
|
|
|
}
|
|
|
|
$issues[$key] = $issue;
|
2013-01-23 00:16:26 +01:00
|
|
|
if ($issue->getIsFatal()) {
|
|
|
|
break 2;
|
|
|
|
}
|
2012-12-30 15:37:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-22 18:21:01 +01:00
|
|
|
foreach (PhabricatorEnv::getEnvConfig('config.ignore-issues')
|
|
|
|
as $ignorable => $derp) {
|
|
|
|
if (isset($issues[$ignorable])) {
|
|
|
|
$issues[$ignorable]->setIsIgnored(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-30 15:37:49 +01:00
|
|
|
return $issues;
|
|
|
|
}
|
|
|
|
|
2013-01-18 01:25:38 +01:00
|
|
|
final public static function repairConfig() {
|
|
|
|
$needs_repair = false;
|
|
|
|
|
|
|
|
$options = PhabricatorApplicationConfigOptions::loadAllOptions();
|
|
|
|
foreach ($options as $option) {
|
|
|
|
try {
|
|
|
|
$option->getGroup()->validateOption(
|
|
|
|
$option,
|
|
|
|
PhabricatorEnv::getEnvConfig($option->getKey()));
|
|
|
|
} catch (PhabricatorConfigValidationException $ex) {
|
|
|
|
PhabricatorEnv::repairConfig($option->getKey(), $option->getDefault());
|
|
|
|
$needs_repair = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $needs_repair;
|
|
|
|
}
|
|
|
|
|
2012-12-30 15:37:49 +01:00
|
|
|
}
|