1 | <?php |
||
7 | class GroupParser extends AbstractSectionParser |
||
8 | { |
||
9 | private array |
||
|
|||
10 | $groups, |
||
11 | $defaultEnvironments; |
||
12 | |||
13 | 270 | public function __construct() |
|
14 | { |
||
15 | 270 | parent::__construct(); |
|
16 | |||
17 | 270 | $this->groups = []; |
|
18 | 270 | $this->defaultEnvironments = []; |
|
19 | 270 | } |
|
20 | |||
21 | 23 | protected function parseLine(string $line): void |
|
22 | { |
||
23 | 23 | $line = trim($line); |
|
24 | |||
25 | 23 | if(preg_match('~(?P<groupName>[^=]+)\s*=\s*\[(?P<envList>[^\[\]]+)\]$~', $line, $matches)) |
|
26 | { |
||
27 | 15 | $this->processGroupDefinition($matches['groupName'], $matches['envList']); |
|
28 | |||
29 | 10 | return; |
|
30 | } |
||
31 | |||
32 | 8 | $this->triggerError($line); |
|
33 | } |
||
34 | |||
35 | 15 | private function processGroupDefinition(string $groupName, string $envList): void |
|
36 | { |
||
37 | 15 | $groupName = trim($groupName); |
|
38 | |||
39 | 15 | $this->checkGroupStillNotExists($groupName); |
|
40 | |||
41 | 15 | $environments = array_map('trim', explode(',', $envList)); |
|
42 | 15 | $environments = $this->checkForDefaultMarker($groupName, $environments); |
|
43 | 14 | $this->checkEnvironmentAreUnique($groupName, $environments); |
|
44 | |||
45 | 13 | $this->groups[$groupName] = []; |
|
46 | |||
47 | 13 | foreach($environments as $env) |
|
48 | { |
||
49 | 13 | if(empty($env)) |
|
50 | { |
||
51 | 3 | $this->triggerError("empty environment in declaration of group $groupName"); |
|
52 | } |
||
53 | |||
54 | 12 | $this->groups[$groupName][] = $env; |
|
55 | } |
||
56 | 10 | } |
|
57 | |||
58 | 15 | private function checkForDefaultMarker(string $groupName, array $environments): array |
|
59 | { |
||
60 | 15 | $environmentNames = []; |
|
61 | 15 | $this->defaultEnvironments[$groupName] = null; |
|
62 | |||
63 | 15 | foreach($environments as $envString) |
|
64 | { |
||
65 | 15 | $name = $envString; |
|
66 | |||
67 | 15 | if(preg_match('~\*\s*(?P<envName>.*)~', $envString, $matches)) |
|
68 | { |
||
69 | 3 | $name = $matches['envName']; |
|
70 | |||
71 | 3 | if(isset($this->defaultEnvironments[$groupName])) |
|
72 | { |
||
73 | 1 | throw new \RuntimeException(sprintf( |
|
74 | 1 | 'Group %s must have only one default environment : %s and %s are declared as default', |
|
75 | $groupName, |
||
76 | 1 | $this->defaultEnvironments[$groupName], |
|
77 | $name |
||
78 | )); |
||
79 | } |
||
80 | |||
81 | 3 | $this->defaultEnvironments[$groupName] = $name; |
|
82 | } |
||
83 | |||
84 | 15 | $environmentNames[] = $name; |
|
85 | } |
||
86 | |||
87 | 14 | return $environmentNames; |
|
88 | } |
||
89 | |||
90 | 15 | private function checkGroupStillNotExists(string $groupName): void |
|
91 | { |
||
92 | 15 | if(isset($this->groups[$groupName])) |
|
93 | { |
||
94 | 1 | $this->triggerError("group $groupName has already been declared"); |
|
95 | } |
||
96 | 15 | } |
|
97 | |||
98 | 14 | private function checkEnvironmentAreUnique(string $groupName, array $environments): void |
|
99 | { |
||
100 | 14 | if($this->hasDuplicatedValues($environments)) |
|
101 | { |
||
102 | 1 | $this->triggerError("duplicated environment in group $groupName"); |
|
103 | } |
||
104 | 13 | } |
|
105 | |||
106 | 240 | private function hasDuplicatedValues(array $values): bool |
|
107 | { |
||
108 | 240 | $duplicatedValues = array_filter(array_count_values($values), function ($counter) { |
|
109 | 14 | return $counter !== 1; |
|
110 | 240 | }); |
|
111 | |||
112 | 240 | return empty($duplicatedValues) === false; |
|
113 | } |
||
114 | |||
115 | 38 | public function getCollectedGroups(): array |
|
116 | { |
||
117 | 38 | return $this->groups; |
|
118 | } |
||
119 | |||
120 | 235 | public function postParse(): void |
|
121 | { |
||
122 | 235 | $this->checkEnvironmentsBelongToOnlyOneGroup(); |
|
123 | 234 | $this->checkGroupsAreNotPartsOfAnotherGroups(); |
|
124 | 233 | } |
|
125 | |||
126 | 235 | private function checkEnvironmentsBelongToOnlyOneGroup(): void |
|
127 | { |
||
128 | 235 | $allEnvironments = $this->getAllEnvironmentsBelongingToGroups(); |
|
129 | |||
130 | 235 | if($this->hasDuplicatedValues($allEnvironments)) |
|
131 | { |
||
132 | 1 | throw new \RuntimeException('Error : some environments are in various groups'); |
|
133 | } |
||
134 | 234 | } |
|
135 | |||
136 | 235 | private function getAllEnvironmentsBelongingToGroups(): array |
|
137 | { |
||
138 | 235 | $allEnvironments = []; |
|
139 | |||
140 | 235 | foreach($this->groups as $group) |
|
141 | { |
||
142 | 9 | $allEnvironments = array_merge($allEnvironments, $group); |
|
143 | } |
||
144 | |||
145 | 235 | return $allEnvironments; |
|
146 | } |
||
147 | |||
148 | 234 | private function checkGroupsAreNotPartsOfAnotherGroups(): void |
|
149 | { |
||
150 | 234 | $allEnvironments = $this->getAllEnvironmentsBelongingToGroups(); |
|
151 | |||
152 | 234 | $errors = array_intersect($allEnvironments, array_keys($this->groups)); |
|
153 | |||
154 | 234 | if(! empty($errors)) |
|
155 | { |
||
156 | 1 | throw new \RuntimeException(sprintf( |
|
157 | 1 | 'Error : a group can not be part of another group (%s)', |
|
158 | 1 | implode(', ', $errors) |
|
159 | )); |
||
160 | } |
||
161 | 233 | } |
|
162 | |||
163 | 33 | public function getDefaultEnvironmentsForGroups(): array |
|
164 | { |
||
165 | 33 | return $this->defaultEnvironments; |
|
166 | } |
||
167 | } |
||
168 |