Issues (2)

src/Config.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Vasoft\VersionIncrement;
6
7
use Vasoft\VersionIncrement\Commits\CommitCollection;
8
use Vasoft\VersionIncrement\Commits\CommitCollectionFactory;
9
use Vasoft\VersionIncrement\Contract\ChangelogFormatterInterface;
10
use Vasoft\VersionIncrement\Contract\CommitParserInterface;
11
use Vasoft\VersionIncrement\Contract\SectionRuleInterface;
12
use Vasoft\VersionIncrement\Contract\TagFormatterInterface;
13
use Vasoft\VersionIncrement\Contract\VcsExecutorInterface;
14
use Vasoft\VersionIncrement\Core\Sections;
15
use Vasoft\VersionIncrement\Events\EventBus;
16
use Vasoft\VersionIncrement\Exceptions\UnknownPropertyException;
17
use Vasoft\VersionIncrement\SectionRules\DefaultRule;
18
19
/**
20
 * Class Config.
21
 *
22
 * Represents the configuration for the version increment tool. This class provides methods to configure various
23
 * aspects of the tool, such as sections, rules, version control settings, and formatters. It also manages default
24
 * configurations and ensures consistency across the application.
25
 */
26
final class Config
27
{
28
    private ?EventBus $eventBus = null;
29
    private ?CommitCollection $commitCollection = null;
30
    private array $scopes = [];
31
    private array $props = [];
32
    private string $squashedCommitMessage = 'Squashed commit of the following:';
33
    private bool $processDefaultSquashedCommit = false;
34
    private array $minorTypes = [
35
        'feat',
36
    ];
37
    private array $majorTypes = [];
38
    private array $sectionRules = [];
39
    public const DEFAULT_SECTION = 'other';
40
    private string $masterBranch = 'master';
41
    private string $releaseSection = 'chore';
42
    private string $releaseScope = 'release';
43
    private string $aggregateSection = '';
44
    private bool $enabledComposerVersioning = true;
45
    private ?ChangelogFormatterInterface $changelogFormatter = null;
46
    private ?CommitParserInterface $commitParser = null;
47
    private ?VcsExecutorInterface $vcsExecutor = null;
48
    private ?TagFormatterInterface $tagFormatter = null;
49
    private bool $hideDoubles = false;
50
    private bool $ignoreUntrackedFiles = false;
51
    private readonly Sections $sections;
52
53 56
    public function __construct()
54
    {
55 56
        $this->sections = new Sections();
0 ignored issues
show
The property sections is declared read-only in Vasoft\VersionIncrement\Config.
Loading history...
56
    }
57
58
    /**
59
     * Sets the sections configuration for the tool.
60
     *
61
     * This method allows you to define a custom set of sections, each with its own title, order, and visibility settings.
62
     * Existing sections are cleared before applying the new configuration. The order of sections is reset, and the default
63
     * section (`other`) will be added automatically if not explicitly defined.
64
     *
65
     * Each section can be configured with the following optional parameters:
66
     * - `title`: The display name of the section in the CHANGELOG (defaults to the section key).
67
     * - `order`: The sorting priority of the section (auto-incremented if not provided).
68
     * - `hidden`: Whether the section should be hidden in the CHANGELOG (defaults to `false`).
69
     *
70
     * @param array $sections an associative array where keys are section codes and values are arrays containing
71
     *                        the section's configuration (`title`, `order`, and `hidden`)
72
     *
73
     * @return $this this Config instance for method chaining
74
     */
75 7
    public function setSections(array $sections): self
76
    {
77 7
        $this->sections->setSections($sections);
78
79 7
        return $this;
80
    }
81
82
    /**
83
     * Sets or updates the configuration for a specific section.
84
     *
85
     * This method allows you to define or modify the settings of a section, such as its title, order, and visibility.
86
     * If the section already exists, its configuration is updated; otherwise, a new section is created. Existing values
87
     * for `order` and `hidden` are preserved unless explicitly overridden.
88
     *
89
     * @param string    $key    the unique identifier (code) of the section
90
     * @param string    $title  the display name of the section in the CHANGELOG
91
     * @param int       $order  The sorting priority of the section. Defaults to `-1`, which preserves the existing order
92
     *                          or assigns a new auto-incremented value if the section does not exist.
93
     * @param null|bool $hidden Whether the section should be hidden in the CHANGELOG. Defaults to `null`, which
94
     *                          preserves the existing visibility setting or sets it to `false` if the section
95
     *                          does not exist.
96
     *
97
     * @return $this this Config instance for method chaining
98
     */
99 3
    public function setSection(
100
        string $key,
101
        string $title,
102
        int $order = -1,
103
        ?bool $hidden = null,
104
    ): self {
105 3
        $this->sections->setSection($key, $title, $order, $hidden);
106
107 3
        return $this;
108
    }
109
110 7
    public function getSections(): Sections
111
    {
112 7
        return $this->sections;
113
    }
114
115
    /**
116
     * Retrieves the commit collection based on the configured sections.
117
     *
118
     * This method creates a `CommitCollection` object by converting the configured sections into `Section` objects.
119
     * It ensures that all sections are sorted and that a default section exists if not explicitly defined.
120
     *
121
     * @return CommitCollection a collection of commits grouped by sections
122
     */
123 27
    public function getCommitCollection(): CommitCollection
124
    {
125 27
        return $this->commitCollection ??= (new CommitCollectionFactory(
126 27
            $this,
127 27
            $this->majorTypes,
128 27
            $this->minorTypes,
129 27
            self::DEFAULT_SECTION,
130 27
        ))->getCollection($this->sections->getSortedSections());
131
    }
132
133
    /**
134
     * Sets the section to be used for release commits.
135
     *
136
     * This method defines the section that will be associated with release-related commits. The specified section will be
137
     * used when generating release commit messages or determining the scope of a release.
138
     *
139
     * @param string $section The key of the section to be used for releases (e.g., 'release').
140
     *
141
     * @return $this this Config instance for method chaining
142
     */
143 1
    public function setReleaseSection(string $section): self
144
    {
145 1
        $this->releaseSection = $section;
146
147 1
        return $this;
148
    }
149
150
    /**
151
     * Retrieves the key of the section configured for release commits.
152
     *
153
     * This method returns the key of the section that is associated with release-related commits. If the configured
154
     * release section does not exist in the sections list, the default section (`other`) is returned instead.
155
     *
156
     * @return string the key of the release section or the default section if the configured release section is invalid
157
     */
158 22
    public function getReleaseSection(): string
159
    {
160 22
        return $this->sections->exits($this->releaseSection) ? $this->releaseSection : self::DEFAULT_SECTION;
161
    }
162
163
    /**
164
     * Retrieves the name of the main branch in the repository.
165
     *
166
     * By default, it is set to "master".
167
     *
168
     * @return string The name of the main branch (e.g., "main" or "master").
169
     */
170 33
    public function getMasterBranch(): string
171
    {
172 33
        return $this->masterBranch;
173
    }
174
175
    /**
176
     * Sets the name of the main branch in the repository.
177
     *
178
     * This method allows you to configure the name of the main branch (e.g., "main" or "master") used by the tool.
179
     *
180
     * @param string $masterBranch the name of the main branch
181
     *
182
     * @return $this this Config instance for method chaining
183
     */
184 4
    public function setMasterBranch(string $masterBranch): self
185
    {
186 4
        $this->masterBranch = $masterBranch;
187
188 4
        return $this;
189
    }
190
191
    /**
192
     * Sets the types of changes that trigger a minor version increment.
193
     *
194
     * This method configures the list of commit types that, when present, will cause the minor version to be
195
     * incremented during version updates.
196
     *
197
     * @param array $minorTypes An array of commit type codes (e.g., ['feat', 'fix']).
198
     *
199
     * @return $this this Config instance for method chaining
200
     */
201 1
    public function setMinorTypes(array $minorTypes): self
202
    {
203 1
        $this->minorTypes = $minorTypes;
204
205 1
        return $this;
206
    }
207
208
    /**
209
     * Sets the types of changes that trigger a major version increment.
210
     *
211
     * This method configures the list of commit types that, when present, will cause the major version to be
212
     * incremented during version updates.
213
     *
214
     * @param array $majorTypes An array of commit type codes (e.g., ['breaking']).
215
     *
216
     * @return $this this Config instance for method chaining
217
     */
218 2
    public function setMajorTypes(array $majorTypes): self
219
    {
220 2
        $this->majorTypes = $majorTypes;
221
222 2
        return $this;
223
    }
224
225
    /**
226
     * Sets the scope to be used for release commit messages.
227
     *
228
     * This method defines the scope that will be included in the description of release-related commits.
229
     * If an empty string is provided, no scope will be added to the release commit message.
230
     *
231
     * @param string $releaseScope The scope to be used for release commits (e.g., 'rel').
232
     *                             Use an empty string to omit the scope from the commit message.
233
     *
234
     * @return $this this Config instance for method chaining
235
     */
236 3
    public function setReleaseScope(string $releaseScope): self
237
    {
238 3
        $this->releaseScope = $releaseScope;
239
240 3
        return $this;
241
    }
242
243
    /**
244
     * Retrieves the scope configured for release commit messages.
245
     *
246
     * This method returns the scope that will be included in the description of release-related commits.
247
     * If no scope is configured, an empty string is returned, indicating that no scope will be added to the commit message.
248
     *
249
     * @return string the scope for release commit messages, or an empty string if no scope is configured
250
     */
251 21
    public function getReleaseScope(): string
252
    {
253 21
        return $this->releaseScope;
254
    }
255
256
    /**
257
     * Enables or disables ignoring untracked files in the repository.
258
     *
259
     * This method configures whether untracked files should be ignored when running the version increment tool.
260
     * By default, untracked files are not ignored, and their presence may cause the tool to fail.
261
     *
262
     * @param bool $ignoreUntrackedFiles Whether to ignore untracked files:
263
     *                                   - `true`: Ignore untracked files.
264
     *                                   - `false`: Do not ignore untracked files (default behavior).
265
     *
266
     * @return $this this Config instance for method chaining
267
     */
268 1
    public function setIgnoreUntrackedFiles(bool $ignoreUntrackedFiles): self
269
    {
270 1
        $this->ignoreUntrackedFiles = $ignoreUntrackedFiles;
271
272 1
        return $this;
273
    }
274
275
    /**
276
     * Checks whether untracked files are ignored in the repository.
277
     *
278
     * This method retrieves the current configuration for ignoring untracked files. If enabled, the tool will not
279
     * consider untracked files when performing operations.
280
     *
281
     * @return bool returns `true` if untracked files are ignored, `false` otherwise
282
     */
283 32
    public function mastIgnoreUntrackedFiles(): bool
284
    {
285 32
        return $this->ignoreUntrackedFiles;
286
    }
287
288
    /**
289
     * Adds a rule for determining whether a commit belongs to a specific section.
290
     *
291
     * This method associates a rule with a specific section. The rule is used to evaluate whether a commit should be
292
     * included in the specified section.
293
     *
294
     * @param string               $key  the key of the section
295
     * @param SectionRuleInterface $rule the rule to be added
296
     *
297
     * @return $this this Config instance for method chaining
298
     */
299 3
    public function addSectionRule(string $key, SectionRuleInterface $rule): self
300
    {
301 3
        $this->sectionRules[$key][] = $rule;
302
303 3
        return $this;
304
    }
305
306
    /**
307
     * Retrieves the rules associated with a specific section.
308
     *
309
     * This method returns an array of rules for the specified section. If no custom rules are defined, a default rule
310
     * is automatically added and returned.
311
     *
312
     * @param string $key the key of the section
313
     *
314
     * @return SectionRuleInterface[] an array of rules for the specified section
315
     */
316 27
    public function getSectionRules(string $key): array
317
    {
318 27
        $this->sectionRules[$key]['default'] = new DefaultRule($key);
319
320 27
        return $this->sectionRules[$key];
321
    }
322
323
    /**
324
     * Sets the section to be used for identifying squashed (aggregate) commits.
325
     *
326
     * This method configures the section that will be treated as a marker for squashed commits. When a commit is
327
     * associated with this section, it will be processed as a squashed commit. Squashed commits typically contain
328
     * a summary of multiple commits and are parsed accordingly to extract individual changes.
329
     *
330
     * @param string $aggregateSection The key of the section to be used for identifying squashed commits
331
     *                                 (e.g., 'aggregate').
332
     *
333
     * @return $this this Config instance for method chaining
334
     */
335 1
    public function setAggregateSection(string $aggregateSection): self
336
    {
337 1
        $this->aggregateSection = $aggregateSection;
338
339 1
        return $this;
340
    }
341
342
    /**
343
     * Retrieves the section configured for identifying squashed (aggregate) commits.
344
     *
345
     * This method returns the key of the section that is used to identify squashed commits. If no section has been
346
     * explicitly configured, an empty string is returned, indicating that no specific section is assigned for
347
     * identifying squashed commits.
348
     *
349
     * @return string the key of the section used for identifying squashed commits, or an empty string if no section
350
     *                is configured
351
     */
352 27
    public function getAggregateSection(): string
353
    {
354 27
        return $this->aggregateSection;
355
    }
356
357
    /**
358
     * Sets the commit message template for squashed commits.
359
     *
360
     * This method allows you to customize the message used to identify squashed commits in the repository.
361
     *
362
     * @param string $squashedCommitMessage the custom message template for squashed commits
363
     *
364
     * @return $this this Config instance for method chaining
365
     */
366 1
    public function setSquashedCommitMessage(string $squashedCommitMessage): self
367
    {
368 1
        $this->squashedCommitMessage = $squashedCommitMessage;
369
370 1
        return $this;
371
    }
372
373
    /**
374
     * Retrieves the commit message template for squashed commits.
375
     *
376
     * @return string the message template for squashed commits
377
     */
378 27
    public function getSquashedCommitMessage(): string
379
    {
380 27
        return $this->squashedCommitMessage;
381
    }
382
383
    /**
384
     * Enables or disables processing of default squashed commits.
385
     *
386
     * This method configures whether the tool should process default squashed commits (those matching the default
387
     * message template).
388
     *
389
     * @param bool $processDefaultSquashedCommit whether to enable processing of default squashed commits
390
     *
391
     * @return $this this Config instance for method chaining
392
     */
393 2
    public function setProcessDefaultSquashedCommit(bool $processDefaultSquashedCommit): self
394
    {
395 2
        $this->processDefaultSquashedCommit = $processDefaultSquashedCommit;
396
397 2
        return $this;
398
    }
399
400
    /**
401
     * Checks whether processing of default squashed commits is enabled.
402
     *
403
     * @return bool returns `true` if processing of default squashed commits is enabled, `false` otherwise
404
     */
405 27
    public function shouldProcessDefaultSquashedCommit(): bool
406
    {
407 27
        return $this->processDefaultSquashedCommit;
408
    }
409
410
    /**
411
     * Retrieves the changelog formatter instance.
412
     *
413
     * If no custom changelog formatter is set, a default instance of `DefaultFormatter` is created and configured.
414
     * The formatter's configuration is automatically updated to use the current `Config` instance.
415
     *
416
     * @return ChangelogFormatterInterface the changelog formatter instance
417
     */
418 27
    public function getChangelogFormatter(): ChangelogFormatterInterface
419
    {
420 27
        if (null === $this->changelogFormatter) {
421 25
            $this->changelogFormatter = new Changelog\DefaultFormatter();
422 25
            $this->changelogFormatter->setConfig($this);
423
        }
424
425 27
        return $this->changelogFormatter;
426
    }
427
428
    /**
429
     * Sets a custom changelog formatter for the configuration.
430
     *
431
     * The provided formatter will be used for all changelog-related operations. The formatter's configuration
432
     * is automatically updated to use the current `Config` instance.
433
     *
434
     * @param ChangelogFormatterInterface $changelogFormatter the custom changelog formatter to set
435
     *
436
     * @return $this this Config instance for method chaining
437
     */
438 2
    public function setChangelogFormatter(ChangelogFormatterInterface $changelogFormatter): self
439
    {
440 2
        $this->changelogFormatter = $changelogFormatter;
441 2
        $this->changelogFormatter->setConfig($this);
442
443 2
        return $this;
444
    }
445
446
    /**
447
     * Retrieves the VCS executor instance.
448
     *
449
     * If no custom VCS executor is set, a default instance of `GitExecutor` is created and used.
450
     *
451
     * @return VcsExecutorInterface the VCS executor instance
452
     */
453 34
    public function getVcsExecutor(): VcsExecutorInterface
454
    {
455 34
        return $this->vcsExecutor ??= new GitExecutor();
456
    }
457
458
    /**
459
     * Sets a custom VCS executor for the configuration.
460
     *
461
     * The provided executor will be used for all version control system operations.
462
     *
463
     * @param VcsExecutorInterface $vcsExecutor the custom VCS executor to set
464
     *
465
     * @return $this this Config instance for method chaining
466
     */
467 35
    public function setVcsExecutor(VcsExecutorInterface $vcsExecutor): self
468
    {
469 35
        $this->vcsExecutor = $vcsExecutor;
470
471 35
        return $this;
472
    }
473
474
    /**
475
     * Retrieves the commit parser instance.
476
     *
477
     * If no custom commit parser is set, a default instance of `ShortParser` is created and configured.
478
     * The parser's configuration is automatically updated to use the current `Config` instance.
479
     *
480
     * @return CommitParserInterface the commit parser instance
481
     */
482 30
    public function getCommitParser(): CommitParserInterface
483
    {
484 30
        if (null === $this->commitParser) {
485 29
            $this->commitParser = new Commits\ShortParser();
486 29
            $this->commitParser->setConfig($this);
487
        }
488
489 30
        return $this->commitParser;
490
    }
491
492
    /**
493
     * Sets a custom commit parser for the configuration.
494
     *
495
     * The provided parser will be used for all commit parsing operations. The parser's configuration is automatically
496
     * updated to use the current `Config` instance.
497
     *
498
     * @return $this this Config instance for method chaining
499
     */
500 1
    public function setCommitParser(CommitParserInterface $changelogFormatter): self
501
    {
502 1
        $this->commitParser = $changelogFormatter;
503 1
        $this->commitParser->setConfig($this);
504
505 1
        return $this;
506
    }
507
508
    /**
509
     * Retrieves the tag formatter instance.
510
     *
511
     * If no custom tag formatter is set, a default instance of `DefaultFormatter` is created and configured.
512
     *
513
     * @return TagFormatterInterface the tag formatter instance
514
     */
515 6
    public function getTagFormatter(): TagFormatterInterface
516
    {
517 6
        if (null === $this->tagFormatter) {
518 5
            $this->tagFormatter = new Tag\DefaultFormatter();
519 5
            $this->tagFormatter->setConfig($this);
520
        }
521
522 6
        return $this->tagFormatter;
523
    }
524
525
    /**
526
     * Sets a custom tag formatter for the configuration.
527
     *
528
     * The provided formatter will be used for all tag-related operations. The formatter's configuration
529
     * is automatically updated to use the current `Config` instance.
530
     *
531
     * @param TagFormatterInterface $tagFormatter the custom tag formatter to set
532
     *
533
     * @return $this this Config instance for method chaining
534
     */
535 1
    public function setTagFormatter(TagFormatterInterface $tagFormatter): self
536
    {
537 1
        $this->tagFormatter = $tagFormatter;
538 1
        $this->tagFormatter->setConfig($this);
539
540 1
        return $this;
541
    }
542
543
    /**
544
     * Enables or disables version management in the `composer.json` file.
545
     *
546
     * When disabled, version management will rely solely on Git tags instead of updating `composer.json`.
547
     *
548
     * @param bool $enabledComposerVersioning Whether to enable version management in `composer.json`.
549
     *                                        - `true`: Enable version management in `composer.json`.
550
     *                                        - `false`: Disable version management in `composer.json`.
551
     *
552
     * @return $this this Config instance for method chaining
553
     */
554 9
    public function setEnabledComposerVersioning(bool $enabledComposerVersioning): self
555
    {
556 9
        $this->enabledComposerVersioning = $enabledComposerVersioning;
557
558 9
        return $this;
559
    }
560
561
    /**
562
     * Checks whether version management in the `composer.json` file is enabled.
563
     *
564
     * @return bool Returns `true` if version management in `composer.json` is enabled, `false` otherwise.
565
     */
566 32
    public function isEnabledComposerVersioning(): bool
567
    {
568 32
        return $this->enabledComposerVersioning;
569
    }
570
571
    /**
572
     * Sets a custom property in the configuration.
573
     *
574
     * This method allows you to store custom key-value pairs in the configuration. These properties can be used to pass
575
     * additional parameters required by custom implementations (e.g., formatters, VCS executors, parsers, etc.).
576
     *
577
     * @param string $key   The name of the property to set. This should be a unique identifier for the property.
578
     * @param mixed  $value The value to associate with the property. This can be any type of data required by the custom
579
     *                      implementation.
580
     *
581
     * @return $this this Config instance for method chaining
582
     *
583
     * @example
584
     * ```php
585
     * return (new \Vasoft\VersionIncrement\Config())
586
     *     ->set('customParam', 'customValue');
587
     * ```
588
     */
589 5
    public function set(string $key, mixed $value): self
590
    {
591 5
        $this->props[$key] = $value;
592
593 5
        return $this;
594
    }
595
596
    /**
597
     * Retrieves the value of a custom property from the configuration.
598
     *
599
     * This method retrieves the value associated with the specified property key. If the property does not exist,
600
     * an exception is thrown to indicate that the property is unknown.
601
     *
602
     * @param string $key The name of the property to retrieve. This should match the key used when setting the property.
603
     *
604
     * @return mixed the value associated with the property
605
     *
606
     * @throws UnknownPropertyException if the specified property does not exist in the configuration
607
     */
608 6
    public function get(string $key): mixed
609
    {
610 6
        if (!isset($this->props[$key])) {
611 1
            throw new UnknownPropertyException($key);
612
        }
613
614 5
        return $this->props[$key];
615
    }
616
617
    /**
618
     * Enables or disables hiding of duplicate entries within the same section in the CHANGELOG.
619
     *
620
     * This method configures whether duplicate entries (lines with identical content) should be hidden in the generated
621
     * CHANGELOG. When enabled, only the first occurrence of a duplicate entry will be displayed within each section.
622
     *
623
     * @param bool $hideDoubles Whether to hide duplicate entries:
624
     *                          - `true`: Hide duplicate entries within the same section.
625
     *                          - `false`: Display all entries, including duplicates (default behavior).
626
     *
627
     * @return $this this Config instance for method chaining
628
     */
629 1
    public function setHideDoubles(bool $hideDoubles): self
630
    {
631 1
        $this->hideDoubles = $hideDoubles;
632
633 1
        return $this;
634
    }
635
636
    /**
637
     * Checks whether hiding of duplicate entries within the same section is enabled.
638
     *
639
     * This method retrieves the current configuration for hiding duplicate entries in the CHANGELOG. If enabled, duplicate
640
     * entries within the same section will be hidden during the generation of the CHANGELOG.
641
     *
642
     * @return bool returns `true` if hiding of duplicate entries is enabled, `false` otherwise
643
     */
644 27
    public function isHideDoubles(): bool
645
    {
646 27
        return $this->hideDoubles;
647
    }
648
649
    /**
650
     * Adds a human-readable title for a specific scope.
651
     *
652
     * This method associates a scope key with a human-readable title. The title will be used in the CHANGELOG
653
     * instead of the raw scope name when generating commit messages. If the scope already exists, its title
654
     * will be updated.
655
     *
656
     * @param string $key   The scope key (e.g., 'dev', 'deprecated').
657
     * @param string $title The human-readable title for the scope (e.g., 'Development', 'Deprecated Features').
658
     */
659 2
    public function addScope(string $key, string $title): self
660
    {
661 2
        $this->scopes[$key] = $title;
662
663 2
        return $this;
664
    }
665
666
    /**
667
     * Retrieves all configured scopes and their human-readable titles.
668
     *
669
     * This method returns an associative array where keys are scope codes and values are their corresponding
670
     * human-readable titles. These titles are used in the CHANGELOG to replace raw scope names for better readability.
671
     *
672
     * @return array an associative array of scopes, where keys are scope codes and values are their titles
673
     */
674 6
    public function getScopes(): array
675
    {
676 6
        return $this->scopes;
677
    }
678
679
    /**
680
     * Retrieves the event bus instance.
681
     *
682
     * This method provides access to the `EventBus` instance, which is responsible for managing and dispatching events
683
     * within the application. If the event bus has not been initialized yet, a new instance of `EventBus` will be created
684
     * and stored for future use.
685
     *
686
     * The event bus is used to facilitate communication between different parts of the application by allowing components
687
     * to subscribe to and handle specific events.
688
     *
689
     * @return EventBus the event bus instance used for dispatching and handling events
690
     */
691 23
    public function getEventBus(): EventBus
692
    {
693 23
        if (null === $this->eventBus) {
694 23
            $this->eventBus = new EventBus();
695
        }
696
697 23
        return $this->eventBus;
698
    }
699
}
700