RegexpFileModifier   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 17
c 2
b 0
f 0
dl 0
loc 87
ccs 22
cts 22
cp 1
rs 10
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A replace() 0 15 3
A handle() 0 5 2
A checkFile() 0 7 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Vasoft\VersionIncrement\Extension;
6
7
use Vasoft\VersionIncrement\Contract\EventListenerInterface;
8
use Vasoft\VersionIncrement\Events\Event;
9
use Vasoft\VersionIncrement\Extension\Exception\FileNotFoundException;
10
use Vasoft\VersionIncrement\Extension\Exception\FileNotWritableException;
11
use Vasoft\VersionIncrement\Extension\Exception\PatternNotFoundException;
12
13
/**
14
 * Class RegexpFileModifier.
15
 *
16
 * This class is an extension for the `voral/version-increment` package, designed to update version strings in arbitrary files
17
 * using regular expressions. It listens to the `BEFORE_VERSION_SET` event and performs version replacements in the specified file
18
 * based on the provided regular expression.
19
 */
20
class RegexpFileModifier implements EventListenerInterface
21
{
22
    /**
23
     * Constructor for the RegexpFileModifier class.
24
     *
25
     * Initializes the file path, regular expression, and optional error code delta.
26
     *
27
     * @param string $filePath       the path to the file where the version will be updated
28
     * @param string $regexp         The regular expression used to locate the version string in the file.
29
     *                               It must contain capturing groups:
30
     *                               - Group 1: The part of the string before the version.
31
     *                               - Group 2: The part of the string after the version.
32
     * @param int    $errorCodeDelta Optional delta value to ensure unique error codes across multiple modules.
33
     *                               Defaults to `0`.
34
     */
35 7
    public function __construct(
36
        private readonly string $filePath,
37
        private readonly string $regexp,
38
        private readonly int $errorCodeDelta = 0,
39 7
    ) {}
40
41
    /**
42
     * Handles the event and updates the version in the specified file.
43
     *
44
     * This method is called when an event is dispatched. If the event contains a new version,
45
     * it checks the file's existence and writability, then replaces the version in the file
46
     * using the provided regular expression.
47
     *
48
     * @param Event $event the event object containing the new version in the `version` property
49
     *
50
     * @throws FileNotFoundException    if the specified file does not exist
51
     * @throws FileNotWritableException if the specified file is not writable
52
     * @throws PatternNotFoundException if the regular expression does not match any part of the file content
53
     */
54 7
    public function handle(Event $event): void
55
    {
56 7
        if (!empty($event->version)) {
57 7
            $this->checkFile();
58 3
            $this->replace($event);
59
        }
60
    }
61
62
    /**
63
     * Checks if the file exists and is writable.
64
     *
65
     * This method ensures that the file specified in the constructor exists and can be modified.
66
     * If the file does not exist or is not writable, an exception is thrown.
67
     *
68
     * @throws FileNotFoundException    if the file does not exist
69
     * @throws FileNotWritableException if the file is not writable
70
     */
71 7
    private function checkFile(): void
72
    {
73 7
        if (!file_exists($this->filePath)) {
74 2
            throw new FileNotFoundException($this->filePath, $this->errorCodeDelta);
75
        }
76 5
        if (!is_writable($this->filePath)) {
77 2
            throw new FileNotWritableException($this->filePath, $this->errorCodeDelta);
78
        }
79
    }
80
81
    /**
82
     * Replaces the version in the file using the provided regular expression.
83
     *
84
     * This method reads the file content, applies the regular expression to locate the version,
85
     * and replaces it with the new version from the event. If the regular expression does not
86
     * find a match, an exception is thrown.
87
     *
88
     * @param Event $event the event object containing the new version in the `version` property
89
     *
90
     * @throws PatternNotFoundException if the regular expression does not match any part of the file content
91
     */
92 3
    private function replace(Event $event): void
93
    {
94 3
        $newVersion = $event->version;
95 3
        $content = file_get_contents($this->filePath);
96
97 3
        $updatedContent = preg_replace_callback(
98 3
            $this->regexp,
99 3
            static fn($matches) => $matches[1] . $newVersion . $matches[2],
100 3
            $content,
101 3
        );
102 3
        if (null === $updatedContent || $content === $updatedContent) {
103 2
            throw new PatternNotFoundException($this->filePath, $this->errorCodeDelta);
104
        }
105
106 1
        file_put_contents($this->filePath, $updatedContent);
107
    }
108
}
109