Passed
Push — master ( 910b2e...b580f7 )
by Dorian
03:58
created

CommandLineInterface   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 186
rs 10
c 0
b 0
f 0
wmc 22

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A isInteractive() 0 3 1
A write() 0 3 1
A writeln() 0 3 1
A displayErrors() 0 14 2
A indent() 0 3 1
A logError() 0 4 1
A setInteractive() 0 3 1
A forceOutput() 0 8 1
A askQuestion() 0 14 3
A listing() 0 9 1
A askConfirmation() 0 14 3
A confirm() 0 10 3
A isDryRun() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace App\UI;
4
5
use Symfony\Component\Console\Command\Command;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Console\Question\ConfirmationQuestion;
9
use Symfony\Component\Console\Question\Question;
10
11
final class CommandLineInterface implements UserInterface
12
{
13
    /** @var bool */
14
    private $dryRun;
15
16
    /** @var \Symfony\Component\Console\Command\Command */
17
    private $command;
18
19
    /** @var \Symfony\Component\Console\Input\InputInterface */
20
    private $input;
21
22
    /** @var \Symfony\Component\Console\Output\OutputInterface */
23
    private $output;
24
25
    /**
26
     * @param bool $dryRun
27
     * @param \Symfony\Component\Console\Command\Command $command
28
     * @param \Symfony\Component\Console\Input\InputInterface $input
29
     * @param \Symfony\Component\Console\Output\OutputInterface $output
30
     */
31
    public function __construct(bool $dryRun, Command $command, InputInterface $input, OutputInterface $output)
32
    {
33
        $this->dryRun = $dryRun;
34
        $this->command = $command;
35
        $this->input = $input;
36
        $this->output = $output;
37
38
        if ($dryRun) {
39
            $input->setInteractive(false);
40
        }
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function isInteractive(): bool
47
    {
48
        return $this->input->isInteractive();
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function setInteractive(bool $interactive): void
55
    {
56
        $this->input->setInteractive($interactive);
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function isDryRun(): bool
63
    {
64
        return $this->dryRun;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function askQuestion(string $message, $default = null): string
71
    {
72
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */
73
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
74
        $questionHelper = $this->command->getHelper('question');
75
76
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
77
        $answer = $questionHelper->ask($this->input, $this->output, new Question($message, $default));
78
79
        if ($answer && $this->input->isInteractive()) {
80
            $this->writeln('');
81
        }
82
83
        return (string) $answer;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    private function askConfirmation(string $message, bool $default = true): bool
90
    {
91
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */
92
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
93
        $questionHelper = $this->command->getHelper('question');
94
95
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
96
        $answer = $questionHelper->ask($this->input, $this->output, new ConfirmationQuestion($message, $default));
97
98
        if ($answer && $this->input->isInteractive()) {
99
            $this->writeln('');
100
        }
101
102
        return $answer;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function write($messages, bool $newLine = false): void
109
    {
110
        $this->output->write($messages, $newLine);
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function writeln($messages, int $options = 0): void
117
    {
118
        $this->output->writeln($messages, $options);
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function listing(array $messages, int $indentation = 0): void
125
    {
126
        $messages = array_map(function ($message) use ($indentation) {
127
            return sprintf(str_repeat(' ', $indentation).' * %s', $message);
128
        }, $messages);
129
130
        $this->write(PHP_EOL);
131
        $this->writeln($messages);
132
        $this->write(PHP_EOL);
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function forceOutput(callable $callable): void
139
    {
140
        $verbosity = $this->output->getVerbosity();
141
        $this->output->setVerbosity(OutputInterface::VERBOSITY_NORMAL);
142
143
        $callable();
144
145
        $this->output->setVerbosity($verbosity);
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function indent(int $indentation = 1, int $characters = 2, string $character = ' '): string
152
    {
153
        return str_repeat(str_repeat($character, $characters), $indentation);
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159
    public function confirm(bool $confirmationDefault = true): bool
160
    {
161
        $confirmationQuestion = '<question>Continue?</question> ('.($confirmationDefault ? 'Y/n' : 'y/N').') ';
162
        if (!$this->askConfirmation($confirmationQuestion, $confirmationDefault)) {
163
            $this->writeln(PHP_EOL.$this->indent().'Not doing anything...');
164
165
            return false;
166
        }
167
168
        return true;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function logError(string $error, array &$errors): void
175
    {
176
        $this->writeln('<error>An error occurred.</error>');
177
        $errors[] = $error;
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183
    public function displayErrors(
184
        array $errors,
185
        string $process,
186
        string $type = 'error',
187
        int $indentation = 0
188
    ): void {
189
        $nbErrors = \count($errors);
190
        if ($nbErrors > 0) {
191
            $this->forceOutput(function () use ($nbErrors, $errors, $process, $type, $indentation) {
192
                $this->writeln(
193
                    PHP_EOL.PHP_EOL.'<'.$type.'>There were '.$nbErrors.' errors during the '.$process.' :</'.$type.'>'
194
                );
195
196
                $this->listing($errors, $indentation);
197
            });
198
        }
199
    }
200
}
201