Passed
Push — main ( 96d323...c12136 )
by Nils
15:53
created

OutputHelper   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
eloc 68
c 6
b 1
f 0
dl 0
loc 138
rs 10
wmc 22

4 Methods

Rating   Name   Duplication   Size   Complexity  
A renderHeader() 0 7 1
A renderTable() 0 6 1
B askForCommand() 0 33 8
D renderCommands() 0 77 12
1
<?php
2
3
namespace Startwind\Forrest\Output;
4
5
use Startwind\Forrest\Command\Command;
6
use Startwind\Forrest\Repository\RepositoryCollection;
7
use Symfony\Component\Console\Helper\QuestionHelper;
8
use Symfony\Component\Console\Helper\Table;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Question\ConfirmationQuestion;
12
use Symfony\Component\Console\Question\Question;
13
14
class OutputHelper
15
{
16
    public static function renderTable(OutputInterface $output, array $headers, array $rows): void
17
    {
18
        $table = new Table($output);
19
        $table->setHeaders($headers);
20
        $table->setRows($rows);
21
        $table->render();
22
    }
23
24
    public static function renderHeader(OutputInterface $output): void
25
    {
26
        $output->writeln([
27
            '',
28
            '<options=bold>Forrest</> - Unifying the Command Line <fg=green>' . FORREST_VERSION . '</>',
29
            // '         by Nils Langner and contributors.',
30
            '',
31
        ]);
32
    }
33
34
    /**
35
     * @param Command[] $commands
36
     */
37
    public static function renderCommands(
38
        OutputInterface $output,
39
        InputInterface  $input,
40
        QuestionHelper  $questionHelper,
41
        array           $commands,
42
        ?string         $repoIdentifier = null,
43
        int             $maxLength = -1,
44
        bool            $askForCommand = false,
45
        bool            $addAiOption = false
46
    ): bool|Command
47
    {
48
        $identifierMaxLength = $maxLength;
49
50
        foreach ($commands as $commandId => $command) {
51
            if ($repoIdentifier) {
52
                $commandIdentifier = RepositoryCollection::createUniqueCommandName($repoIdentifier, $command);
53
            } else {
54
                $commandIdentifier = $commandId;
55
            }
56
            $command->setFullyQualifiedIdentifier($commandIdentifier);
57
            if ($maxLength == -1) {
58
                $identifierMaxLength = max($identifierMaxLength, strlen($commandIdentifier));
59
            }
60
        }
61
62
        uasort($commands, function (Command $a, Command $b) {
63
            if ($a->getScore() > -1) {
64
                return $b->getScore() <=> $a->getScore();
65
            }
66
            return $a->getFullyQualifiedIdentifier() <=> $b->getFullyQualifiedIdentifier();
67
        });
68
69
        $number = 1;
70
        $numberPrefix = '';
71
72
        foreach ($commands as $commandId => $command) {
73
            if ($repoIdentifier) {
74
                $commandIdentifier = RepositoryCollection::createUniqueCommandName($repoIdentifier, $command);
75
            } else {
76
                $commandIdentifier = $commandId;
77
            }
78
79
            $spaces = str_repeat(' ', $identifierMaxLength - strlen($commandIdentifier) + 2);
80
81
            if ($askForCommand) {
82
                $numberPrefix = '  ' . $number;
83
                $number++;
84
            }
85
86
            $placeholder = '';
87
88
            if ($number < 100) {
89
                $placeholder = ' ';
90
            }
91
92
            if ($number < 11) {
93
                $placeholder = '  ';
94
            }
95
96
            $output->writeln($numberPrefix . '  <fg=green>' . $commandIdentifier . '</>' . $placeholder . $spaces . $command->getDescription());
97
        }
98
99
        if ($addAiOption) {
100
            $commandName = 'forrest:ai';
101
            $spaces = str_repeat(' ', $identifierMaxLength - strlen($commandName) + 4);
102
            //$output->writeln('');
103
            $dashes = str_repeat('-', $identifierMaxLength);
104
            $output->writeln('     ' . $dashes);
105
            // $output->writeln('');
106
            $output->writeln('  0  <fg=green>' . $commandName . '</>' . $spaces . "No matching command found. Please ask the Forrest AI.");
107
        }
108
109
        if ($askForCommand) {
110
            return self::askForCommand($output, $input, $questionHelper, $commands, $addAiOption);
111
        }
112
113
        return false;
114
    }
115
116
    /**
117
     * @param Command[] $commands
118
     */
119
    private static function askForCommand(OutputInterface $output, InputInterface $input, QuestionHelper $questionHelper, array $commands, bool $allowZero = false): bool|Command
120
    {
121
        $output->writeln('');
122
123
        if (count($commands) == 1 && !$allowZero) {
124
            $commandIdentifier = array_key_first($commands);
125
            $command = array_pop($commands);
126
            if (!$questionHelper->ask($input, $output, new ConfirmationQuestion('  Do you want to run "' . $commandIdentifier . '" (y/n)? ', false))) {
127
                return false;
128
            }
129
        } else {
130
            $commandNumber = -1;
131
            if ($allowZero) {
132
                $minCommandNumber = 0;
133
            } else {
134
                $minCommandNumber = 1;
135
            }
136
137
            while ($commandNumber < $minCommandNumber || $commandNumber > count($commands)) {
138
                $commandNumber = (int)$questionHelper->ask($input, $output, new Question('  Which command do you want to run [' . $minCommandNumber . '-' . count($commands) . ']? '));
139
            }
140
141
            if ($commandNumber === 0) {
142
                return true;
143
            }
144
145
            $commandIdentifier = array_keys($commands)[$commandNumber - 1];
146
            $command = $commands[$commandIdentifier];
147
        }
148
149
        $command->setFullyQualifiedIdentifier($commandIdentifier);
150
151
        return $command;
152
    }
153
}
154