DeployInit   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 162
rs 10
c 0
b 0
f 0
wmc 26
lcom 1
cbo 5

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A handle() 0 9 2
A configFileExists() 0 12 2
A configureBuilder() 0 13 2
A allOptions() 0 17 3
A welcomeMessage() 0 12 2
A defineRepositoryUrl() 0 9 1
A defineHostname() 0 11 2
A defineForge() 0 11 4
A askPhpVersion() 0 7 1
A defineDeployementPath() 0 9 1
A defineAdditionalHooks() 0 22 5
1
<?php
2
3
namespace Reallyli\LaravelDeployer\Commands;
4
5
use Reallyli\LaravelDeployer\ConfigFileBuilder;
6
7
class DeployInit extends BaseCommand
8
{
9
    protected $builder;
10
11
    protected $signature = 'deploy:init
12
        {hostname? : The hostname of the deployment server}
13
        {--f|forge : Whether the server is maintained by Laravel Forge}
14
        {--a|all : Generate configuration with all possible options}
15
    ';
16
17
    protected $useDeployerOptions = false;
18
    protected $description = 'Generate a deploy.php configuration file';
19
20
    public function __construct(ConfigFileBuilder $builder)
21
    {
22
        parent::__construct();
23
        $this->builder = $builder;
24
    }
25
26
    public function handle()
27
    {
28
        if ($this->configFileExists()) {
29
            return;
30
        }
31
32
        $this->configureBuilder();
33
        $this->builder->build()->store();
34
    }
35
36
    public function configFileExists()
37
    {
38
        $filepath = $this->builder->build()->getConfigFullPath();
39
40
        if (file_exists($filepath)) {
41
            $this->confirm("<fg=red;options=bold>A configuration file already exists.</>\nAre you sure you want to continue and override it?");
42
43
            return true;
44
        }
45
46
        return false;
47
    }
48
49
    public function configureBuilder()
50
    {
51
        if ($this->option('all')) {
52
            return $this->allOptions();
53
        }
54
55
        $this->welcomeMessage('🚀', 'Let\'s configure your deployment!');
56
        $this->defineRepositoryUrl();
57
        $this->defineHostname();
58
        $this->defineForge();
59
        $this->defineDeployementPath();
60
        $this->defineAdditionalHooks();
61
    }
62
63
    public function allOptions()
64
    {
65
        if ($hostname = $this->argument('hostname')) {
66
            $this->builder->setHost('name', $hostname);
67
        }
68
69
        if ($this->option('forge')) {
70
            $this->builder->useForge();
71
        } else {
72
            $this->builder->reloadFpm();
73
        }
74
75
        $this->builder->add('hooks.build', 'npm:install');
76
        $this->builder->add('hooks.build', 'npm:production');
77
        $this->builder->add('hooks.ready', 'artisan:migrate');
78
        $this->builder->add('hooks.ready', 'artisan:horizon:terminate');
79
    }
80
81
    public function welcomeMessage($emoji, $message)
82
    {
83
        if (! $this->input->isInteractive()) {
84
            return;
85
        }
86
87
        $this->output->newLine();
88
        $this->comment(str_repeat('*', strlen($message) + 15));
89
        $this->comment("*     $emoji  $message     *");
90
        $this->comment(str_repeat('*', strlen($message) + 15));
91
        $this->output->newLine();
92
    }
93
94
    public function defineRepositoryUrl()
95
    {
96
        $repository = $this->ask(
97
            'Repository URL',
98
            $this->builder->get('options.repository')
99
        );
100
101
        $this->builder->set('options.repository', $repository);
102
    }
103
104
    public function defineHostname()
105
    {
106
        if (! $hostname = $this->argument('hostname')) {
107
            $hostname = $this->ask(
108
                'Hostname of your deployment server',
109
                $this->builder->getHostname()
110
            );
111
        }
112
113
        $this->builder->setHost('name', $hostname);
114
    }
115
116
    public function defineForge()
117
    {
118
        $question = 'Do you use Laravel Forge to maintain your server?';
119
        if ($this->option('forge') || $this->confirm($question)) {
120
            return $this->builder->useForge($this->askPhpVersion());
121
        }
122
123
        if ($this->confirm('Do you want to reload php-fpm after each deployment?')) {
124
            return $this->builder->reloadFpm($this->askPhpVersion());
125
        }
126
    }
127
128
    public function askPhpVersion()
129
    {
130
        return $this->ask(
131
            'Which php version are you using? (format: #.#)',
132
            ConfigFileBuilder::DEFAULT_PHP_VERSION
133
        );
134
    }
135
136
    public function defineDeployementPath()
137
    {
138
        $path = $this->ask(
139
            'Deployment path (absolute to the server)',
140
            $this->builder->getHost('deploy_path')
141
        );
142
143
        $this->builder->setHost('deploy_path', $path);
144
    }
145
146
    public function defineAdditionalHooks()
147
    {
148
        $npm = $this->choice(
149
            'Do you want to compile your asset during deployment?',
150
            ['No', 'Yes using `npm run production`', 'Yes using `npm run development`'],
151
            1
152
        );
153
154
        if ($npm !== 'No') {
155
            $build = $npm === 'Yes using `npm run production`' ? 'production' : 'development';
156
            $this->builder->add('hooks.build', 'npm:install');
157
            $this->builder->add('hooks.build', "npm:$build");
158
        }
159
160
        if ($this->confirm('Do you want to migrate during deployment?', true)) {
161
            $this->builder->add('hooks.ready', 'artisan:migrate');
162
        }
163
164
        if ($this->confirm('Do you want to terminate horizon after each deployment?')) {
165
            $this->builder->add('hooks.ready', 'artisan:horizon:terminate');
166
        }
167
    }
168
}
169