PatternCommand::doExecute()   B
last analyzed

Complexity

Conditions 10
Paths 120

Size

Total Lines 56
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 10
eloc 27
c 2
b 0
f 0
nc 120
nop 2
dl 0
loc 56
rs 7.5

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 Startwind\Forrest\CliCommand\Search;
4
5
use Startwind\Forrest\CliCommand\Ai\AskCommand;
6
use Startwind\Forrest\Output\OutputHelper;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\ArrayInput;
9
use Symfony\Component\Console\Input\InputArgument;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
class PatternCommand extends SearchCommand
15
{
16
    private const PERFECT_SCORE = 20;
17
18
    public const COMMAND_NAME = 'search:pattern';
19
20
    protected static $defaultName = self::COMMAND_NAME;
21
    protected static $defaultDescription = 'Search for commands that fit the given pattern.';
22
23
    protected function configure(): void
24
    {
25
        parent::configure();
26
27
        $this->addArgument('pattern', InputArgument::IS_ARRAY, 'The pattern you want to search for.');
28
        $this->addOption('force', null, InputOption::VALUE_NONE, 'Run the command without asking for permission.');
29
        $this->addOption('score', 's', InputOption::VALUE_OPTIONAL, 'The minimal search score.', 10);
30
31
        $this->setAliases(['ask', 'pattern']);
32
    }
33
34
    protected function doExecute(InputInterface $input, OutputInterface $output): int
35
    {
36
        OutputHelper::renderHeader($output);
37
38
        $minScore = $input->getOption('score');
39
40
        $this->enrichRepositories();
41
42
        $pattern = $input->getArgument('pattern');
43
44
        if (count($pattern) == 1 && str_contains($pattern[0], ' ')) {
45
            $pattern = explode(' ', $pattern[0]);
46
        }
47
48
        $this->renderInfoBox('This is a list of commands that match the given pattern. Sorted by relevance.');
49
50
        $commands = $this->getRepositoryCollection()->searchByPattern($pattern);
51
52
        $filteredCommands = [];
53
        $perfectCommands = [];
54
55
        foreach ($commands as $key => $command) {
56
57
            // var_dump($command->getName() . ' - ' . $command->getScore());
58
59
            if ($command->getScore() > $minScore) {
60
                $filteredCommands[$key] = $command;
61
            }
62
63
            if ($command->getScore() > self::PERFECT_SCORE) {
64
                $perfectCommands[$key] = $command;
65
            }
66
        }
67
68
        if (count($filteredCommands) == 0) {
69
            $filteredCommands = $commands;
70
        }
71
72
        if (count($perfectCommands) > 0) {
73
            $filteredCommands = $perfectCommands;
74
        }
75
76
        if (empty($filteredCommands)) {
77
            $this->renderErrorBox('No commands found that match the given pattern.');
78
            return Command::FAILURE;
79
        }
80
81
        $result = $this->runFromCommands($filteredCommands, [], true);
82
83
        if ($result !== true) {
84
            return $result;
85
        }
86
87
        $this->renderInfoBox('We are asking the Forrest AI...');
88
89
        return $this->runAiAskCommand($pattern);
90
    }
91
92
    /**
93
     * The run command can also be applied to a file. This is a shortcut for the
94
     * search:file symfony console command.
95
     */
96
    private function runAiAskCommand(array $patterns): int
97
    {
98
        $arguments = [
99
            'question' => $patterns,
100
            '--silent' => true
101
        ];
102
103
        $fileArguments = new ArrayInput($arguments);
104
        $fileCommand = $this->getApplication()->find(AskCommand::COMMAND_NAME);
105
106
        return $fileCommand->run($fileArguments, $this->getOutput());
107
    }
108
109
}
110