Passed
Push — master ( f2f8c0...5c7f99 )
by Caen
02:56 queued 13s
created

HydeBuildSiteCommand   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 58
dl 0
loc 150
rs 10
c 0
b 0
f 0
wmc 14

8 Methods

Rating   Name   Duplication   Size   Complexity  
A canGenerateSearch() 0 3 1
A runPreBuildActions() 0 14 3
A runPostBuildActions() 0 25 4
A canGenerateFeed() 0 3 1
A printFinishMessage() 0 13 1
A canGenerateSitemap() 0 3 1
A handle() 0 21 1
A runNodeCommand() 0 13 2
1
<?php
2
3
namespace Hyde\Framework\Commands;
4
5
use Exception;
6
use Hyde\Framework\Actions\PostBuildTasks\GenerateRssFeed;
7
use Hyde\Framework\Actions\PostBuildTasks\GenerateSearch;
8
use Hyde\Framework\Actions\PostBuildTasks\GenerateSitemap;
9
use Hyde\Framework\Helpers\Features;
10
use Hyde\Framework\Hyde;
11
use Hyde\Framework\Services\BuildService;
12
use Hyde\Framework\Services\BuildTaskService;
13
use Hyde\Framework\Services\DiscoveryService;
14
use Illuminate\Support\Facades\Config;
15
use LaravelZero\Framework\Commands\Command;
16
17
/**
18
 * Hyde Command to run the Build Process.
19
 *
20
 * @see \Hyde\Framework\Testing\Feature\StaticSiteServiceTest
21
 */
22
class HydeBuildSiteCommand extends Command
23
{
24
    /**
25
     * The signature of the command.
26
     *
27
     * @var string
28
     */
29
    protected $signature = 'build 
30
        {--run-dev : Run the NPM dev script after build}
31
        {--run-prod : Run the NPM prod script after build}
32
        {--run-prettier : Format the output using NPM Prettier}
33
        {--pretty-urls : Should links in output use pretty URLs?}
34
        {--no-api : Disable API calls, for example, Torchlight}';
35
36
    /**
37
     * The description of the command.
38
     *
39
     * @var string
40
     */
41
    protected $description = 'Build the static site';
42
43
    protected BuildService $service;
44
45
    /**
46
     * Execute the console command.
47
     *
48
     * @return int
49
     *
50
     * @throws Exception
51
     */
52
    public function handle(): int
53
    {
54
        $time_start = microtime(true);
55
56
        $this->title('Building your static site!');
57
58
        $this->service = new BuildService($this->output);
59
60
        $this->runPreBuildActions();
61
62
        $this->service->cleanOutputDirectory();
63
64
        $this->service->transferMediaAssets();
65
66
        $this->service->compileStaticPages();
67
68
        $this->runPostBuildActions();
69
70
        $this->printFinishMessage($time_start);
0 ignored issues
show
Bug introduced by
It seems like $time_start can also be of type string; however, parameter $time_start of Hyde\Framework\Commands\...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

70
        $this->printFinishMessage(/** @scrutinizer ignore-type */ $time_start);
Loading history...
71
72
        return 0;
73
    }
74
75
    /** @internal */
76
    protected function runPreBuildActions(): void
77
    {
78
        if ($this->option('no-api')) {
79
            $this->info('Disabling external API calls');
80
            $this->newLine();
81
            $config = config('hyde.features');
82
            unset($config[array_search('torchlight', $config)]);
83
            Config::set(['hyde.features' => $config]);
84
        }
85
86
        if ($this->option('pretty-urls')) {
87
            $this->info('Generating site with pretty URLs');
88
            $this->newLine();
89
            Config::set(['site.pretty_urls' => true]);
90
        }
91
    }
92
93
    /**
94
     * Run any post-build actions.
95
     *
96
     * @return void
97
     */
98
    public function runPostBuildActions(): void
99
    {
100
        $service = new BuildTaskService($this->output);
101
102
        if ($this->option('run-prettier')) {
103
            $this->runNodeCommand(
104
                'npx prettier '.Hyde::pathToRelative(Hyde::getSiteOutputPath()).'/**/*.html --write --bracket-same-line',
105
                'Prettifying code!',
106
                'prettify code'
107
            );
108
        }
109
110
        if ($this->option('run-dev')) {
111
            $this->runNodeCommand('npm run dev', 'Building frontend assets for development!');
112
        }
113
114
        if ($this->option('run-prod')) {
115
            $this->runNodeCommand('npm run prod', 'Building frontend assets for production!');
116
        }
117
118
        $service->runIf(GenerateSitemap::class, $this->canGenerateSitemap());
119
        $service->runIf(GenerateRssFeed::class, $this->canGenerateFeed());
120
        $service->runIf(GenerateSearch::class, $this->canGenerateSearch());
121
122
        $service->runPostBuildTasks();
123
    }
124
125
    /** @internal */
126
    protected function printFinishMessage(float $time_start): void
127
    {
128
        $execution_time = (microtime(true) - $time_start);
129
        $this->info(sprintf(
130
            'All done! Finished in %s seconds. (%sms)',
131
            number_format($execution_time, 2),
132
            number_format($execution_time * 1000, 2)
133
        ));
134
135
        $this->info('Congratulations! 🎉 Your static site has been built!');
136
        $this->line(
137
            'Your new homepage is stored here -> '.
138
            DiscoveryService::createClickableFilepath(Hyde::getSiteOutputPath('index.html'))
139
        );
140
    }
141
142
    /* @internal */
143
    protected function runNodeCommand(string $command, string $message, ?string $actionMessage = null): void
144
    {
145
        $this->info($message.' This may take a second.');
146
147
        $output = shell_exec(sprintf(
148
            '%s%s',
149
            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

149
            app()->/** @scrutinizer ignore-call */ environment() === 'testing' ? 'echo ' : '',
Loading history...
150
            $command
151
        ));
152
153
        $this->line($output ?? sprintf(
154
            '<fg=red>Could not %s! Is NPM installed?</>',
155
            $actionMessage ?? 'run script'
156
        ));
157
    }
158
159
    protected function canGenerateSitemap(): bool
160
    {
161
        return Features::sitemap();
162
    }
163
164
    protected function canGenerateFeed(): bool
165
    {
166
        return Features::rss();
167
    }
168
169
    protected function canGenerateSearch(): bool
170
    {
171
        return Features::hasDocumentationSearch();
172
    }
173
}
174