Passed
Pull Request — master (#117)
by Dave
03:20 queued 01:10
created

RemoveBaseLineFromResultsCommand   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 80
dl 0
loc 148
rs 10
c 2
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B execute() 0 72 5
A getOutputFormatter() 0 8 2
A configure() 0 23 1
1
<?php
2
3
/**
4
 * Static Analysis Results Baseliner (sarb).
5
 *
6
 * (c) Dave Liddament
7
 *
8
 * For the full copyright and licence information please view the LICENSE file distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command;
14
15
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\OutputFormatter\InvalidOutputFormatterException;
16
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\OutputFormatter\OutputFormatter;
17
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\OutputFormatter\OutputFormatterLookupService;
18
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\Pruner\ResultsPrunerInterface;
19
use DaveLiddament\StaticAnalysisResultsBaseliner\Domain\ResultsParser\AnalysisResultsBuilder;
20
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\internal\BaseLineFileHelper;
21
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\internal\CliConfigReader;
22
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\internal\ErrorReporter;
23
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\internal\InvalidConfigException;
24
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\internal\OutputWriter;
25
use DaveLiddament\StaticAnalysisResultsBaseliner\Framework\Command\internal\ProjectRootHelper;
26
use DaveLiddament\StaticAnalysisResultsBaseliner\Plugins\OutputFormatters\TableOutputFormatter;
27
use Symfony\Component\Console\Command\Command;
28
use Symfony\Component\Console\Input\InputInterface;
29
use Symfony\Component\Console\Input\InputOption;
30
use Symfony\Component\Console\Output\OutputInterface;
31
use Throwable;
32
33
class RemoveBaseLineFromResultsCommand extends Command
34
{
35
    public const COMMAND_NAME = 'remove-baseline-results';
36
37
    private const OUTPUT_FORMAT = 'output-format';
38
    private const SHOW_RANDOM_ERRORS = 'clean-up';
39
    const RANDOM_ISSUES_TO_FIX = 5;
40
41
    /**
42
     * @var string|null
43
     */
44
    protected static $defaultName = self::COMMAND_NAME;
45
46
    /**
47
     * @var OutputFormatterLookupService
48
     */
49
    private $outputFormatterLookupService;
50
    /**
51
     * @var ResultsPrunerInterface
52
     */
53
    private $resultsPruner;
54
    /**
55
     * @var TableOutputFormatter
56
     */
57
    private $tableOutputFormatter;
58
59
    public function __construct(
60
        ResultsPrunerInterface $resultsPruner,
61
        OutputFormatterLookupService $outputFormatterLookupService,
62
        TableOutputFormatter $tableOutputFormatter
63
    ) {
64
        parent::__construct(self::COMMAND_NAME);
65
        $this->resultsPruner = $resultsPruner;
66
        $this->tableOutputFormatter = $tableOutputFormatter;
67
        $this->outputFormatterLookupService = $outputFormatterLookupService;
68
    }
69
70
    protected function configure(): void
71
    {
72
        $this->setDescription('Shows issues created since the baseline');
73
74
        $outputFormatters = $this->outputFormatterLookupService->getIdentifiers();
75
        $this->addOption(
76
            self::OUTPUT_FORMAT,
77
            null,
78
            InputOption::VALUE_REQUIRED,
79
            'Output format. One of: '.implode('|', $outputFormatters),
80
            TableOutputFormatter::CODE
81
        );
82
83
        $this->addOption(
84
            self::SHOW_RANDOM_ERRORS,
85
            null,
86
            InputOption::VALUE_NONE,
87
            'Show a random 5 issues in the baseline to fix'
88
        );
89
90
        ProjectRootHelper::configureProjectRootOption($this);
91
92
        BaseLineFileHelper::configureBaseLineFileArgument($this);
93
    }
94
95
    protected function execute(InputInterface $input, OutputInterface $output): int
96
    {
97
        try {
98
            $projectRoot = ProjectRootHelper::getProjectRoot($input);
99
            $outputFormatter = $this->getOutputFormatter($input);
100
            $baseLineFileName = BaseLineFileHelper::getBaselineFile($input);
101
            $inputAnalysisResultsAsString = CliConfigReader::getStdin($input);
102
            $showRandomIssues = CliConfigReader::getBooleanOption($input, self::SHOW_RANDOM_ERRORS);
103
104
            $prunedResults = $this->resultsPruner->getPrunedResults(
105
                $baseLineFileName,
106
                $inputAnalysisResultsAsString,
107
                $projectRoot
108
            );
109
110
            $outputAnalysisResults = $prunedResults->getPrunedResults();
111
112
            OutputWriter::writeToStdError(
113
                $output,
114
                "Latest analysis issue count: {$prunedResults->getInputAnalysisResults()->getCount()}",
115
                false
116
            );
117
118
            OutputWriter::writeToStdError(
119
                $output,
120
                "Baseline issue count: {$prunedResults->getBaseLine()->getAnalysisResults()->getCount()}",
121
                false
122
            );
123
124
            OutputWriter::writeToStdError(
125
                $output,
126
                "Issue count with baseline removed: {$outputAnalysisResults->getCount()}",
127
                !$outputAnalysisResults->hasNoIssues()
128
            );
129
130
            $outputAsString = $outputFormatter->outputResults($outputAnalysisResults);
131
            $output->writeln($outputAsString);
132
133
            $returnCode = $outputAnalysisResults->hasNoIssues() ? 0 : 1;
134
135
            if ($showRandomIssues) {
136
                $issuesToReport = min(self::RANDOM_ISSUES_TO_FIX, $prunedResults->getInputAnalysisResults()->getCount());
137
138
                OutputWriter::writeToStdError(
139
                    $output,
140
                    "Random {$issuesToReport} issues in the baseline to fix...",
141
                    false
142
                );
143
144
                $randomIssuesBuilder = new AnalysisResultsBuilder();
145
                $allIssues = $prunedResults->getInputAnalysisResults()->getAnalysisResults();
146
147
                for ($i = 0; $i < $issuesToReport; ++$i) {
148
                    $totalRemaining = count($allIssues);
149
                    $issuePicked = rand(0, $totalRemaining - 1);
150
                    $randomIssuesBuilder->addAnalysisResult($allIssues[$issuePicked]);
151
                }
152
153
                $outputAsString = $this->tableOutputFormatter->outputResults($randomIssuesBuilder->build());
154
155
                OutputWriter::writeToStdError(
156
                    $output,
157
                    $outputAsString,
158
                    false
159
                );
160
            }
161
162
            return $returnCode;
163
        } catch (Throwable $throwable) {
164
            $returnCode = ErrorReporter::reportError($output, $throwable);
165
166
            return $returnCode;
167
        }
168
    }
169
170
    /**
171
     * @throws InvalidConfigException
172
     */
173
    private function getOutputFormatter(InputInterface $input): OutputFormatter
174
    {
175
        $identifier = CliConfigReader::getOptionWithDefaultValue($input, self::OUTPUT_FORMAT);
176
177
        try {
178
            return $this->outputFormatterLookupService->getOutputFormatter($identifier);
179
        } catch (InvalidOutputFormatterException $e) {
180
            throw InvalidConfigException::invalidOptionValue(self::OUTPUT_FORMAT, $identifier, $this->outputFormatterLookupService->getIdentifiers());
181
        }
182
    }
183
}
184