Skip to content

Commit ef3e8da

Browse files
fixing doc generator
1 parent 7b340d6 commit ef3e8da

File tree

1 file changed

+161
-11
lines changed

1 file changed

+161
-11
lines changed

Kununu/ArchitectureTest/DocGenerator.php

Lines changed: 161 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,181 @@
77
require $root . '/vendor/autoload.php';
88

99
use Kununu\ArchitectureTest\DirectoryFinder;
10+
use Kununu\ArchitectureTest\Configuration\Layer;
1011

1112
$outputDir = DirectoryFinder::getProjectDirectory() . '/doc/architecture';
12-
$outputFile = $outputDir . '/architecture.mmd';
13+
$outputFile = $outputDir . '/architecture-diagram.mmd';
1314

1415
if (!is_dir($outputDir)) {
1516
if (!mkdir($outputDir, 0755, true) && !is_dir($outputDir)) {
1617
throw new RuntimeException(sprintf('Directory "%s" was not created', $outputDir));
1718
}
1819
}
1920

20-
$architectureDefinition = DirectoryFinder::getArchitectureDefinitionFile();
21+
$architectureDefinition = DirectoryFinder::getArchitectureDefinition();
2122

22-
$mmdContent = "C4Context\n";
23-
function addLayerToMmd(array $layers, &$content): void
24-
{
25-
foreach ($layers as $layer) {
26-
$content .= " title Architecture Diagram\n";
27-
$content .= " Enterprise_Boundary(b0, \"{$layer['layer']}\"){\n";
23+
$content = "C4Context\n";
24+
$content .= "title Architecture Diagram\n";
25+
$layersTrack = [];
26+
$componentsTrack = [];
27+
$innerDependenciesTrack = [];
28+
$dependenciesTrack = [];
29+
$externalDependenciesTrack = [];
30+
$trackedRelations = [];
31+
$relations = "";
32+
$i = 0;
33+
$j = 0;
34+
$k = 0;
35+
foreach ($architectureDefinition['architecture'] as $layerData) {
36+
$layer = Layer::fromArray($layerData);
37+
$layersTrack[$layer->selector->getName()] = $i;
38+
$i++;
39+
}
40+
41+
foreach ($architectureDefinition['architecture'] as $layerData) {
42+
$layer = Layer::fromArray($layerData);
43+
$outerLayerNr = $layersTrack[$layer->selector->getName()];
44+
$content .= "Container_Boundary(b$outerLayerNr, \"{$layer->name}\"){\n";
45+
46+
/** @var \Kununu\ArchitectureTest\Configuration\SubLayer $subLayer */
47+
foreach ($layer->subLayers as $subLayer) {
48+
$componentsTrack[$subLayer->selector->getName()] = $j;
49+
$trackedRelations[$j] = [];
50+
$innerDependenciesTrack[$j] = [];
51+
$finalText = "";
52+
foreach($subLayer->rules as $rule) {
53+
if ($rule instanceof \Kununu\ArchitectureTest\Configuration\Rules\MustBeFinal) {
54+
$finalText = "🔒 ";
55+
}
56+
57+
if ($rule instanceof \Kununu\ArchitectureTest\Configuration\Rules\MustOnlyDependOnWhitelist) {
58+
/** @var \Kununu\ArchitectureTest\Configuration\Selector\Selectable $dependency */
59+
foreach ($rule->dependencyWhitelist as $dependency) {
60+
$name = $dependency->getName();
61+
if (str_starts_with($name, "\\")) {
62+
$name = substr($dependency->getName(), 1);
63+
}
64+
if (str_ends_with($name, "\\")) {
65+
$name = substr($name, 0, -1);
66+
}
67+
if (str_starts_with($name, '*')) {
68+
continue;
69+
}
70+
71+
if (str_starts_with($name, 'App')) {
72+
$outerLayerOfDependency = "App\\" . explode('\\', $name)[1];
73+
$currentOuterLayer = $layer->selector->getName();
74+
if ($outerLayerOfDependency === $currentOuterLayer) {
75+
continue;
76+
}
77+
if (in_array($outerLayerOfDependency, array_keys($layersTrack), true)) {
78+
$innerDependenciesTrack[$j][$subLayer->selector->getName()] = $name;
79+
continue;
80+
}
81+
$dependenciesTrack[$name] = $k;
82+
continue;
83+
}
84+
if (!array_key_exists($name, $dependenciesTrack)) {
85+
$dependenciesTrack[$name] = $k;
86+
$trackedRelations[$j][] = $k;
87+
$k++;
88+
}
89+
$number = $dependenciesTrack[$name];
90+
$trackedRelations[$j][] = $number;
91+
}
92+
}
93+
}
94+
$content .= " Component(\"c$j\", \"$finalText{$subLayer->name}\", \"{$subLayer->selector->getName()}\")\n";
95+
$j++;
96+
}
97+
$content .= "}\n\n"; // End the main layer block
98+
}
99+
100+
if (array_key_exists('deprecated', $architectureDefinition)) {
101+
foreach ($architectureDefinition['deprecated'] as $layerData) {
102+
$layer = Layer::fromArray($layerData);
103+
$layersCount[$layer->selector->getName()] = $i;
104+
$content .= "Container_Boundary(b$i, \"{$layerData['layer']}\"){\n";
105+
foreach($dependenciesTrack as $name => $number) {
106+
if (str_starts_with($name, $layer->selector->getName())) {
107+
$nameSpaces = explode('\\', $name);
108+
$className = $nameSpaces[count($nameSpaces) - 1];
109+
$content .= " Component(\"e$number\", \"Deprecated $className\", \"$name\")\n";
110+
} else {
111+
if (str_starts_with($name, 'App')) {
112+
continue;
113+
}
114+
$externalContainer = explode('\\', $name)[0];
115+
if (!array_key_exists($externalContainer, $externalDependenciesTrack)) {
116+
$externalDependenciesTrack[$externalContainer] = [
117+
$name => $number
118+
];
119+
continue;
120+
}
121+
$externalDependenciesTrack[$externalContainer][$name] = $number;
122+
}
123+
}
124+
$content .= "}\n\n"; // End the main layer block
125+
$i++;
126+
}
127+
} else {
128+
$externalDependenciesTrack = $dependenciesTrack;
129+
}
130+
131+
$externalComponentsTrack = [];
132+
foreach ($externalDependenciesTrack as $container => $external) {
133+
$content .= "Container_Boundary(b$i, \"{$container}\"){\n";
134+
foreach ($external as $name => $number) {
135+
$nameSpaces = explode('\\', $name);
136+
$className = $nameSpaces[count($nameSpaces) - 1];
137+
$content .= " Component(\"e$number\", \"$className\", \"$name\")\n";
138+
$externalComponentsTrack[$name] = $number;
139+
}
140+
$content .= "}\n\n"; // End the main layer block
141+
$i++;
142+
}
143+
144+
$trackedInnerRelations = [];
145+
foreach ($innerDependenciesTrack as $componentNumber => $connections) {
146+
$trackedInnerRelations[$componentNumber] = [];
147+
foreach($connections as $sourceComponent => $dependency) {
148+
$nameSpaces = explode('\\', $dependency);
149+
foreach ($componentsTrack as $component => $externalNumber) {
150+
if (count($nameSpaces) < 3) {
151+
if ($component === $dependency) {
152+
$trackedInnerRelations[$componentNumber][] = $externalNumber;
153+
}
154+
continue;
155+
}
156+
$shortedName = $nameSpaces[0] . '/' . $nameSpaces[1] . '/' . $nameSpaces[2];
157+
if (str_starts_with($component, $shortedName)) {
158+
$nameSpaces = explode('\\', $name);
159+
$className = $nameSpaces[count($nameSpaces) - 1];
160+
$trackedInnerRelations[$componentNumber][] = $externalNumber;
161+
}
162+
}
163+
}
164+
}
165+
166+
foreach($trackedRelations as $number => $externalNumbers) {
167+
foreach(array_unique($externalNumbers) as $externalNumber) {
168+
if (!in_array($externalNumber, $externalComponentsTrack, true)) {
169+
var_dump("Missing external Component nr $externalNumber");
170+
continue;
171+
}
172+
$relations .= "Rel(c$number, e$externalNumber, \"Can depend on\", \"DI\")\n";
173+
$relations .= "UpdateRelStyle(c$number, e$externalNumber, \$textColor=\"red\", \$offsetY=\"-40\")\n";
174+
}
175+
}
28176

29-
$content .= " }\n\n"; // End the main layer block
177+
foreach ($trackedInnerRelations as $number => $innerNumbers) {
178+
foreach(array_unique($innerNumbers) as $innerNumber) {
179+
$relations .= "Rel(c$number, c$innerNumber, \"Can depend on\", \"DI\")\n";
30180
}
31181
}
32182

33-
addLayerToMmd($architectureDefinition['architecture'], $mmdContent);
183+
$content .= $relations;
34184

35-
file_put_contents($outputFile, $mmdContent);
185+
file_put_contents($outputFile, $content);
36186

37187
echo 'Mermaid file generated at: ' . $outputFile . PHP_EOL;

0 commit comments

Comments
 (0)