UpdateNNTmux::handle()   F
last analyzed

Complexity

Conditions 24
Paths > 20000

Size

Total Lines 126
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 80
c 2
b 1
f 0
dl 0
loc 126
rs 0
cc 24
nc 20904
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Console\Commands;
4
5
use Blacklight\Tmux;
6
use Illuminate\Console\Command;
7
use Illuminate\Support\Facades\App;
8
use Illuminate\Support\Facades\Process;
9
use Ytake\LaravelSmarty\Smarty;
10
11
class UpdateNNTmux extends Command
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'nntmux:all';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Update NNTmux installation';
26
27
    /**
28
     * @var array Decoded JSON updates file.
29
     */
30
    protected $updates = null;
31
32
    /**
33
     * Create a new command instance.
34
     */
35
    public function __construct()
36
    {
37
        parent::__construct();
38
    }
39
40
    /**
41
     * Execute the console command.
42
     */
43
    public function handle(): void
44
    {
45
        $maintenance = $this->appDown();
46
        $running = $this->stopTmux();
47
48
        try {
49
            $output = $this->call('nntmux:git');
50
            if ($output === 'Already up-to-date.') {
0 ignored issues
show
introduced by
The condition $output === 'Already up-to-date.' is always false.
Loading history...
51
                $this->info($output);
52
            } else {
53
                $status = $this->call('nntmux:composer');
54
                if ($status) {
55
                    $this->error('Composer failed to update!!');
56
                }
57
                $fail = $this->call('nntmux:db');
58
                if ($fail) {
59
                    $this->error('Db updating failed!!');
60
                }
61
            }
62
        } catch (\Exception $e) {
63
            $this->error($e->getMessage());
64
        }
65
66
        // Install npm packages
67
        $this->info('Installing npm packages...');
68
        $process = Process::timeout(360)->run('npm install');
69
        echo $process->output();
70
        echo $process->errorOutput();
71
        $this->info('Npm packages installed successfully!');
72
        // Run npm build
73
        $this->info('Building assets...');
74
        $process = Process::timeout(360)->run('npm run build');
75
        echo $process->output();
76
        echo $process->errorOutput();
77
        $this->info('Assets built successfully!');
78
79
        $cleared = (new Smarty)->setCompileDir(config('ytake-laravel-smarty.compile_path'))->clearCompiledTemplate();
80
        if ($cleared) {
81
            $this->output->writeln('<comment>The Smarty compiled template cache has been cleaned for you</comment>');
82
        } else {
83
            $this->output->writeln(
84
                '<comment>You should clear your Smarty compiled template cache at: '.
85
                config('ytake-laravel-smarty.compile_path').'</comment>'
86
            );
87
        }
88
89
        // Merge changes from .env.example into .env
90
        $this->info('Merging changes from .env.example into .env...');
91
92
        try {
93
            // Read both files
94
            $envExampleContent = file_get_contents(base_path('.env.example'));
95
            $envContent = file_get_contents(base_path('.env'));
96
97
            if ($envExampleContent === false || $envContent === false) {
98
                throw new \Exception('Could not read .env or .env.example files');
99
            }
100
101
            // Parse files into key-value pairs
102
            $envExampleVars = [];
103
            foreach (preg_split("/\r\n|\n|\r/", $envExampleContent) as $line) {
104
                $line = trim($line);
105
                if (empty($line) || str_starts_with($line, '#')) {
106
                    continue;
107
                }
108
109
                if (preg_match('/^([^=]+)=(.*)$/', $line, $matches)) {
110
                    $key = trim($matches[1]);
111
                    $value = $matches[2]; // Keep the original value with potential = signs
112
                    $envExampleVars[$key] = $value;
113
                }
114
            }
115
116
            $envVars = [];
117
            foreach (preg_split("/\r\n|\n|\r/", $envContent) as $line) {
118
                $line = trim($line);
119
                if (empty($line) || str_starts_with($line, '#')) {
120
                    continue;
121
                }
122
123
                if (preg_match('/^([^=]+)=(.*)$/', $line, $matches)) {
124
                    $key = trim($matches[1]);
125
                    $value = $matches[2];
126
                    $envVars[$key] = $value;
127
                }
128
            }
129
130
            // Find keys in .env.example that are not in .env
131
            $missingKeys = array_diff_key($envExampleVars, $envVars);
132
133
            if (empty($missingKeys)) {
134
                $this->info('No new keys found in .env.example to merge into .env');
135
            } else {
136
                // Add missing keys to .env file
137
                $newEnvContent = $envContent;
138
                if (! str_ends_with($newEnvContent, "\n")) {
139
                    $newEnvContent .= "\n";
140
                }
141
                $newEnvContent .= "\n# New settings added from .env.example\n";
142
143
                foreach ($missingKeys as $key => $value) {
144
                    $newEnvContent .= "$key=$value\n";
145
                }
146
147
                // Write updated content back to .env
148
                if (file_put_contents(base_path('.env'), $newEnvContent)) {
149
                    $this->info('Successfully merged '.count($missingKeys).' new keys from .env.example into .env');
150
                    $this->line('The following keys were added:');
151
                    foreach ($missingKeys as $key => $value) {
152
                        $this->line("  $key=$value");
153
                    }
154
                } else {
155
                    throw new \Exception('Failed to write changes to .env file');
156
                }
157
            }
158
159
        } catch (\Exception $e) {
160
            $this->error('Failed to merge changes: '.$e->getMessage());
161
            $this->info('There are changes in .env.example that need to be added manually to .env');
162
        }
163
164
        if ($maintenance === true) {
165
            $this->call('up');
166
        }
167
        if ($running === true) {
168
            $this->startTmux();
169
        }
170
    }
171
172
    private function appDown(): bool
173
    {
174
        if (App::isDownForMaintenance() === false) {
175
            $this->call('down', ['--render' => 'errors::maintenance', '--retry' => 120]);
176
177
            return true;
178
        }
179
180
        return false;
181
    }
182
183
    private function stopTmux(): bool
184
    {
185
        if ((new Tmux)->isRunning() === true) {
186
            $this->call('tmux-ui:stop', ['--kill' => true]);
187
188
            return true;
189
        }
190
191
        return false;
192
    }
193
194
    private function startTmux(): void
195
    {
196
        $this->call('tmux-ui:start');
197
    }
198
}
199