Passed
Push — main ( b93b89...14e515 )
by Nils
02:53
created

AskCommand::formatCliText()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 10
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 22
rs 9.9332
1
<?php
2
3
namespace Startwind\Forrest\CliCommand\Ai;
4
5
use Startwind\Forrest\CliCommand\Command\CommandCommand;
6
use Startwind\Forrest\Util\OutputHelper;
7
use Symfony\Component\Console\Command\Command as SymfonyCommand;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Startwind\Forrest\Command\Answer\Answer;
13
use Symfony\Component\Console\Question\Question;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Question\Question was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
15
class AskCommand extends CommandCommand
16
{
17
    protected static $defaultName = 'ai:ask';
18
    protected static $defaultDescription = 'Suggest an answer to a question.';
19
20
    protected function configure(): void
21
    {
22
        $this->addArgument('question', InputArgument::IS_ARRAY, 'The question you want to have answered.', []);
23
        $this->setAliases(['ask']);
24
        $this->addOption('force', null, InputOption::VALUE_NONE, 'Run the command without asking for permission.');
25
26
        parent::configure();
27
    }
28
29
    protected function doExecute(InputInterface $input, OutputInterface $output): int
30
    {
31
        $this->enrichRepositories();
32
33
        \Startwind\Forrest\Output\OutputHelper::renderHeader($output);
34
35
        $aiQuestion = trim(implode(' ', $input->getArgument('question')));
36
37
        if ($aiQuestion == 'how') {
38
            OutputHelper::writeErrorBox($output, ["Please provide a question."]);
39
            return SymfonyCommand::FAILURE;
40
        }
41
42
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */
43
        $questionHelper = $this->getHelper('question');
44
45
        if (!$aiQuestion) {
46
            OutputHelper::writeInfoBox($output, ["Hi, I am Forrest, your AI command line helper. How can I help you?"]);
47
            $output->writeln('');
48
            $aiQuestion = $questionHelper->ask($input, $output, new Question('  Your question: '));
49
            $output->writeln(['', '']);
50
        } else {
51
            OutputHelper::writeInfoBox($output, [
52
                ucfirst($aiQuestion)
53
            ]);
54
        }
55
56
        $answers = $this->getRepositoryCollection()->ask($aiQuestion);
57
58
        foreach ($answers as $repositoryName => $repoAnswers) {
59
            foreach ($repoAnswers as $answer) {
60
                /** @var Answer $answer */
61
                $output->writeln(OutputHelper::indentText($this->formatCliText($answer->getAnswer())));
62
                $command = $answer->getCommand();
63
64
                if ($command->getPrompt()) {
65
                    return $this->runCommand($answer->getCommand(), []);
66
                }
67
            }
68
        }
69
70
        return SymfonyCommand::SUCCESS;
71
    }
72
73
    private function formatCliText(string $text): string
74
    {
75
        preg_match_all('#```shell((.|\n)*?)```#', $text, $matches);
76
77
        if (count($matches[1]) == 1) {
78
            $shell = $matches[1][0];
79
80
            $shellNew = implode("\n", OutputHelper::indentText(trim($shell), 2, 100, ' | '));
81
82
            $text = str_replace($matches[0][0], $shellNew, $text);
83
        }
84
85
        preg_match_all('#`(.*)`#', $text, $matches);
86
87
        if (count($matches[1]) > 0) {
88
89
            foreach ($matches[0] as $key => $match) {
90
                $text = str_replace($match, '<options=bold>' . $matches[1][$key] . '</>', $text);
91
            }
92
        }
93
94
        return $text;
95
    }
96
}
97