InstallCommand::execute()   C
last analyzed

Complexity

Conditions 10
Paths 17

Size

Total Lines 97
Code Lines 68

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
cc 10
eloc 68
nc 17
nop 2
dl 0
loc 97
ccs 0
cts 68
cp 0
crap 110
rs 6.8315
c 0
b 0
f 0

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
namespace CompoLab\Application\Cli;
4
5
use Symfony\Component\Console\Command\Command;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Input\InputOption;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\Console\Question\ConfirmationQuestion;
10
use Symfony\Component\Console\Question\Question;
11
use Symfony\Component\Yaml\Yaml;
12
13
final class InstallCommand extends Command
14
{
15
    public function configure()
16
    {
17
        $this
18
            ->setName('install')
19
            ->setDescription('Install and configure CompoLab')
20
            ->setHelp('This command help to create a valid configuration, store it into the config/settings.yml file and create the empty public/packages.json file.')
21
            ->addOption('reset', 'r', InputOption::VALUE_NONE, 'Erase existing package index or archives')
22
        ;
23
    }
24
25
    public function execute(InputInterface $input, OutputInterface $output)
26
    {
27
        $helper = $this->getHelper('question'); /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */
28
29
        $root = realpath(__DIR__ . '/../../..');
30
        $packagesJson = sprintf('%s/public/packages.json', $root);
31
        $packageArchives = sprintf('%s/public/archives', $root);
32
33
        if ($input->getOption('reset')) {
34
            $validateReset = $helper->ask($input, $output, new ConfirmationQuestion(
35
                'Are you sure you want to erase all repository packages (y/n)? ', false
36
            ));
37
            if (!$validateReset) {
38
                $output->writeln('Aborting installation.');
39
                return;
40
            }
41
42
            $output->write('Delete public/packages.json... ');
43
            unlink($packagesJson);
44
            $output->writeln('OK');
45
46
            $output->write('Empty public/archives... ');
47
            $this->rmdir($packageArchives);
48
            $output->writeln('OK');
49
        }
50
51
        $composerURL = $helper->ask($input, $output, (new Question(
52
            'Enter the CompoLab server URL (eg. https://composer.my-website.com): '
53
        ))->setNormalizer(function ($value) {
54
            return trim((string) $value);
55
        })->setValidator(function ($value) {
56
            if (!filter_var($value, FILTER_VALIDATE_URL)) {
57
                throw new \InvalidArgumentException('Invalid URL');
58
            }
59
            return $value;
60
        }));
61
62
        $composerPublicDirPath = $helper->ask($input, $output, (new Question(
63
            'Enter the path to CompoLab `public` directory (leave empty to auto configure): ',
64
            sprintf('%s/public', $root)
65
        ))->setNormalizer(function ($value) {
66
            return trim((string) $value);
67
        })->setValidator(function ($value) {
68
            if (!is_dir($value)) {
69
                throw new \InvalidArgumentException('Invalid directory path');
70
            }
71
            return $value;
72
        }));
73
74
        $gitlabURL = $helper->ask($input, $output, (new Question(
75
            'Enter your GitLab server URL (eg. https://gitlab.my-website.com): '
76
        ))->setNormalizer(function ($value) {
77
            return trim((string) $value);
78
        })->setValidator(function ($value) {
79
            if (!filter_var($value, FILTER_VALIDATE_URL)) {
80
                throw new \InvalidArgumentException('Invalid URL');
81
            }
82
            return $value;
83
        }));
84
85
        $gitlabToken = $helper->ask($input, $output, (new Question(
86
            'Enter a valid Gitlab authentication token (url_token method): '
87
        ))->setNormalizer(function ($value) {
88
            return trim((string) $value);
89
        })->setHidden(true));
90
91
        $output->write('Create config/settings.yml... ');
92
        file_put_contents(sprintf('%s/config/settings.yml', $root), Yaml::dump([
93
            'parameters' => [
94
                'composer.url'  => $composerURL,
95
                'composer.dir'  => $composerPublicDirPath,
96
                'gitlab.url'    => $gitlabURL,
97
                'gitlab.token'  => $gitlabToken,
98
                'gitlab.method' => 'url_token',
99
            ]
100
        ]));
101
        $output->writeln('OK');
102
103
        if (!file_exists($packagesJson)) {
104
            $output->write('Create public/packages.json... ');
105
            file_put_contents($packagesJson, json_encode(['packages' => []]));
106
            $output->writeln('OK');
107
        }
108
109
        if (!is_writable($packagesJson) or !is_readable($packagesJson)) {
110
            $output->write('Make public/packages.yml writable... ');
111
            chmod($packagesJson, 0777);
112
            $output->writeln('OK');
113
        }
114
115
        if (!is_writable($packageArchives)) {
116
            $output->write('Make public/archives writable... ');
117
            chmod($packageArchives, 0777);
118
            $output->writeln('OK');
119
        }
120
121
        $output->writeln('Finished');
122
    }
123
124
    private function rmdir($dir, bool $rmCurrent = false) {
125
        foreach (array_diff(scandir($dir), ['.', '..', '.gitkeep']) as $file) {
0 ignored issues
show
Bug introduced by
It seems like scandir($dir) can also be of type false; however, parameter $array1 of array_diff() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

125
        foreach (array_diff(/** @scrutinizer ignore-type */ scandir($dir), ['.', '..', '.gitkeep']) as $file) {
Loading history...
126
            if (is_dir($path = "$dir/$file")) {
127
                $this->rmdir($path, true);
128
            } else {
129
                unlink($path);
130
            }
131
        }
132
133
        if ($rmCurrent) {
134
            rmdir($dir);
135
        }
136
    }
137
}
138