Passed
Push — master ( 561a55...a121e9 )
by Caen
03:36 queued 14s
created

BuildSiteCommand::configureBuildTaskService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Console\Commands;
6
7
use Hyde\Hyde;
8
use Hyde\Facades\Config;
9
use Hyde\Support\BuildWarnings;
10
use Hyde\Console\Concerns\Command;
11
use Hyde\Framework\Services\BuildService;
12
use Hyde\Framework\Services\BuildTaskService;
13
14
use function memory_get_peak_usage;
15
use function number_format;
16
use function array_search;
17
use function shell_exec;
18
use function microtime;
19
use function sprintf;
20
use function app;
21
22
/**
23
 * Hyde Command to run the Build Process.
24
 */
25
class BuildSiteCommand extends Command
26
{
27
    /** @var string */
28
    protected $signature = 'build
29
        {--run-dev : Run the NPM dev script after build}
30
        {--run-prod : Run the NPM prod script after build}
31
        {--run-prettier : Format the output using NPM Prettier}
32
        {--pretty-urls : Should links in output use pretty URLs?}
33
        {--no-api : Disable API calls, for example, Torchlight}';
34
35
    /** @var string */
36
    protected $description = 'Build the static site';
37
38
    protected BuildService $service;
39
    protected BuildTaskService $taskService;
40
41
    public function handle(): int
42
    {
43
        $timeStart = microtime(true);
44
45
        $this->title('Building your static site!');
46
47
        $this->service = new BuildService($this->output);
48
49
        $this->configureBuildTaskService();
50
51
        $this->runPreBuildActions();
52
53
        $this->service->transferMediaAssets();
54
55
        $this->service->compileStaticPages();
56
57
        $this->runPostBuildActions();
58
59
        $this->printFinishMessage($timeStart);
0 ignored issues
show
Bug introduced by
It seems like $timeStart can also be of type string; however, parameter $timeStart of Hyde\Console\Commands\Bu...d::printFinishMessage() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
        $this->printFinishMessage(/** @scrutinizer ignore-type */ $timeStart);
Loading history...
60
61
        return $this->getExitCode();
62
    }
63
64
    protected function configureBuildTaskService(): void
65
    {
66
        /** @var BuildTaskService $taskService */
67
        $taskService = app(BuildTaskService::class);
68
69
        $this->taskService = $taskService;
70
        $this->taskService->setOutput($this->output);
71
    }
72
73
    protected function runPreBuildActions(): void
74
    {
75
        if ($this->option('no-api')) {
76
            $this->info('Disabling external API calls');
77
            $this->newLine();
78
            /** @var array<string, string> $config */
79
            $config = Config::getArray('hyde.features', []);
80
            unset($config[array_search('torchlight', $config)]);
81
            Config::set(['hyde.features' => $config]);
82
        }
83
84
        if ($this->option('pretty-urls')) {
85
            $this->info('Generating site with pretty URLs');
86
            $this->newLine();
87
            Config::set(['hyde.pretty_urls' => true]);
88
        }
89
90
        $this->taskService->runPreBuildTasks();
91
    }
92
93
    public function runPostBuildActions(): void
94
    {
95
        $this->taskService->runPostBuildTasks();
96
97
        if ($this->option('run-prettier')) {
98
            $this->runNodeCommand(
99
                'npx prettier '.Hyde::pathToRelative(Hyde::sitePath()).'/**/*.html --write --bracket-same-line',
100
                'Prettifying code!',
101
                'prettify code'
102
            );
103
        }
104
105
        if ($this->option('run-dev')) {
106
            $this->runNodeCommand('npm run dev', 'Building frontend assets for development!');
107
        }
108
109
        if ($this->option('run-prod')) {
110
            $this->runNodeCommand('npm run prod', 'Building frontend assets for production!');
111
        }
112
    }
113
114
    protected function printFinishMessage(float $timeStart): void
115
    {
116
        if ($this->hasWarnings()) {
117
            $this->newLine();
118
            $this->error('There were some warnings during the build process:');
119
            $this->newLine();
120
            BuildWarnings::writeWarningsToOutput($this->output, $this->output->isVerbose());
121
        }
122
123
        $executionTime = (microtime(true) - $timeStart);
124
        $this->info(sprintf(
125
            "\nAll done! Finished in %s seconds (%sms) with %sMB peak memory usage",
126
            number_format($executionTime, 2),
127
            number_format($executionTime * 1000, 2),
128
            number_format(memory_get_peak_usage() / 1024 / 1024, 2)
129
        ));
130
131
        $this->info('Congratulations! 🎉 Your static site has been built!');
132
        $this->line(
133
            'Your new homepage is stored here -> '.
134
            static::fileLink(Hyde::sitePath('index.html'))
135
        );
136
    }
137
138
    protected function runNodeCommand(string $command, string $message, ?string $actionMessage = null): void
139
    {
140
        $this->info($message.' This may take a second.');
141
142
        $output = shell_exec(sprintf(
143
            '%s%s',
144
            (string) app()->environment() === 'testing' ? 'echo ' : '',
0 ignored issues
show
introduced by
The method environment() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

144
            (string) app()->/** @scrutinizer ignore-call */ environment() === 'testing' ? 'echo ' : '',
Loading history...
145
            $command
146
        ));
147
148
        $this->line($output ?? sprintf(
149
            '<fg=red>Could not %s! Is NPM installed?</>',
150
            $actionMessage ?? 'run script'
151
        ));
152
    }
153
154
    protected function hasWarnings(): bool
155
    {
156
        return BuildWarnings::hasWarnings() && BuildWarnings::reportsWarnings();
157
    }
158
159
    protected function getExitCode(): int
160
    {
161
        if ($this->hasWarnings() && BuildWarnings::reportsWarningsAsExceptions()) {
162
            return Command::INVALID;
163
        }
164
165
        return Command::SUCCESS;
166
    }
167
}
168