Passed
Push — master ( efe3fd...6bd5d7 )
by Peter
06:06
created

YamlCommand::printOutput()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.024

Importance

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