GenerateCommand::execute()   C
last analyzed

Complexity

Conditions 13
Paths 23

Size

Total Lines 207
Code Lines 117

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 117
c 1
b 0
f 0
nc 23
nop 2
dl 0
loc 207
rs 5.2933

How to fix   Long Method    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
declare(strict_types=1);
4
5
namespace Thruster\Tool\ProjectGenerator\Console\Command;
6
7
use GitWrapper\GitWrapper;
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Helper\ProgressBar;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Console\Question\Question;
13
use Symfony\Component\Filesystem\Filesystem;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\Finder\SplFileInfo;
16
17
/**
18
 * Class GenerateCommand.
19
 *
20
 * @author  Aurimas Niekis <[email protected]>
21
 */
22
class GenerateCommand extends Command
23
{
24
    /**
25
     * {@inheritdoc}
26
     */
27
    protected function configure(): void
28
    {
29
        $this->setName('main');
30
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    protected function execute(InputInterface $input, OutputInterface $output)
36
    {
37
        $helper = $this->getHelper('question');
38
39
        $output->writeln(
40
            [
41
                $this->getApplication()->getLongVersion(),
42
                '',
43
            ]
44
        );
45
46
        $question = new Question('<question>Please enter project name in title case:</question> ');
47
48
        $name = $helper->ask($input, $output, $question);
49
50
        if (empty($name)) {
51
            $output->writeln(
52
                [
53
                    '',
54
                    '<error>Error: Project name cannot be empty</error>',
55
                ]
56
            );
57
58
            return 1;
59
        }
60
61
        if (false === ctype_upper($name[0])) {
62
            $output->writeln(
63
                [
64
                    '',
65
                    '<error>Error: Project name must be title case</error>',
66
                ]
67
            );
68
69
            return 1;
70
        }
71
72
        $nameCan     = strtolower(preg_replace('/(?<!^)([A-Z])/', '-$1', str_replace('_', '-', $name)));
73
        $projectPath = getcwd() . '/' . $nameCan;
74
75
        if (file_exists($projectPath) || is_dir($projectPath)) {
76
            $output->writeln(
77
                [
78
                    '',
79
                    '<error>Error: Project with name "' . $nameCan . '" already exists</error>',
80
                ]
81
            );
82
83
            return 1;
84
        }
85
86
        $projectTypes = ['Component', 'Tool', 'Bundle', 'Action'];
87
        $question     = new Question('<question>Please enter project type (Component):</question> ', 'Component');
88
        $question->setAutocompleterValues($projectTypes);
89
90
        $projectType = $helper->ask($input, $output, $question);
91
92
        if (empty($projectType)) {
93
            $output->writeln(
94
                [
95
                    '',
96
                    '<error>Error: Project type cannot be empty</error>',
97
                ]
98
            );
99
100
            return 1;
101
        }
102
103
        if (false === ctype_upper($projectType[0])) {
104
            $output->writeln(
105
                [
106
                    '',
107
                    '<error>Error: Project type must be title case</error>',
108
                ]
109
            );
110
111
            return 1;
112
        }
113
114
        $author    = rtrim(shell_exec('git config --get user.name'));
115
        $authorSug = '';
116
        if (null !== $author) {
117
            $authorSug = '(' . $author . ')';
118
        }
119
        $question = new Question('<question>Please enter author ' . $authorSug . ':</question> ', $author);
120
121
        $author = $helper->ask($input, $output, $question);
122
123
        if (empty($author)) {
124
            $output->writeln(
125
                [
126
                    '',
127
                    '<error>Error: Author cannot be empty</error>',
128
                ]
129
            );
130
131
            return 1;
132
        }
133
134
        $email    = rtrim(shell_exec('git config --get user.email'));
135
        $emailSug = '';
136
        if (null !== $email) {
137
            $emailSug = '(' . $email . ')';
138
        }
139
        $question = new Question('<question>Please enter email ' . $emailSug . ':</question> ', $email);
140
141
        $email = $helper->ask($input, $output, $question);
142
143
        if (empty($email)) {
144
            $output->writeln(
145
                [
146
                    '',
147
                    '<error>Error: Email cannot be empty</error>',
148
                ]
149
            );
150
151
            return 1;
152
        }
153
154
        $repo     = '[email protected]:ThrusterIO/' . $nameCan . '.git';
155
        $question = new Question('<question>Please enter git repository (' . $repo . '):</question> ', $repo);
156
157
        $repo = $helper->ask($input, $output, $question);
158
159
        if (empty($email)) {
160
            $output->writeln(
161
                [
162
                    '',
163
                    '<error>Error: Git repository cannot be empty</error>',
164
                ]
165
            );
166
167
            return 1;
168
        }
169
170
        $output->writeln(['']);
171
172
        $year = date('Y');
173
174
        $output->write('<info>Cloning project template: </info>');
175
        $wrapper = new GitWrapper();
176
        $wrapper->cloneRepository('[email protected]:ThrusterIO/project-template.git', $projectPath);
177
        $output->writeln('<comment>Done</comment>');
178
179
        $fs = new Filesystem();
180
        $output->write('<info>Removing .git folder: </info>');
181
        $fs->remove($projectPath . '/.git');
182
        $output->writeln('<comment>Done</comment>');
183
184
        $output->write('<info>Removing src/.gitkeep file: </info>');
185
        $fs->remove($projectPath . '/src/.gitkeep');
186
        $output->writeln('<comment>Done</comment>');
187
188
        $output->write('<info>Removing tests/.gitkeep file: </info>');
189
        $fs->remove($projectPath . '/tests/.gitkeep');
190
        $output->writeln('<comment>Done</comment>');
191
192
        $output->write('<info>Initialized empty Git repository: </info>');
193
        $git = $wrapper->init($projectPath);
194
        $output->writeln('<comment>Done</comment>');
195
196
        $finder = new Finder();
197
        $finder->in($projectPath)->ignoreDotFiles(false)->files();
198
199
        $output->writeln(['', '<info>Applying variables to files: </info>']);
200
        $progress = new ProgressBar($output, count($finder));
201
        $progress->setFormat('debug');
202
        $progress->start();
203
204
        /** @var SplFileInfo $file */
205
        foreach ($finder as $file) {
206
            $searchFor = [
207
                '${NAME}$',
208
                '${NAME_CAN}$',
209
                '${PROJECT_TYPE}$',
210
                '${YEAR}$',
211
                '${AUTHOR}$',
212
                '${EMAIL}$',
213
            ];
214
215
            $replaceWith = [
216
                $name,
217
                $nameCan,
218
                $projectType,
219
                $year,
220
                $author,
221
                $email,
222
            ];
223
224
            $progress->setMessage($file->getFilename());
225
226
            file_put_contents(
227
                $file->getRealPath(),
228
                str_replace($searchFor, $replaceWith, $file->getContents())
229
            );
230
231
            $progress->advance();
232
        }
233
234
        $progress->finish();
235
236
        $git->remote('add', 'origin', $repo);
237
        $git->add('./');
238
239
        $output->writeln(['', '', '<comment>Finished.</comment>']);
240
241
        return 0;
242
    }
243
}
244