Passed
Pull Request — master (#74)
by Peter
07:08
created

YamlCommand::execute()   B

Complexity

Conditions 11
Paths 64

Size

Total Lines 68
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 11.4266

Importance

Changes 4
Bugs 2 Features 1
Metric Value
eloc 47
c 4
b 2
f 1
dl 0
loc 68
ccs 39
cts 46
cp 0.8478
rs 7.3166
cc 11
nc 64
nop 2
crap 11.4266

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
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\Console\Style\SymfonyStyle;
13
use Symfony\Component\Yaml\Exception\ParseException;
14
use YamlStandards\Command\Service\ResultService;
15
use YamlStandards\Model\Component\Cache\NativeCache;
16
use YamlStandards\Model\Component\Cache\NoCache;
17
use YamlStandards\Model\Config\YamlStandardConfigLoader;
18
use YamlStandards\Result\Result;
19
20
class YamlCommand extends Command
21
{
22
    private const COMMAND_NAME = 'yaml-standards';
23
24
    public const ARGUMENT_PATH_TO_CONFIG_FILE = 'pathToConfigFile';
25
    public const OPTION_FIX = 'fix';
26
    public const OPTION_PATH_TO_CACHE_DIR = 'path-to-cache-dir';
27
    public const OPTION_DISABLE_CACHE = 'no-cache';
28
29
    protected static $defaultName = self::COMMAND_NAME;
30
31 10
    protected function configure(): void
32
    {
33 10
        $this
34 10
            ->setName(self::COMMAND_NAME) // set command name for symfony/console lower version as 3.4
35 10
            ->setDescription('Check yaml files respect standards')
36 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')
37 10
            ->addOption(self::OPTION_FIX, null, InputOption::VALUE_NONE, 'Automatically fix problems')
38 10
            ->addOption(self::OPTION_PATH_TO_CACHE_DIR, null, InputOption::VALUE_REQUIRED, 'Custom path to cache dir', '/')
39 10
            ->addOption(self::OPTION_DISABLE_CACHE, null, InputOption::VALUE_NONE, 'Disable cache functionality');
40
    }
41
42
    /**
43
     * @inheritDoc
44
     */
45 10
    protected function execute(InputInterface $input, OutputInterface $output): int
46
    {
47 10
        $inputSettingData = new InputSettingData($input);
48 10
        $yamlStandardConfigLoader = new YamlStandardConfigLoader();
49 10
        $pathToConfigFile = $inputSettingData->getPathToConfigFile();
50 10
        $pathToCacheDir = $inputSettingData->getPathToCacheDir();
51 10
        $yamlStandardConfigTotalData = $yamlStandardConfigLoader->loadFromYaml($pathToConfigFile);
52 9
        $cache = $inputSettingData->isCacheDisabled() ? new NoCache() : new NativeCache();
53 9
        $cache->deleteCacheFileIfConfigFileWasChanged($pathToConfigFile, $pathToCacheDir);
54
55 9
        $symfonyStyle = new SymfonyStyle($input, $output);
56 9
        $progressBar = $symfonyStyle->createProgressBar($yamlStandardConfigTotalData->getTotalCountOfFiles());
57 9
        $progressBar->setFormat('debug');
58 9
        $results = [[]];
59
60 9
        foreach ($yamlStandardConfigTotalData->getYamlStandardConfigsSingleData() as $configNumber => $yamlStandardConfigSingleData) {
61
            // config number 0 is reserved for config file
62 9
            ++$configNumber;
63
64 9
            $filesToCache = [];
65 9
            $cachedPathToFiles = $cache->getCachedPathToFiles($yamlStandardConfigSingleData->getPathToFiles(), $configNumber, $pathToCacheDir);
66 9
            foreach ($cachedPathToFiles as $pathToFile) {
67 9
                $fileResults = [];
68 9
                if ($this->isFileExcluded($pathToFile, $yamlStandardConfigSingleData->getPathToExcludedFiles())) {
69 5
                    $filesToCache[] = $pathToFile;
70 5
                    $progressBar->advance();
71 5
                    continue;
72
                }
73
74 8
                if (is_readable($pathToFile) === false) {
75
                    $message = 'File is not readable.';
76
                    $fileResults[] = new Result($pathToFile, Result::RESULT_CODE_GENERAL_ERROR, $message);
77
                    $progressBar->advance();
78
                    continue;
79
                }
80
81
                try {
82 8
                    foreach ($yamlStandardConfigSingleData->getYamlStandardConfigsSingleStandardData() as $yamlStandardConfigSingleCheckerData) {
83 8
                        $standardParametersData = $yamlStandardConfigSingleCheckerData->getStandardParametersData();
84 8
                        $checker = $yamlStandardConfigSingleCheckerData->getChecker();
85 8
                        $fixer = $yamlStandardConfigSingleCheckerData->getFixer();
86
87 8
                        if ($fixer !== null && $inputSettingData->isFixEnabled()) {
88 1
                            $result = $fixer->runFix($pathToFile, $pathToFile, $standardParametersData);
89
                        } else {
90 8
                            $result = $checker->runCheck($pathToFile, $standardParametersData);
91
                        }
92 8
                        $fileResults[] = $result;
93
                    }
94
                } catch (ParseException $e) {
95
                    $message = sprintf('Unable to parse the YAML string: %s', $e->getMessage());
96
                    $fileResults[] = new Result($pathToFile, Result::RESULT_CODE_GENERAL_ERROR, $message);
97
                }
98
99 8
                if (ResultService::getResultCodeByResults($fileResults) === Result::RESULT_CODE_OK_AS_INTEGER) {
100 8
                    $filesToCache[] = $pathToFile;
101
                }
102 8
                $results[] = $fileResults;
103 8
                $progressBar->advance();
104
            }
105
106 9
            $cache->cacheFiles($filesToCache, $configNumber, $pathToCacheDir);
107
        }
108 9
        $progressBar->finish();
109
        /** @var \YamlStandards\Result\Result[] $mergedResult */
110 9
        $mergedResult = array_merge(...$results); // add all results to one array instead of multidimensional array with results for every file
111
112 9
        return $this->printOutput($output, $mergedResult);
113
    }
114
115
    /**
116
     * @param \Symfony\Component\Console\Output\OutputInterface $output
117
     * @param \YamlStandards\Result\Result[] $results
118
     * @return int
119
     */
120 9
    private function printOutput(OutputInterface $output, array $results): int
121
    {
122 9
        $output->writeln(PHP_EOL);
123 9
        foreach ($results as $result) {
124 8
            if ($result->getResultCode() !== Result::RESULT_CODE_OK) {
125
                $output->writeln(sprintf('FILE: %s', $result->getPathToFile()));
126
                $output->writeln('-------------------------------------------------');
127
                $output->writeln($result->getMessage() . PHP_EOL);
128
129
                if ($result->canBeFixedByFixer()) {
130
                    $output->writeln('<fg=red>This can be fixed by `--fix` option</fg=red>' . PHP_EOL);
131
                }
132
            }
133
        }
134
135 9
        return ResultService::getResultCodeByResults($results);
136
    }
137
138
    /**
139
     * @param string $pathToFile
140
     * @param string[] $pathToExcludedFiles
141
     * @return bool
142
     */
143 9
    private function isFileExcluded(string $pathToFile, array $pathToExcludedFiles): bool
144
    {
145 9
        if (in_array($pathToFile, $pathToExcludedFiles, true)) {
146 5
            return true;
147
        }
148
149 8
        return false;
150
    }
151
}
152