Completed
Pull Request — master (#10)
by Julien
04:19
created

KubernetesDeployJobEvent::getDeployBranch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\AentGitLabCI\Event;
4
5
use Safe\Exceptions\FilesystemException;
6
use TheAentMachine\Aent\Event\CI\AbstractCIKubernetesDeployJobEvent;
7
use TheAentMachine\Aent\K8SProvider\Provider;
8
use TheAentMachine\AentGitLabCI\Context\BaseGitLabCIContext;
9
use TheAentMachine\AentGitLabCI\Exception\GitLabCIFileException;
10
use TheAentMachine\AentGitLabCI\Exception\JobException;
11
use TheAentMachine\AentGitLabCI\GitLabCI\GitLabCIFile;
12
use TheAentMachine\AentGitLabCI\GitLabCI\Job\CleanupKubernetesJob;
13
use TheAentMachine\AentGitLabCI\GitLabCI\Job\DeployKubernetesJob;
14
use TheAentMachine\AentGitLabCI\GitLabCI\Job\Model\BranchesModel;
15
use TheAentMachine\Exception\MissingEnvironmentVariableException;
16
use TheAentMachine\Prompt\Helper\ValidatorHelper;
17
18
final class KubernetesDeployJobEvent extends AbstractCIKubernetesDeployJobEvent
19
{
20
    /** @var string[] */
21
    private $deployBranches = [];
22
23
    /** @var string[] */
24
    private $ignoredBranches = [];
25
26
    /**
27
     * @param string $directoryName
28
     * @param Provider $provider
29
     * @throws FilesystemException
30
     * @throws GitLabCIFileException
31
     * @throws JobException
32
     * @throws MissingEnvironmentVariableException
33
     */
34
    protected function addDeployJob(string $directoryName, Provider $provider): void
35
    {
36
        $this->output->writeln("\n🦊 Currently, we only support a deploy on branches when using Kubernetes as orchestrator!");
37
        $branchesModel = $this->getBranches();
38
        $isManual = $this->deployManually();
39
        $this->prompt->printAltBlock("GitLab: adding deploy job...");
40
        $context = new BaseGitLabCIContext();
41
        $context->setBranchesModel($branchesModel);
42
        $context->toMetadata();
43
        if ($provider->getName() === Provider::GOOGLE_CLOUD) {
44
            $job = DeployKubernetesJob::newDeployOnGCloud($directoryName, $context, $branchesModel, $isManual);
45
        } else {
46
            $job = DeployKubernetesJob::newDeployOnRancher($directoryName, $context, $branchesModel, $isManual);
47
        }
48
        $file = new GitLabCIFile();
49
        $file->findOrCreate();
50
        $file->addDeploy($job);
51
        $this->prompt->printAltBlock("GitLab: adding cleanup job...");
52
        if ($provider->getName() === Provider::GOOGLE_CLOUD) {
53
            $job = CleanupKubernetesJob::newCleanupForGCloud($context, $branchesModel, $isManual);
54
        } else {
55
            $job = CleanupKubernetesJob::newCleanupForRancher($context, $branchesModel, $isManual);
56
        }
57
        $file->addCleanUp($job);
58
    }
59
60
    /**
61
     * @return BranchesModel
62
     * @throws JobException
63
     */
64
    private function getBranches(): BranchesModel
65
    {
66
        $text = "\nBranch for deploy (keep empty if you don't want to use a specific branch)";
67
        $helpText = "A branch for which GitLab will deploy your stack and create images from Dockerfiles.";
68
        $branchName = $this->getDeployBranch($text, $helpText);
69
        if (!empty($branchName)) {
70
            $this->deployBranches[] = $branchName;
71
            $text = $text = "\nBranch (keep empty to skip)";
0 ignored issues
show
Unused Code introduced by
The assignment to $text is dead and can be removed.
Loading history...
72
            do {
73
                $branchName = $this->getDeployBranch($text, $helpText);
74
                if (!empty($branchName)) {
75
                    $this->deployBranches[] = $branchName;
76
                }
77
            } while (!empty($branchName));
78
        }
79
        $text = "\nBranch to ignore (keep empty to skip)";
80
        $helpText = "A branch for which GitLab will NOT deploy your stack and create images from Dockerfiles.";
81
        $branchName = $this->getIgnoredBranch($text, $helpText);
82
        if (!empty($branchName)) {
83
            $this->ignoredBranches[] = $branchName;
84
            do {
85
                $branchName = $this->getIgnoredBranch($text, $helpText);
86
                if (!empty($branchName)) {
87
                    $this->ignoredBranches[] = $branchName;
88
                }
89
            } while (!empty($branchName));
90
        }
91
        if (empty($this->deployBranches)) {
92
            $this->deployBranches = [ 'branches' ];
93
        }
94
        return new BranchesModel($this->deployBranches, $this->ignoredBranches);
95
    }
96
97
    /**
98
     * @param string $text
99
     * @param string $helpText
100
     * @return null|string
101
     */
102
    private function getDeployBranch(string $text, string $helpText): ?string
103
    {
104
        $validator = ValidatorHelper::merge(
105
            ValidatorHelper::getFuncShouldNotReturnTrueValidator([$this, 'doesDeployBranchExist'], 'Deploy branch "%s" does already exist!'),
106
            ValidatorHelper::getAlphaWithAdditionalCharactersValidator(['_', '.', '-'])
107
        );
108
        return $this->prompt->input($text, $helpText, null, false, $validator);
109
    }
110
111
    /**
112
     * @param string $text
113
     * @param string $helpText
114
     * @return null|string
115
     */
116
    private function getIgnoredBranch(string $text, string $helpText): ?string
117
    {
118
        $validator = ValidatorHelper::merge(
119
            ValidatorHelper::getFuncShouldNotReturnTrueValidator([$this, 'doesIgnoredBranchExist'], 'Branch "%s" is already ignored or used for deploy!'),
120
            ValidatorHelper::getAlphaWithAdditionalCharactersValidator(['_', '.', '-'])
121
        );
122
        return $this->prompt->input($text, $helpText, null, false, $validator);
123
    }
124
125
    /**
126
     * @param string|null $branchName
127
     * @return bool
128
     */
129
    public function doesDeployBranchExist(?string $branchName): bool
130
    {
131
        if (empty($branchName)) {
132
            return false;
133
        }
134
        foreach ($this->deployBranches as $deployBranchName) {
135
            if ($deployBranchName === $branchName) {
136
                return true;
137
            }
138
        }
139
        return false;
140
    }
141
142
    /**
143
     * @param string|null $branchName
144
     * @return bool
145
     */
146
    public function doesIgnoredBranchExist(?string $branchName): bool
147
    {
148
        $resp = $this->doesDeployBranchExist($branchName);
149
        if ($resp) {
150
            return $resp;
151
        }
152
        foreach ($this->ignoredBranches as $ignoredBranchName) {
153
            if ($ignoredBranchName === $branchName) {
154
                return true;
155
            }
156
        }
157
        return false;
158
    }
159
160
    /**
161
     * @return bool
162
     */
163
    private function deployManually(): bool
164
    {
165
        $text = "\nDo you want to deploy your stack <info>manually</info>?";
166
        return $this->prompt->confirm($text, null, null, true);
167
    }
168
}
169