CruiseInstall   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 11
eloc 56
c 2
b 0
f 0
dl 0
loc 114
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 28 5
A promptForMissingArgumentsUsing() 0 15 1
A addComposerScript() 0 10 2
A renameDockerImages() 0 27 3
1
<?php
2
3
namespace Sfneal\Cruise\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Contracts\Console\PromptsForMissingInput;
7
use Illuminate\Process\Pipe;
8
use Illuminate\Support\Facades\Artisan;
9
use Illuminate\Support\Facades\Process;
10
11
use function Laravel\Prompts\text;
12
13
class CruiseInstall extends Command implements PromptsForMissingInput
14
{
15
    /**
16
     * The name and signature of the console command.
17
     *
18
     * @var string
19
     */
20
    protected $signature = 'cruise:install
21
                            {docker_id : Your docker ID you will be using with your laravel application}
22
                            {docker_image : Your laravel applications docker image name}';
23
24
    /**
25
     * The console command description.
26
     *
27
     * @var string
28
     */
29
    protected $description = 'Install the cruise package and publish files';
30
31
    /**
32
     * Execute the console command.
33
     */
34
    public function handle(): int
35
    {
36
        Artisan::call('vendor:publish', ['--tag' => 'cruise-config']);
37
        $this->info('Published cruise config files config/cruise.php');
38
39
        Artisan::call('vendor:publish', ['--tag' => 'docker']);
40
        $this->info('Published docker assets to the application root');
41
42
        $this->renameDockerImages($this->argument('docker_id'), $this->argument('docker_image'));
43
44
        $this->addComposerScript('start-dev');
45
        $this->addComposerScript('start-dev-db');
46
        $this->addComposerScript('start-dev-node');
47
        $this->addComposerScript('start-test');
48
        $this->addComposerScript('stop');
49
        $this->addComposerScript('build');
50
        $this->info('Published composer scripts for starting/stopping docker services');
51
52
        if (! file_exists(base_path('.env.dev')) && file_exists(base_path('.env'))) {
53
            copy(base_path('.env'), base_path('.env.dev'));
54
            $this->info('Published missing .env.dev file');
55
        }
56
        if (! file_exists(base_path('.env.dev.db')) && file_exists(base_path('.env'))) {
57
            copy(base_path('.env.dev'), base_path('.env.dev.db'));
58
            $this->info('Published missing .env.dev.db file');
59
        }
60
61
        return self::SUCCESS;
62
    }
63
64
    private function addComposerScript(string $script): void
65
    {
66
        $script_path = 'vendor/sfneal/cruise/scripts/runners';
67
68
        $process = Process::run([
69
            'composer', 'config', "scripts.$script", "sh $script_path/$script.sh", '--working-dir='.base_path(),
70
        ]);
71
72
        if ($process->successful()) {
73
            $this->info("Added 'composer $script' command to composer.json");
74
        }
75
    }
76
77
    private function renameDockerImages(string $docker_id, string $image_name): void
78
    {
79
        $og_full_image_name = trim(Process::path(base_path())
80
            ->run("grep -A 10 'services:' docker-compose.yml | grep -A 1 'app:' | grep 'image:' | awk '{print $2}' | grep -o '^[^:]*'")
81
            ->output());
82
83
        $process = Process::pipe(function (Pipe $pipe) use ($og_full_image_name, $docker_id, $image_name) {
84
            [$og_docker_id, $og_image_name] = explode('/', $og_full_image_name);
85
86
            $docker_compose_files = [
87
                'docker-compose.yml',
88
                'docker-compose-dev.yml',
89
                'docker-compose-dev-db.yml',
90
                'docker-compose-dev-node.yml',
91
                'docker-compose-tests.yml',
92
            ];
93
94
            foreach ($docker_compose_files as $docker_file) {
95
                $pipe->path(base_path())->command("sed -i'' 's|$og_docker_id|$docker_id|g' ".$docker_file);
96
                $pipe->path(base_path())->command(trim("sed -i'' 's|$og_image_name|$image_name|g' ".$docker_file));
97
            }
98
        });
99
100
        if ($process->successful()) {
101
            $this->info("Renamed docker images from {$og_full_image_name} to {$docker_id}/{$image_name}");
102
        } else {
103
            $this->info("Failed to rename docker images from {$og_full_image_name} to {$docker_id}/{$image_name}");
104
        }
105
    }
106
107
    /**
108
     * Prompt for missing input arguments using the returned questions.
109
     *
110
     * @return array<string, string>
111
     */
112
    protected function promptForMissingArgumentsUsing(): array
113
    {
114
        return [
115
            'docker_id' => function () {
116
                return text(
117
                    label: 'Enter your Docker ID:',
118
                    placeholder: 'E.g. mydockerid',
119
                    required: true,
120
                );
121
            },
122
            'docker_image' => function () {
123
                return text(
124
                    label: 'Enter your Docker image name (recommend using application name):',
125
                    placeholder: 'E.g. myapplication',
126
                    required: true,
127
                );
128
            },
129
        ];
130
    }
131
}
132