ChangelogDefinition::validate()   F
last analyzed

Complexity

Conditions 19
Paths 1296

Size

Total Lines 48
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 28
nc 1296
nop 1
dl 0
loc 48
rs 0.3499
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\Framework\Changelog;
4
5
use Shopware\Core\Framework\Feature;
6
use Shopware\Core\Framework\Log\Package;
7
use Symfony\Component\Validator\Constraints as Assert;
8
use Symfony\Component\Validator\Context\ExecutionContextInterface;
9
10
/**
11
 * @internal
12
 */
13
#[Package('core')]
14
class ChangelogDefinition
15
{
16
    private const VIOLATION_MESSAGE_SECTION_SEPARATOR = 'You should use "___" to separate %s and %s section';
17
    private const VIOLATION_MESSAGE_STARTING_KEYWORD = "Changelog entry \"%s\" does not start with a valid keyword (%s).\nPlease have look at the handbook: https://handbook.shopware.com/Product/Guides/Development/WritingChangelog#changelog-entries";
18
19
    #[Assert\NotBlank(message: 'The title should not be blank')]
20
    private string $title;
21
22
    #[Assert\NotBlank(message: 'The Jira ticket should not be blank')]
23
    #[Assert\Regex(pattern: '/^NEXT-\d+$/', message: 'The Jira ticket has an invalid format')]
24
    private string $issue;
25
26
    private ?string $flag = null;
27
28
    private ?string $author = null;
29
30
    private ?string $authorEmail = null;
31
32
    private ?string $authorGitHub = null;
33
34
    private ?string $core = null;
35
36
    private ?string $storefront = null;
37
38
    private ?string $administration = null;
39
40
    private ?string $api = null;
41
42
    private ?string $upgrade = null;
43
44
    private ?string $nextMajorVersionChanges = null;
45
46
    #[Assert\Callback]
47
    public function validate(ExecutionContextInterface $context): void
48
    {
49
        if (empty($this->api) && empty($this->core) && empty($this->storefront) && empty($this->administration)) {
50
            $context->buildViolation('You have to define at least one change of API, Core, Administration or Storefront')
51
                ->addViolation();
52
        }
53
54
        if ($this->api) {
55
            if (preg_match('/\n+#\s+(\w+)/', $this->api, $matches)) {
56
                $this->buildViolationSectionSeparator($context, ChangelogSection::api, $matches[1]);
57
            }
58
            $this->checkChangelogEntries($context, $this->api, ChangelogSection::api);
59
        }
60
61
        if ($this->storefront) {
62
            if (preg_match('/\n+#\s+(\w+)/', $this->storefront, $matches)) {
63
                $this->buildViolationSectionSeparator($context, ChangelogSection::storefront, $matches[1]);
64
            }
65
            $this->checkChangelogEntries($context, $this->storefront, ChangelogSection::storefront);
66
        }
67
68
        if ($this->administration) {
69
            if (preg_match('/\n+#\s+(\w+)/', $this->administration, $matches)) {
70
                $this->buildViolationSectionSeparator($context, ChangelogSection::administration, $matches[1]);
71
            }
72
            $this->checkChangelogEntries($context, $this->administration, ChangelogSection::administration);
73
        }
74
75
        if ($this->core) {
76
            if (preg_match('/\n+#\s+(\w+)/', $this->core, $matches)) {
77
                $this->buildViolationSectionSeparator($context, ChangelogSection::core, $matches[1]);
78
            }
79
            $this->checkChangelogEntries($context, $this->core, ChangelogSection::core);
80
        }
81
82
        if ($this->upgrade && preg_match('/\n+#\s+(\w+)/', $this->upgrade, $matches)) {
83
            $this->buildViolationSectionSeparator($context, ChangelogSection::upgrade, $matches[1]);
84
        }
85
86
        if ($this->nextMajorVersionChanges && preg_match('/\n+#\s+(\w+)/', $this->nextMajorVersionChanges, $matches)) {
87
            $this->buildViolationSectionSeparator($context, ChangelogSection::major, $matches[1]);
88
        }
89
90
        if ($this->flag && !Feature::has($this->flag)) {
91
            $context->buildViolation(sprintf('Unknown flag %s is assigned ', $this->flag))
92
                ->atPath('flag')
93
                ->addViolation();
94
        }
95
    }
96
97
    public function getTitle(): string
98
    {
99
        return $this->title;
100
    }
101
102
    public function setTitle(string $title): ChangelogDefinition
103
    {
104
        $this->title = $title;
105
106
        return $this;
107
    }
108
109
    public function getIssue(): string
110
    {
111
        return $this->issue;
112
    }
113
114
    public function setIssue(string $issue): ChangelogDefinition
115
    {
116
        $this->issue = $issue;
117
118
        return $this;
119
    }
120
121
    public function getFlag(): ?string
122
    {
123
        return $this->flag;
124
    }
125
126
    public function setFlag(?string $flag): ChangelogDefinition
127
    {
128
        $this->flag = $flag;
129
130
        return $this;
131
    }
132
133
    public function getAuthor(): ?string
134
    {
135
        return $this->author;
136
    }
137
138
    public function setAuthor(?string $author): ChangelogDefinition
139
    {
140
        $this->author = $author;
141
142
        return $this;
143
    }
144
145
    public function getAuthorEmail(): ?string
146
    {
147
        return $this->authorEmail;
148
    }
149
150
    public function setAuthorEmail(?string $authorEmail): ChangelogDefinition
151
    {
152
        $this->authorEmail = $authorEmail;
153
154
        return $this;
155
    }
156
157
    public function getAuthorGitHub(): ?string
158
    {
159
        return $this->authorGitHub;
160
    }
161
162
    public function setAuthorGitHub(?string $authorGitHub): ChangelogDefinition
163
    {
164
        $this->authorGitHub = $authorGitHub;
165
166
        return $this;
167
    }
168
169
    public function getCore(): ?string
170
    {
171
        return $this->core;
172
    }
173
174
    public function setCore(?string $core): ChangelogDefinition
175
    {
176
        $this->core = $core;
177
178
        return $this;
179
    }
180
181
    public function getStorefront(): ?string
182
    {
183
        return $this->storefront;
184
    }
185
186
    public function setStorefront(?string $storefront): ChangelogDefinition
187
    {
188
        $this->storefront = $storefront;
189
190
        return $this;
191
    }
192
193
    public function getAdministration(): ?string
194
    {
195
        return $this->administration;
196
    }
197
198
    public function setAdministration(?string $administration): ChangelogDefinition
199
    {
200
        $this->administration = $administration;
201
202
        return $this;
203
    }
204
205
    public function getApi(): ?string
206
    {
207
        return $this->api;
208
    }
209
210
    public function setApi(?string $api): ChangelogDefinition
211
    {
212
        $this->api = $api;
213
214
        return $this;
215
    }
216
217
    public function getUpgradeInformation(): ?string
218
    {
219
        return $this->upgrade;
220
    }
221
222
    public function setUpgradeInformation(?string $upgrade): ChangelogDefinition
223
    {
224
        $this->upgrade = $upgrade;
225
226
        return $this;
227
    }
228
229
    public function setNextMajorVersionChanges(?string $nextMajorVersionChanges): ChangelogDefinition
230
    {
231
        $this->nextMajorVersionChanges = $nextMajorVersionChanges;
232
233
        return $this;
234
    }
235
236
    public function getNextMajorVersionChanges(): ?string
237
    {
238
        return $this->nextMajorVersionChanges;
239
    }
240
241
    public function toTemplate(): string
242
    {
243
        $template = <<<EOD
244
---
245
title: $this->title
246
issue: $this->issue
247
%FEATURE_FLAG%
248
%AUTHOR%
249
%AUTHOR_EMAIL%
250
%AUTHOR_GITHUB%
251
---
252
# Core
253
*
254
___
255
# API
256
*
257
___
258
# Administration
259
*
260
___
261
# Storefront
262
*
263
___
264
# Upgrade Information
265
## Topic 1
266
### Topic 1a
267
### Topic 1b
268
## Topic 2
269
___
270
# Next Major Version Changes
271
## Breaking Change 1:
272
* Do this
273
## Breaking Change 2:
274
change
275
```
276
static
277
```
278
to
279
```
280
self
281
```
282
EOD;
283
        $template = str_replace('%FEATURE_FLAG%', $this->flag ? 'flag: ' . $this->flag : '', $template);
284
        $template = str_replace('%AUTHOR%', $this->author ? 'author: ' . $this->author : '', $template);
285
        $template = str_replace('%AUTHOR_EMAIL%', $this->authorEmail ? 'author_email: ' . $this->authorEmail : '', $template);
286
        $template = str_replace('%AUTHOR_GITHUB%', $this->authorGitHub ? 'author_github: ' . $this->authorGitHub : '', $template);
287
        $template = str_replace("\n\n", "\n", $template);
288
289
        return trim($template);
290
    }
291
292
    private function buildViolationSectionSeparator(ExecutionContextInterface $context, ChangelogSection $currentSection, string $nextSection): void
293
    {
294
        $context->buildViolation(sprintf(self::VIOLATION_MESSAGE_SECTION_SEPARATOR, $currentSection->value, $nextSection))
295
            ->atPath($currentSection->name)
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on Shopware\Core\Framework\Changelog\ChangelogSection.
Loading history...
296
            ->addViolation();
297
    }
298
299
    private function checkChangelogEntries(ExecutionContextInterface $context, ?string $changelogPart, ChangelogSection $currentSection): void
300
    {
301
        if (!\is_string($changelogPart)) {
302
            return;
303
        }
304
305
        $changelogEntries = explode("\n", $changelogPart);
306
        foreach ($changelogEntries as $changelogEntry) {
307
            if (!str_starts_with($changelogEntry, '*')) {
308
                continue;
309
            }
310
            // Remove leading asterisk and spaces around changelog entry
311
            $changelogEntry = trim(substr($changelogEntry, 1));
312
            if ($changelogEntry === '') {
313
                continue;
314
            }
315
316
            foreach (ChangelogKeyword::cases() as $allowedChangelogKeyword) {
317
                if (str_starts_with($changelogEntry, $allowedChangelogKeyword->value)) {
318
                    continue 2;
319
                }
320
            }
321
            $context->buildViolation(sprintf(self::VIOLATION_MESSAGE_STARTING_KEYWORD, $changelogEntry, implode(', ', array_column(ChangelogKeyword::cases(), 'value'))))
322
                ->atPath($currentSection->name)
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on Shopware\Core\Framework\Changelog\ChangelogSection.
Loading history...
323
                ->addViolation();
324
        }
325
    }
326
}
327