mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW Allow debugging of config cyclic errors
It is possible to specify before and after rules on config fragments that conflict - A before B and B before A isnt possible to solve. This used to just throw an error with no way to debug. Now if you specify debug as a GET parameter and the site is not in live mode youll get a basic dump of the remaining DAG graph
This commit is contained in:
parent
e0b8f15171
commit
6009cfadc2
65
core/DAG.php
65
core/DAG.php
@ -4,7 +4,7 @@
|
|||||||
* A Directed Acyclic Graph - used for doing topological sorts on dependencies, such as the before/after conditions
|
* A Directed Acyclic Graph - used for doing topological sorts on dependencies, such as the before/after conditions
|
||||||
* in config yaml fragments
|
* in config yaml fragments
|
||||||
*/
|
*/
|
||||||
class SS_DAG {
|
class SS_DAG implements IteratorAggregate {
|
||||||
/** @var array|null - The nodes/vertices in the graph. Should be a numeric sequence of items (no string keys, no gaps). */
|
/** @var array|null - The nodes/vertices in the graph. Should be a numeric sequence of items (no string keys, no gaps). */
|
||||||
protected $data;
|
protected $data;
|
||||||
|
|
||||||
@ -68,7 +68,68 @@ class SS_DAG {
|
|||||||
$dag = $withedges;
|
$dag = $withedges;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($dag) throw new Exception("DAG has cyclic requirements");
|
if ($dag) {
|
||||||
|
$remainder = new SS_DAG($data); $remainder->dag = $dag;
|
||||||
|
throw new SS_DAG_CyclicException("DAG has cyclic requirements", $remainder);
|
||||||
|
}
|
||||||
return $sorted;
|
return $sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getIterator() {
|
||||||
|
return new SS_DAG_Iterator($this->data, $this->dag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SS_DAG_CyclicException extends Exception {
|
||||||
|
|
||||||
|
public $dag;
|
||||||
|
|
||||||
|
function __construct($message, $dag) {
|
||||||
|
$this->dag = $dag;
|
||||||
|
parent::__construct($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class SS_DAG_Iterator implements Iterator {
|
||||||
|
|
||||||
|
protected $data;
|
||||||
|
protected $dag;
|
||||||
|
|
||||||
|
protected $dagkeys;
|
||||||
|
protected $i;
|
||||||
|
|
||||||
|
function __construct($data, $dag) {
|
||||||
|
$this->data = $data;
|
||||||
|
$this->dag = $dag;
|
||||||
|
$this->rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
function key() {
|
||||||
|
return $this->i;
|
||||||
|
}
|
||||||
|
|
||||||
|
function current() {
|
||||||
|
$res = array();
|
||||||
|
|
||||||
|
$res['from'] = $this->data[$this->i];
|
||||||
|
|
||||||
|
$res['to'] = array();
|
||||||
|
foreach ($this->dag[$this->i] as $to) $res['to'][] = $this->data[$to];
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
$this->i = array_shift($this->dagkeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rewind() {
|
||||||
|
$this->dagkeys = array_keys($this->dag);
|
||||||
|
$this->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
function valid() {
|
||||||
|
return $this->i !== null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,30 @@ class SS_ConfigManifest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->yamlConfigFragments = $dag->sort();
|
try {
|
||||||
|
$this->yamlConfigFragments = $dag->sort();
|
||||||
|
}
|
||||||
|
catch (SS_DAG_CyclicException $e) {
|
||||||
|
|
||||||
|
if (!Director::isLive() && isset($_REQUEST['debug'])) {
|
||||||
|
$res = '<h1>Remaining config fragment graph</h1>';
|
||||||
|
$res .= '<dl>';
|
||||||
|
|
||||||
|
foreach ($e->dag as $node) {
|
||||||
|
$res .= "<dt>{$node['from']['module']}/{$node['from']['file']}#{$node['from']['name']} marked to come after</dt><dd><ul>";
|
||||||
|
foreach ($node['to'] as $to) {
|
||||||
|
$res .= "<li>{$to['module']}/{$to['file']}#{$to['name']}</li>";
|
||||||
|
}
|
||||||
|
$res .= "</ul></dd>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$res .= '</dl>';
|
||||||
|
echo $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user