Completed
Pull Request — master (#1)
by Jindun
06:14
created

AddEventCommand::askForBranches()   B

Complexity

Conditions 10
Paths 16

Size

Total Lines 48
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 48
rs 7.6666
c 0
b 0
f 0
cc 10
nc 16
nop 0

How to fix   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 TheAentMachine\AentGitLabCI\Command;
4
5
use TheAentMachine\AentGitLabCI\Aenthill\Metadata;
6
use TheAentMachine\AentGitLabCI\Exception\GitLabCIFileException;
7
use TheAentMachine\AentGitLabCI\Exception\JobException;
8
use TheAentMachine\AentGitLabCI\GitLabCI\GitLabCIFile;
9
use TheAentMachine\AentGitLabCI\GitLabCI\Job\Model\BranchesModel;
10
use TheAentMachine\Aenthill\CommonEvents;
11
use TheAentMachine\Aenthill\CommonMetadata;
12
use TheAentMachine\Aenthill\Manifest;
13
use TheAentMachine\Command\AbstractEventCommand;
14
use TheAentMachine\Exception\ManifestException;
15
use TheAentMachine\Exception\MissingEnvironmentVariableException;
16
use TheAentMachine\Question\CommonValidators;
17
18
final class AddEventCommand extends AbstractEventCommand
19
{
20
    protected function getEventName(): string
21
    {
22
        return CommonEvents::ADD_EVENT;
23
    }
24
25
    /**
26
     * @param null|string $payload
27
     * @return null|string
28
     * @throws GitLabCIFileException
29
     * @throws MissingEnvironmentVariableException
30
     * @throws JobException
31
     */
32
    protected function executeEvent(?string $payload): ?string
33
    {
34
        $aentHelper = $this->getAentHelper();
35
        $aentHelper->title('Installing GitLab CI file');
36
37
        $file = new GitLabCIFile();
38
        if ($file->exist()) {
39
            $this->output->writeln('🦊 <info>' . GitLabCIFile::DEFAULT_FILENAME . '</info> found!');
40
        } else {
41
            $file->findOrCreate();
42
            $this->output->writeln('🦊 <info>' . GitLabCIFile::DEFAULT_FILENAME . '</info> was successfully created!');
43
        }
44
45
        $aentHelper->spacer();
46
47
        if (null === Manifest::getMetadata(Metadata::REGISTRY_DOMAIN_NAME_KEY)) {
48
            $registryDomainName = $this->askForRegistryDomainName();
49
            Manifest::addMetadata(Metadata::REGISTRY_DOMAIN_NAME_KEY, $registryDomainName);
50
        }
51
52
        if (null === Manifest::getMetadata(Metadata::PROJECT_GROUP_KEY)) {
53
            $projectGroup = $this->askForProjectGroup();
54
            Manifest::addMetadata(Metadata::PROJECT_GROUP_KEY, $projectGroup);
55
        }
56
57
        if (null === Manifest::getMetadata(Metadata::PROJECT_NAME_KEY)) {
58
            $projectName = $this->askForProjectName();
59
            Manifest::addMetadata(Metadata::PROJECT_NAME_KEY, $projectName);
60
        }
61
62
        if (null === Manifest::getMetadata(CommonMetadata::IS_VARIABLE_ENVIRONMENT)) {
63
            $branchesModel = $this->askForBranches();
64
            Manifest::addMetadata(CommonMetadata::IS_VARIABLE_ENVIRONMENT, (string)$branchesModel->isMultipleBranches());
65
        }
66
67
        return Manifest::getMetadata(CommonMetadata::IS_VARIABLE_ENVIRONMENT);
68
    }
69
70
    private function askForRegistryDomainName(): string
71
    {
72
        return $this->getAentHelper()->question('Registry domain name')
73
            ->setHelpText('The domain name of the Docker Container Registry integrated with your Git repository on your GitLab. This is the space where your Docker images are stored.')
74
            ->compulsory()
75
            ->setValidator(CommonValidators::getDomainNameWithPortValidator())
76
            ->ask();
77
    }
78
79
    private function askForProjectGroup(): string
80
    {
81
        return $this->getAentHelper()->question('Project group')
82
            ->setHelpText('The group defined in the project path on GitLab. For example: for the project with URL "https://git.yourcompany.com/foo/bar", "foo" is the group name.')
83
            ->compulsory()
84
            ->setValidator(CommonValidators::getAlphaValidator(['-']))
85
            ->ask();
86
    }
87
88
    private function askForProjectName(): string
89
    {
90
        return $this->getAentHelper()->question('Project name')
91
            ->setHelpText('The project name defined in the project path on GitLab. For example: for the project with URL "https://git.yourcompany.com/foo/bar", "bar" is the project name.')
92
            ->compulsory()
93
            ->setValidator(CommonValidators::getAlphaValidator(['-']))
94
            ->ask();
95
    }
96
97
    /**
98
     * @return BranchesModel
99
     * @throws JobException
100
     */
101
    private function askForBranches(): BranchesModel
102
    {
103
        try {
104
            $branchesModel = BranchesModel::newFromMetadata();
105
            return $branchesModel;
106
        } catch (ManifestException | JobException $e) {
107
            $singleBranch = 'On one single branch';
108
            $allBranches = 'On all branches';
109
            $customBranches = 'Choose custom branches';
110
            $choices = [$singleBranch, $allBranches, $customBranches];
111
            $strategy = $this->getAentHelper()->choiceQuestion('Which deployment strategy to you want to apply?', $choices)
112
                ->ask();
113
114
            $branches = [];
115
            $branchesToIgnore = [];
116
            switch ($strategy) {
117
                case $singleBranch:
118
                    $branches[] = $this->askForBranch(true);
119
                    break;
120
                case $allBranches:
121
                    $branches[] = 'branches';
122
                    break;
123
                case $customBranches:
124
                    $branches[] = $this->askForBranch(true);
125
                    do {
126
                        $anotherBranch = $this->askForBranch(false);
127
                        if (!empty($anotherBranch)) {
128
                            $branches[] = $anotherBranch;
129
                        }
130
                    } while (!empty($anotherBranch));
131
                    break;
132
            }
133
134
            if ($strategy !== $singleBranch) {
135
                do {
136
                    $branchToIgnore = $this->getAentHelper()->question('Git branch to ignore (leave empty to skip)')
137
                        ->setDefault('')
138
                        ->setValidator(CommonValidators::getAlphaValidator(['_', '.', '-'], 'branch names can contain alphanumeric characters and "_", ".", "-".'))
139
                        ->ask();
140
                    if (!empty($branchToIgnore)) {
141
                        $branchesToIgnore[] = $branchToIgnore;
142
                    }
143
                } while (!empty($branchToIgnore));
144
            }
145
146
            $branchesModel = new BranchesModel($branches, $branchesToIgnore);
147
            $branchesModel->feedMetadata();
148
            return $branchesModel;
149
        }
150
    }
151
152
    private function askForBranch(bool $compulsory = true): string
153
    {
154
        $questionText = $compulsory ? 'Git branch' : 'Git branch (leave empty to skip)';
155
        $question = $this->getAentHelper()->question($questionText)
156
            ->setDefault('')
157
            ->setValidator(CommonValidators::getAlphaValidator(['_', '.', '-'], 'branch names can contain alphanumeric characters and "_", ".", "-".'));
158
        if ($compulsory) {
159
            $question->compulsory();
160
        }
161
        return $question->ask();
162
    }
163
}
164