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

tempestphp / tempest-framework / 11904119374

18 Nov 2024 12:08PM UTC coverage: 81.946% (-0.1%) from 82.07%
11904119374

push

github

web-flow
chore(core): fixes to path helper (#744)

1 of 1 new or added line in 1 file covered. (100.0%)

27 existing lines in 3 files now uncovered.

7848 of 9577 relevant lines covered (81.95%)

52.03 hits per line

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

72.0
/src/Tempest/Generation/src/StubFileGenerator.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Tempest\Generation;
6

7
use Closure;
8
use Tempest\Generation\DataObjects\StubFile;
9
use Tempest\Generation\Enums\StubFileType;
10
use Tempest\Generation\Exceptions\FileGenerationAbortedException;
11
use Tempest\Generation\Exceptions\FileGenerationFailedException;
12
use function Tempest\path;
13
use Tempest\Support\NamespaceHelper;
14
use function Tempest\Support\str;
15
use Tempest\Support\StringHelper;
16
use Throwable;
17

18
/**
19
 * This class can generate a file from a stub file with additional useful methods.
20
 * It only works with PHP class files.
21
 */
22
final class StubFileGenerator
23
{
24
    /**
25
     * @param StubFile $stubFile The stub file to use for the generation. It must be of type CLASS_FILE.
26
     * @param string $targetPath The path where the generated file will be saved including the filename and extension.
27
     * @param bool $shouldOverride Whether the generator should override the file if it already exists.
28
     * @param array<string, string> $replacements An array of key-value pairs to replace in the stub file.
29
     *     The keys are the placeholders in the stub file (e.g. 'DummyNamespace')
30
     *     The values are the replacements for the placeholders (e.g. 'App\Models')
31
     *
32
     * @param array<Closure(ClassManipulator): ClassManipulator> $manipulations An array of manipulations to apply to the generated class.
33
     *
34
     * @throws FileGenerationFailedException
35
     */
36
    public function generateClassFile(
11✔
37
        StubFile $stubFile,
38
        string $targetPath,
39
        bool $shouldOverride = false,
40
        array $replacements = [],
41
        array $manipulations = [],
42
    ): void {
43
        try {
44
            if ($stubFile->type !== StubFileType::CLASS_FILE) {
11✔
UNCOV
45
                throw new FileGenerationFailedException(sprintf('The stub file must be of type CLASS_FILE, "%s" given.', $stubFile->type->name));
×
46
            }
47

48
            if (file_exists($targetPath) && ! $shouldOverride) {
11✔
UNCOV
49
                throw new FileGenerationAbortedException(sprintf('The file "%s" already exists and the operation has been aborted.', $targetPath));
×
50
            }
51

52
            $this->prepareFilesystem($targetPath);
11✔
53

54
            // Transform stub to class
55
            $namespace = NamespaceHelper::toMainNamespace($targetPath);
11✔
56
            $classname = NamespaceHelper::toClassName($targetPath);
11✔
57
            $classManipulator = (new ClassManipulator($stubFile->filePath))
11✔
58
                ->setNamespace($namespace)
11✔
59
                ->setClassName($classname);
11✔
60

61
            foreach ($replacements as $placeholder => $replacement) {
11✔
62
                if (! is_string($replacement)) {
3✔
63
                    continue;
3✔
64
                }
65

UNCOV
66
                $classManipulator->manipulate(fn (StringHelper $code) => $code->replace($placeholder, $replacement));
×
67
            }
68

69
            // Run all manipulations
70
            $classManipulator = array_reduce(
11✔
71
                array: $manipulations,
11✔
72
                callback: fn (ClassManipulator $manipulator, Closure $manipulation) => $manipulation($manipulator),
11✔
73
                initial: $classManipulator
11✔
74
            );
11✔
75

76
            if (file_exists($targetPath) && $shouldOverride) {
11✔
UNCOV
77
                @unlink($targetPath);
×
78
            }
79

80
            $classManipulator->save($targetPath);
11✔
81
        } catch (Throwable $throwable) {
×
UNCOV
82
            throw new FileGenerationFailedException(sprintf('The file could not be written. %s', $throwable->getMessage()));
×
83
        }
84
    }
85

86
    /**
87
     * @param StubFile $stubFile The stub file to use for the generation. It must be of type RAW_FILE.
88
     * @param string $targetPath The path where the generated file will be saved including the filename and extension.
89
     * @param bool $shouldOverride Whether the generator should override the file if it already exists.
90
     * @param array<string, string> $replacements An array of key-value pairs to replace in the stub file.
91
     *     The keys are the placeholders in the stub file (e.g. 'dummy-content')
92
     *     The values are the replacements for the placeholders (e.g. 'real content')
93
     *
94
     * @param array<Closure(StringHelper): StringHelper> $manipulations An array of manipulations to apply to the generated file raw content.
95
     *
96
     * @throws FileGenerationFailedException
97
     */
98
    public function generateRawFile(
2✔
99
        StubFile $stubFile,
100
        string $targetPath,
101
        bool $shouldOverride = false,
102
        array $replacements = [],
103
        array $manipulations = [],
104
    ): void {
105
        try {
106
            if ($stubFile->type !== StubFileType::RAW_FILE) {
2✔
UNCOV
107
                throw new FileGenerationFailedException(sprintf('The stub file must be of type RAW_FILE, "%s" given.', $stubFile->type->name));
×
108
            }
109

110
            if (file_exists($targetPath) && ! $shouldOverride) {
2✔
UNCOV
111
                throw new FileGenerationAbortedException(sprintf('The file "%s" already exists and the operation has been aborted.', $targetPath));
×
112
            }
113

114
            $this->prepareFilesystem($targetPath);
2✔
115
            $fileContent = file_get_contents($stubFile->filePath);
2✔
116

117
            foreach ($replacements as $placeholder => $replacement) {
2✔
118
                if (! is_string($replacement)) {
×
UNCOV
119
                    continue;
×
120
                }
121

UNCOV
122
                $fileContent = str($fileContent)->replace($placeholder, $replacement);
×
123
            }
124

125
            // Run all manipulations
126
            $fileContent = array_reduce(
2✔
127
                array: $manipulations,
2✔
128
                initial: $fileContent,
2✔
129
                callback: fn (StringHelper $content, Closure $manipulation) => $manipulation($content)
2✔
130
            );
2✔
131

132
            if (file_exists($targetPath) && $shouldOverride) {
2✔
UNCOV
133
                @unlink($targetPath);
×
134
            }
135

136
            file_put_contents($targetPath, $fileContent);
2✔
137
        } catch (Throwable $throwable) {
×
UNCOV
138
            throw new FileGenerationFailedException(sprintf('The file could not be written. %s', $throwable->getMessage()));
×
139
        }
140
    }
141

142
    /**
143
     * Prepare the directory structure for the new file.
144
     * It will delete the target file if it exists and we force the override.
145
     *
146
     * @param string $targetPath The path where the generated file will be saved including the filename and extension.
147
     */
148
    private function prepareFilesystem(string $targetPath): void
12✔
149
    {
150
        // Recursively create directories before writing the file
151
        $directory = dirname($targetPath);
12✔
152
        if (! is_dir($directory)) {
12✔
153
            mkdir($directory, recursive: true);
9✔
154
        }
155
    }
156
}
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