Completed
Push — master ( 98be7b...7a3330 )
by Dorian
01:30
created

CommandLineInterface   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 4
dl 0
loc 159
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A isInteractive() 0 4 1
A isDryRun() 0 4 1
A askConfirmation() 0 15 3
A write() 0 4 1
A writeln() 0 4 1
A listing() 0 10 1
A forceOutput() 0 9 1
A indent() 0 4 1
A confirm() 0 11 3
A logError() 0 5 1
A displayErrors() 0 17 2
1
<?php declare(strict_types=1);
2
3
namespace App\Cli;
4
5
use App\UI\UserInterface;
6
use Symfony\Component\Console\Command\Command;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\Console\Question\ConfirmationQuestion;
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
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function isInteractive(): bool
43
    {
44
        return $this->input->isInteractive();
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function isDryRun(): bool
51
    {
52
        return $this->dryRun;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function askConfirmation(string $message, bool $default = true): bool
59
    {
60
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */
61
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
62
        $questionHelper = $this->command->getHelper('question');
63
64
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
65
        $answer = $questionHelper->ask($this->input, $this->output, new ConfirmationQuestion($message, $default));
66
67
        if ($answer && $this->input->isInteractive()) {
68
            $this->writeln('');
69
        }
70
71
        return $answer;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function write($messages, bool $newLine = false): void
78
    {
79
        $this->output->write($messages, $newLine);
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    public function writeln($messages, int $options = 0): void
86
    {
87
        $this->output->writeln($messages, $options);
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function listing(array $messages, int $indentation = 0): void
94
    {
95
        $messages = array_map(function ($message) use ($indentation) {
96
            return sprintf(str_repeat(' ', $indentation).' * %s', $message);
97
        }, $messages);
98
99
        $this->write(PHP_EOL);
100
        $this->writeln($messages);
101
        $this->write(PHP_EOL);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function forceOutput(callable $callable): void
108
    {
109
        $verbosity = $this->output->getVerbosity();
110
        $this->output->setVerbosity(OutputInterface::VERBOSITY_NORMAL);
111
112
        $callable();
113
114
        $this->output->setVerbosity($verbosity);
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function indent(int $indentation = 1, int $characters = 2, string $character = ' '): string
121
    {
122
        return str_repeat(str_repeat($character, $characters), $indentation);
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function confirm(bool $confirmationDefault = true): bool
129
    {
130
        $confirmationQuestion = '<question>Continue?</question> ('.($confirmationDefault ? 'Y/n' : 'y/N').') ';
131
        if (!$this->askConfirmation($confirmationQuestion, $confirmationDefault)) {
132
            $this->writeln(PHP_EOL.$this->indent().'Not doing anything...');
133
134
            return false;
135
        }
136
137
        return true;
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143
    public function logError(string $error, array &$errors): void
144
    {
145
        $this->writeln('<error>An error occurred.</error>');
146
        $errors[] = $error;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function displayErrors(
153
        array $errors,
154
        string $process,
155
        string $type = 'error',
156
        int $indentation = 0
157
    ): void {
158
        $nbErrors = \count($errors);
159
        if ($nbErrors > 0) {
160
            $this->forceOutput(function () use ($nbErrors, $errors, $process, $type, $indentation) {
161
                $this->writeln(
162
                    PHP_EOL.PHP_EOL.'<'.$type.'>There were '.$nbErrors.' errors during the '.$process.' :</'.$type.'>'
163
                );
164
165
                $this->listing($errors, $indentation);
166
            });
167
        }
168
    }
169
}
170