Passed
Push — dev5 ( 8481ee...a622eb )
by Ron
03:52 queued 01:34
created

updateRun::handle()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 11
nc 3
nop 0
dl 0
loc 21
ccs 0
cts 11
cp 0
crap 12
rs 9.9
c 1
b 0
f 0
1
<?php
2
3
namespace App\Console\Commands;
4
5
use Zip;
6
7
use Illuminate\Console\Command;
8
9
use Illuminate\Support\Facades\File;
10
use Illuminate\Support\Facades\Storage;
11
12
class updateRun extends Command
13
{
14
    protected $signature   = 'tb-update:run';
15
    protected $description = 'Update the Tech Bench to a newer version';
16
17
    public function handle()
18
    {
19
        $this->line('');
20
        //  Select which update file to use
21
        $updateFile = $this->checkForUpdate();
22
        if($updateFile)
23
        {
24
            //  Open up the file and verify it is at least the same version as the current setup
25
            $valid = $this->openUpdate($updateFile);
26
27
            if($valid)
28
            {
29
                $this->call('down');
30
                $this->copyFiles($updateFile);
31
32
                $this->info('Update Completed');
33
            }
34
            else
35
            {
36
                $this->error('The selected update is not a newer version');
37
                $this->error('Cannot downgrade Tech Bench in this manner');
38
            }
39
        }
40
    }
41
42
    //  Check to see if any backups are in the backup folder
43
    protected function checkForUpdate()
44
    {
45
        $updateList = [];
46
        $updates    = Storage::disk('staging')->files('updates');
47
48
        //  Cycle through each file in the update directory to see if they are update files
49
        foreach($updates as $update)
50
        {
51
            $baseName = explode('/', $update)[1];
52
53
            //  Verify the file is in the .zip format
54
            $fileParts = pathinfo($baseName);
55
            if($fileParts['extension'] == 'zip')
56
            {
57
                //  Verify this is actually an update file
58
                $zip = Zip::open(config('filesystems.disks.staging.root').
59
                    DIRECTORY_SEPARATOR.'updates'.DIRECTORY_SEPARATOR.$baseName);
60
                $files = $zip->listFiles();
61
                if(in_array($fileParts['filename'].'/config/version.yml', $files))
62
                {
63
                    $updateList[] = $baseName;
64
                }
65
            }
66
        }
67
68
        if(empty($updateList))
69
        {
70
            $this->error('No updates have been loaded to the system');
71
            $this->error('Please upload update package to the Storage/Staging/Updates folder');
72
            return false;
73
        }
74
75
        //  Determine if there is more than one update that can be applied
76
        if(count($updateList) > 1)
77
        {
78
            $this->line('');
79
80
            $anticipate = [];
81
            foreach($updateList as $key => $up) {
82
                $opt = $key + 1;
83
                $anticipate[$opt] = $up;
84
                $this->line('['.$opt.'] '.$up);
85
            }
86
            $updateFile = $this->choice('Please select which update you would like to load', $anticipate);
87
        }
88
        else
89
        {
90
            $updateFile = $updateList[0];
91
        }
92
93
        return $updateFile;
94
    }
95
96
    //  Unzip the update and verify it is a newer or the same version
97
    protected function openUpdate($file)
98
    {
99
        $fileParts = pathinfo($file);
100
        $folder = $fileParts['filename'];
101
102
        $zip = Zip::open(config('filesystems.disks.staging.root').
103
            DIRECTORY_SEPARATOR.'updates'.DIRECTORY_SEPARATOR.$file);
104
105
        $zip->extract(config('filesystems.disks.staging.root').
106
            DIRECTORY_SEPARATOR.'updates'.DIRECTORY_SEPARATOR.'tmp');
107
        $zip->close();
108
109
        $verFile = fopen(config('filesystems.disks.staging.root').
110
            DIRECTORY_SEPARATOR.'updates'.DIRECTORY_SEPARATOR.'tmp'.
111
            DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.'config'.
112
            DIRECTORY_SEPARATOR.'version.yml', 'r');
113
114
        $verData = [];
115
        $i = 0;
116
        while(!feof(
117
        /** @scrutinizer ignore-type */
118
        $verFile))
119
        {
120
            $line = fgets(
121
            /** @scrutinizer ignore-type */
122
            $verFile);
123
            $data = explode(':', $line);
124
125
            if(($data[0] === '  major' || $data[0] === '  minor' || $data[0] === '  patch') && $i < 3)
126
            {
127
                $verData[trim($data[0])] = trim($data[1]);
128
                $i++;
129
            }
130
        }
131
132
        $curVersion = new \PragmaRX\Version\Package\Version();
133
134
        $valid = false;
135
        if($verData['major'] > $curVersion->major())
136
        {
137
            $valid = true;
138
        }
139
        else if($verData['minor'] > $curVersion->minor())
140
        {
141
            $valid = true;
142
        }
143
        else if($verData['patch'] >= $curVersion->patch())
144
        {
145
            $valid = true;
146
        }
147
148
        return $valid;
149
    }
150
151
    //  copy the update files to the proper folders
152
    protected function copyFiles($updateFile)
153
    {
154
        $fileParts = pathinfo($updateFile);
155
        $folder = $fileParts['filename'];
156
157
        $updateFile = config('filesystems.disks.staging.root').
158
            DIRECTORY_SEPARATOR.'updates'.DIRECTORY_SEPARATOR.'tmp'.
159
            DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR;
160
161
        // Copy files
162
        File::copyDirectory($updateFile.'app',       base_path().DIRECTORY_SEPARATOR.'app');
163
        File::copyDirectory($updateFile.'bootstrap', base_path().DIRECTORY_SEPARATOR.'bootstrap');
164
        File::copyDirectory($updateFile.'config',    base_path().DIRECTORY_SEPARATOR.'config');
165
        File::copyDirectory($updateFile.'database',  base_path().DIRECTORY_SEPARATOR.'database');
166
        File::copyDirectory($updateFile.'public',    base_path().DIRECTORY_SEPARATOR.'public');
167
        File::copyDirectory($updateFile.'resources', base_path().DIRECTORY_SEPARATOR.'resources');
168
        File::copyDirectory($updateFile.'routes',    base_path().DIRECTORY_SEPARATOR.'routes');
169
        File::copy($updateFile.'composer.json',      base_path().DIRECTORY_SEPARATOR.'composer.json');
170
        File::copy($updateFile.'composer.lock',      base_path().DIRECTORY_SEPARATOR.'composer.lock');
171
        File::copy($updateFile.'package.json',       base_path().DIRECTORY_SEPARATOR.'package.json');
172
        File::copy($updateFile.'package-lock.json',  base_path().DIRECTORY_SEPARATOR.'package-lock.json');
173
174
        //  Run Composer Updates
175
        exec('cd '.base_path().' && composer install --no-dev --no-interaction --optimize-autoloader --no-ansi > /dev/null 2>&1');
176
        $this->call('ziggy:generate');
177
        //  Run NPM Updates
178
        exec('cd '.base_path().' && npm install --only=production > /dev/null 2>&1');
179
        exec('cd '.base_path().' && npm run production > /dev/null 2>&1');
180
181
        //  Update the database
182
        $this->call('migrate', ['--force' => 'default']);
183
184
        //  Update the cache
185
        $this->call('config:cache');
186
        $this->call('route:cache');
187
188
        //  Put the app back in working order
189
        $this->call('up');
190
191
        return true;
192
    }
193
}
194