Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
33 / 33 |
|
100.00% |
19 / 19 |
CRAP | |
100.00% |
1 / 1 |
BuildTaskService | |
100.00% |
33 / 33 |
|
100.00% |
19 / 19 |
26 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
setOutput | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRegisteredTasks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
runPreBuildTasks | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
runPostBuildTasks | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
registerTask | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
registerTaskInService | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
registerIf | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
registerTasks | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
findTasksInConfig | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
findTasksInAppDirectory | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
pathToClassName | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
makeTaskIdentifier | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
registerFrameworkTasks | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
canCleanSiteDirectory | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
canGenerateManifest | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
canGenerateSitemap | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
canGenerateFeed | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
canGenerateSearch | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Hyde\Framework\Services; |
6 | |
7 | use Hyde\Facades\Config; |
8 | use Hyde\Facades\Features; |
9 | use Hyde\Facades\Filesystem; |
10 | use Hyde\Framework\Features\BuildTasks\BuildTask; |
11 | use Hyde\Framework\Features\BuildTasks\PreBuildTask; |
12 | use Hyde\Framework\Features\BuildTasks\PostBuildTask; |
13 | use Hyde\Framework\Actions\PreBuildTasks\CleanSiteDirectory; |
14 | use Hyde\Framework\Actions\PostBuildTasks\GenerateSearch; |
15 | use Hyde\Framework\Actions\PostBuildTasks\GenerateRssFeed; |
16 | use Hyde\Framework\Actions\PostBuildTasks\GenerateSitemap; |
17 | use Hyde\Framework\Actions\PostBuildTasks\GenerateBuildManifest; |
18 | use Illuminate\Console\OutputStyle; |
19 | use Illuminate\Support\Str; |
20 | |
21 | use function array_map; |
22 | use function array_values; |
23 | use function class_basename; |
24 | use function is_string; |
25 | use function str_replace; |
26 | |
27 | /** |
28 | * This service manages the build tasks that are called before and after the site is compiled using the build command. |
29 | * |
30 | * The class is registered as a singleton in the Laravel service container and is run by the build command. |
31 | * Build Tasks can be registered programmatically, through the config, and through autodiscovery. |
32 | * The service determines when to run a task depending on which class it extends. |
33 | */ |
34 | class BuildTaskService |
35 | { |
36 | /** @var array<string, \Hyde\Framework\Features\BuildTasks\BuildTask> */ |
37 | protected array $buildTasks = []; |
38 | |
39 | protected ?OutputStyle $output = null; |
40 | |
41 | public function __construct() |
42 | { |
43 | $this->registerFrameworkTasks(); |
44 | |
45 | $this->registerTasks($this->findTasksInConfig()); |
46 | |
47 | $this->registerTasks($this->findTasksInAppDirectory()); |
48 | } |
49 | |
50 | public function setOutput(?OutputStyle $output): void |
51 | { |
52 | $this->output = $output; |
53 | } |
54 | |
55 | /** @return array<class-string<\Hyde\Framework\Features\BuildTasks\PreBuildTask>|class-string<\Hyde\Framework\Features\BuildTasks\PostBuildTask>> */ |
56 | public function getRegisteredTasks(): array |
57 | { |
58 | return array_map(fn (BuildTask $task): string => $task::class, array_values($this->buildTasks)); |
59 | } |
60 | |
61 | public function runPreBuildTasks(): void |
62 | { |
63 | foreach ($this->buildTasks as $task) { |
64 | if ($task instanceof PreBuildTask) { |
65 | $task->run($this->output); |
66 | } |
67 | } |
68 | } |
69 | |
70 | public function runPostBuildTasks(): void |
71 | { |
72 | foreach ($this->buildTasks as $task) { |
73 | if ($task instanceof PostBuildTask) { |
74 | $task->run($this->output); |
75 | } |
76 | } |
77 | } |
78 | |
79 | /** @param \Hyde\Framework\Features\BuildTasks\PreBuildTask|\Hyde\Framework\Features\BuildTasks\PostBuildTask|class-string<\Hyde\Framework\Features\BuildTasks\PreBuildTask|\Hyde\Framework\Features\BuildTasks\PostBuildTask> $task */ |
80 | public function registerTask(PreBuildTask|PostBuildTask|string $task): void |
81 | { |
82 | $this->registerTaskInService(is_string($task) ? new $task() : $task); |
83 | } |
84 | |
85 | protected function registerTaskInService(PreBuildTask|PostBuildTask $task): void |
86 | { |
87 | $this->buildTasks[$this->makeTaskIdentifier($task)] = $task; |
88 | } |
89 | |
90 | /** @param class-string<\Hyde\Framework\Features\BuildTasks\PreBuildTask|\Hyde\Framework\Features\BuildTasks\PostBuildTask> $task */ |
91 | protected function registerIf(string $task, bool $condition): void |
92 | { |
93 | if ($condition) { |
94 | $this->registerTask($task); |
95 | } |
96 | } |
97 | |
98 | /** @param array<\Hyde\Framework\Features\BuildTasks\PreBuildTask|\Hyde\Framework\Features\BuildTasks\PostBuildTask|class-string<\Hyde\Framework\Features\BuildTasks\PreBuildTask|\Hyde\Framework\Features\BuildTasks\PostBuildTask>> $tasks */ |
99 | protected function registerTasks(array $tasks): void |
100 | { |
101 | foreach ($tasks as $task) { |
102 | $this->registerTask($task); |
103 | } |
104 | } |
105 | |
106 | /** @return array<class-string<\Hyde\Framework\Features\BuildTasks\PreBuildTask>|class-string<\Hyde\Framework\Features\BuildTasks\PostBuildTask>> */ |
107 | protected function findTasksInConfig(): array |
108 | { |
109 | return Config::getArray('hyde.build_tasks', []); |
110 | } |
111 | |
112 | /** @return array<class-string<\Hyde\Framework\Features\BuildTasks\PreBuildTask>|class-string<\Hyde\Framework\Features\BuildTasks\PostBuildTask>> */ |
113 | protected function findTasksInAppDirectory(): array |
114 | { |
115 | return Filesystem::smartGlob('app/Actions/*BuildTask.php')->map(function (string $file): string { |
116 | return static::pathToClassName($file); |
117 | })->toArray(); |
118 | } |
119 | |
120 | protected static function pathToClassName(string $file): string |
121 | { |
122 | return str_replace(['app', '.php', '/'], ['App', '', '\\'], $file); |
123 | } |
124 | |
125 | protected function makeTaskIdentifier(BuildTask $class): string |
126 | { |
127 | // If a user-land task is registered with the same class name (excluding namespaces) as a framework task, |
128 | // this will allow the user-land task to override the framework task, making them easy to swap out. |
129 | |
130 | return Str::kebab(class_basename($class)); |
131 | } |
132 | |
133 | private function registerFrameworkTasks(): void |
134 | { |
135 | $this->registerIf(CleanSiteDirectory::class, $this->canCleanSiteDirectory()); |
136 | $this->registerIf(GenerateBuildManifest::class, $this->canGenerateManifest()); |
137 | $this->registerIf(GenerateSitemap::class, $this->canGenerateSitemap()); |
138 | $this->registerIf(GenerateRssFeed::class, $this->canGenerateFeed()); |
139 | $this->registerIf(GenerateSearch::class, $this->canGenerateSearch()); |
140 | } |
141 | |
142 | private function canCleanSiteDirectory(): bool |
143 | { |
144 | return Config::getBool('hyde.empty_output_directory', true); |
145 | } |
146 | |
147 | private function canGenerateManifest(): bool |
148 | { |
149 | return Config::getBool('hyde.generate_build_manifest', true); |
150 | } |
151 | |
152 | private function canGenerateSitemap(): bool |
153 | { |
154 | return Features::sitemap(); |
155 | } |
156 | |
157 | private function canGenerateFeed(): bool |
158 | { |
159 | return Features::rss(); |
160 | } |
161 | |
162 | private function canGenerateSearch(): bool |
163 | { |
164 | return Features::hasDocumentationSearch(); |
165 | } |
166 | } |