• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CPS-IT / project-builder / 11671619573

04 Nov 2024 07:52PM UTC coverage: 96.526%. Remained the same
11671619573

Pull #639

github

web-flow
Merge 76cba5db1 into 1301e6dd7
Pull Request #639: [TASK] Update rector/rector to v1.2.9

2223 of 2303 relevant lines covered (96.53%)

14.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/src/Builder/Generator/Step/CollectBuildInstructionsStep.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer package "cpsit/project-builder".
7
 *
8
 * Copyright (C) 2022 Elias Häußler <e.haeussler@familie-redlich.de>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace CPSIT\ProjectBuilder\Builder\Generator\Step;
25

26
use CPSIT\ProjectBuilder\Builder;
27
use CPSIT\ProjectBuilder\Event;
28
use CPSIT\ProjectBuilder\Exception;
29
use CPSIT\ProjectBuilder\IO;
30
use CPSIT\ProjectBuilder\Twig;
31
use Symfony\Component\EventDispatcher;
32
use Symfony\Component\ExpressionLanguage;
33

34
use function is_string;
35

36
/**
37
 * CollectBuildInstructionsStep.
38
 *
39
 * @author Elias Häußler <e.haeussler@familie-redlich.de>
40
 * @license GPL-3.0-or-later
41
 */
42
final class CollectBuildInstructionsStep extends AbstractStep
43
{
44
    private const TYPE = 'collectBuildInstructions';
45

46
    public function __construct(
17✔
47
        private readonly ExpressionLanguage\ExpressionLanguage $expressionLanguage,
48
        private readonly IO\Messenger $messenger,
49
        private readonly Interaction\InteractionFactory $interactionFactory,
50
        private readonly Twig\Renderer $renderer,
51
        private readonly EventDispatcher\EventDispatcherInterface $eventDispatcher,
52
    ) {
53
        parent::__construct();
17✔
54
    }
55

56
    public function run(Builder\BuildResult $buildResult): bool
15✔
57
    {
58
        $instructions = $buildResult->getInstructions();
15✔
59

60
        foreach ($instructions->getConfig()->getProperties() as $property) {
15✔
61
            if (!$property->conditionMatches($this->expressionLanguage, $instructions->getTemplateVariables(), true)) {
15✔
62
                // Apply NULL as value of property to avoid errors in conditions
63
                // that reference this property in array-notation
64
                $this->apply($property, null, $buildResult);
13✔
65

66
                continue;
13✔
67
            }
68

69
            $this->messenger->section($property->getName());
14✔
70

71
            if ($property->hasValue() && $property->hasSubProperties()) {
14✔
72
                throw Exception\InvalidConfigurationException::forConflictingProperties('value', 'properties');
×
73
            }
74

75
            $this->applyProperty($property, $buildResult);
14✔
76
        }
77

78
        return true;
11✔
79
    }
80

81
    public function revert(Builder\BuildResult $buildResult): void
7✔
82
    {
83
        // Intentionally left blank.
84
    }
7✔
85

86
    public static function getType(): string
17✔
87
    {
88
        return self::TYPE;
17✔
89
    }
90

91
    public static function supports(string $type): bool
14✔
92
    {
93
        return self::TYPE === $type;
14✔
94
    }
95

96
    private function applyProperty(Builder\Config\ValueObject\Property $property, Builder\BuildResult $buildResult): void
14✔
97
    {
98
        if ($property->hasValue()) {
14✔
99
            $this->apply(
1✔
100
                $property,
1✔
101
                $this->renderValue($property->getValue(), $buildResult),
1✔
102
                $buildResult,
1✔
103
            );
1✔
104

105
            return;
1✔
106
        }
107

108
        foreach ($property->getSubProperties() as $subProperty) {
13✔
109
            $subProperty->setParent($property);
13✔
110
            $this->applySubProperty($subProperty, $buildResult);
13✔
111
        }
112
    }
113

114
    private function applySubProperty(Builder\Config\ValueObject\SubProperty $subProperty, Builder\BuildResult $buildResult): void
13✔
115
    {
116
        $instructions = $buildResult->getInstructions();
13✔
117

118
        if (!$subProperty->conditionMatches($this->expressionLanguage, $instructions->getTemplateVariables(), true)) {
13✔
119
            // Apply NULL as value of sub-property to avoid errors in conditions
120
            // that reference this sub-property in array-notation
121
            $this->apply($subProperty, null, $buildResult);
1✔
122

123
            return;
1✔
124
        }
125

126
        if ($subProperty->hasValue()) {
12✔
127
            $this->apply($subProperty, $subProperty->getValue(), $buildResult);
×
128

129
            return;
×
130
        }
131

132
        switch ($subProperty->getType()) {
12✔
133
            case 'dynamicSelect':
12✔
134
                $value = $this->processOptions($subProperty->getOptions(), $instructions);
×
135

136
                break;
×
137

138
            default:
139
                $interaction = $this->interactionFactory->get($subProperty->getType());
12✔
140
                $value = $interaction->interact($subProperty, $instructions);
12✔
141

142
                break;
8✔
143
        }
144

145
        $this->apply($subProperty, $value, $buildResult);
8✔
146
    }
147

148
    private function apply(
15✔
149
        Builder\Config\ValueObject\Property|Builder\Config\ValueObject\SubProperty $property,
150
        mixed $value,
151
        Builder\BuildResult $buildResult,
152
    ): void {
153
        $event = new Event\BuildInstructionCollectedEvent($property, $property->getPath(), $value, $buildResult);
15✔
154

155
        $this->eventDispatcher->dispatch($event);
15✔
156

157
        $buildResult->getInstructions()->addTemplateVariable($event->getPath(), $event->getValue());
15✔
158
        $buildResult->applyStep($this);
15✔
159
    }
160

161
    /**
162
     * @param list<Builder\Config\ValueObject\PropertyOption> $options
163
     */
164
    private function processOptions(array $options, Builder\BuildInstructions $instructions): mixed
×
165
    {
166
        foreach ($options as $option) {
×
167
            // A condition is required for dynamic selections
168
            if ($option->conditionMatches($this->expressionLanguage, $instructions->getTemplateVariables())) {
×
169
                return $option->getValue();
×
170
            }
171
        }
172

173
        return null;
×
174
    }
175

176
    private function renderValue(float|bool|int|string|null $value, Builder\BuildResult $buildResult): int|float|string|bool|null
1✔
177
    {
178
        if (!is_string($value)) {
1✔
179
            return $value;
1✔
180
        }
181

182
        return $this->renderer->withDefaultTemplate($value)->render($buildResult->getInstructions());
1✔
183
    }
184
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc