Passed
Branch master (e09f8d)
by Peter
26:53
created

YamlCommand::execute()   B

Complexity

Conditions 9
Paths 15

Size

Total Lines 49
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 10.2655

Importance

Changes 4
Bugs 2 Features 1
Metric Value
cc 9
eloc 33
c 4
b 2
f 1
nc 15
nop 2
dl 0
loc 49
ccs 24
cts 32
cp 0.75
crap 10.2655
rs 8.0555
1
<?php
2
3
declare(strict_types=1);
4
5
namespace YamlStandards\Command;
6
7
use Symfony\Component\Console\Command\Command;
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 Symfony\Component\Yaml\Exception\ParseException;
13
use YamlStandards\Command\Service\ProcessOutputService;
14
use YamlStandards\Command\Service\ResultService;
15
use YamlStandards\Model\Config\YamlStandardConfigLoader;
16
use YamlStandards\Result\Result;
17
18
class YamlCommand extends Command
19
{
20
    private const COMMAND_NAME = 'yaml-standards';
21
22
    public const ARGUMENT_PATH_TO_CONFIG_FILE = 'pathToConfigFile';
23
    public const OPTION_FIX = 'fix';
24
25
    protected static $defaultName = self::COMMAND_NAME;
26
27 10
    protected function configure(): void
28
    {
29
        $this
30 10
            ->setName(self::COMMAND_NAME) // set command name for symfony/console lower version as 3.4
31 10
            ->setDescription('Check yaml files respect standards')
32 10
            ->addArgument(self::ARGUMENT_PATH_TO_CONFIG_FILE, InputArgument::OPTIONAL, 'Path to configuration file. By default configuration file is looking in root directory', './yaml-standards.yaml')
33 10
            ->addOption(self::OPTION_FIX, null, InputOption::VALUE_NONE, 'Automatically fix problems');
34 10
    }
35
36
    /**
37
     * @inheritDoc
38
     */
39 10
    protected function execute(InputInterface $input, OutputInterface $output): ?int
40
    {
41 10
        Reporting::startTiming();
42
43 10
        $inputSettingData = new InputSettingData($input);
44 10
        $yamlStandardConfigLoader = new YamlStandardConfigLoader();
45 10
        $yamlStandardConfigTotalData = $yamlStandardConfigLoader->loadFromYaml($inputSettingData->getPathToConfigFile());
46
47 9
        $processOutput = new ProcessOutput($yamlStandardConfigTotalData->getTotalCountOfYamlFiles());
48 9
        $results = [[]];
49
50 9
        foreach ($yamlStandardConfigTotalData->getYamlStandardConfigsSingleData() as $yamlStandardConfigSingleData) {
51 9
            foreach ($yamlStandardConfigSingleData->getPathToYamlFiles() as $pathToYamlFile) {
52 9
                $fileResults = [];
53 9
                if ($this->isFileExcluded($pathToYamlFile, $yamlStandardConfigSingleData->getPathToExcludedYamlFiles())) {
54 5
                    $output->write($processOutput->process(ProcessOutput::STATUS_CODE_SKIPP));
55 5
                    continue;
56
                }
57
58 8
                if (is_readable($pathToYamlFile) === false) {
59
                    $message = 'File is not readable.';
60
                    $fileResults[] = new Result($pathToYamlFile, Result::RESULT_CODE_GENERAL_ERROR, ProcessOutput::STATUS_CODE_ERROR, $message);
61
                    $output->write($processOutput->process(ProcessOutput::STATUS_CODE_ERROR));
62
                    continue;
63
                }
64
65
                try {
66 8
                    foreach ($yamlStandardConfigSingleData->getYamlStandardConfigsSingleStandardData() as $yamlStandardConfigSingleCheckerData) {
67 8
                        $standardParametersData = $yamlStandardConfigSingleCheckerData->getStandardParametersData();
68 8
                        $fixer = $yamlStandardConfigSingleCheckerData->getFixer();
69 8
                        if ($fixer !== null && $inputSettingData->isFixEnabled()) {
70
                            $fileResults[] = $fixer->runFix($pathToYamlFile, $pathToYamlFile, $standardParametersData);
71
                        } else {
72 8
                            $fileResults[] = $yamlStandardConfigSingleCheckerData->getChecker()->runCheck($pathToYamlFile, $standardParametersData);
73
                        }
74
                    }
75
                } catch (ParseException $e) {
76
                    $message = sprintf('Unable to parse the YAML string: %s', $e->getMessage());
77
                    $fileResults[] = new Result($pathToYamlFile, Result::RESULT_CODE_GENERAL_ERROR, ProcessOutput::STATUS_CODE_ERROR, $message);
78
                }
79
80 8
                $results[] = $fileResults;
81 9
                $output->write($processOutput->process(ProcessOutputService::getWorstStatusCodeByResults($fileResults)));
82
            }
83
        }
84 9
        $output->writeln($processOutput->getLegend());
85 9
        $results = array_merge(...$results); // add all results to one array instead of multidimensional array with results for every file
86
87 9
        return $this->printOutput($output, $results);
88
    }
89
90
    /**
91
     * @param \Symfony\Component\Console\Output\OutputInterface $output
92
     * @param \YamlStandards\Result\Result[] $results
93
     * @return int
94
     */
95 9
    private function printOutput(OutputInterface $output, array $results): int
96
    {
97 9
        foreach ($results as $result) {
98 8
            if ($result->getStatusCode() !== ProcessOutput::STATUS_CODE_OK) {
99
                $output->writeln(sprintf('FILE: %s', $result->getPathToFile()));
100
                $output->writeln('-------------------------------------------------');
101
                $output->writeln($result->getMessage() . PHP_EOL);
102
103
                if ($result->canBeFixedByFixer()) {
104 8
                    $output->writeln('<fg=red>This can be fixed by `--fix` option</fg=red>' . PHP_EOL);
105
                }
106
            }
107
        }
108
109 9
        $output->writeln(Reporting::printRunTime());
110
111 9
        return ResultService::getResultCodeByResults($results);
112
    }
113
114
    /**
115
     * @param string $pathToYamlFile
116
     * @param string[] $pathToExcludedYamlFiles
117
     * @return bool
118
     */
119 9
    private function isFileExcluded($pathToYamlFile, array $pathToExcludedYamlFiles): bool
120
    {
121 9
        if (in_array($pathToYamlFile, $pathToExcludedYamlFiles, true)) {
122 5
            return true;
123
        }
124
125 8
        return false;
126
    }
127
}
128