Completed
Push — master ( dce046...4c253f )
by Bill
11s
created

ChurnCommand::getPhpFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php declare(strict_types = 1);
2
3
namespace Churn\Commands;
4
5
use Churn\Collections\FileCollection;
6
use Churn\Results\ResultCollection;
7
use Illuminate\Support\Collection;
8
use Churn\Factories\ProcessFactory;
9
use Churn\Managers\FileManager;
10
use Churn\Results\ResultsParser;
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Helper\Table;
13
use Symfony\Component\Console\Input\InputArgument;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Churn\Configuration\Config;
18
use Symfony\Component\Yaml\Yaml;
19
20
class ChurnCommand extends Command
21
{
22
    /**
23
     * The config values.
24
     * @var Config
25
     */
26
    private $config;
27
28
    /**
29
     * The process factory.
30
     * @var ProcessFactory
31
     */
32
    private $processFactory;
33
34
    /**
35
     * Th results parser.
36
     * @var ResultsParser
37
     */
38
    private $resultsParser;
39
40
    /**
41
     * Collection of files to run the processes on.
42
     * @var FileCollection
43
     */
44
    private $filesCollection;
45
46
    /**
47
     * Collection of processes currently running.
48
     * @var Collection
49
     */
50
    private $runningProcesses;
51
52
    /**
53
     * Array of completed processes.
54
     * @var array
55
     */
56
    private $completedProcessesArray;
57
58
    /**
59
     * The start time.
60
     * @var float
61
     */
62
    private $startTime;
63
64
    /**
65
     * Keeps track of how many files were processed.
66
     * @var integer
67
     */
68
    private $filesCount;
69
70
    /**
71
     * ChurnCommand constructor.
72
     */
73
    public function __construct()
74
    {
75
        parent::__construct();
76
77
        $this->resultsParser = new ResultsParser();
78
    }
79
80
    /**
81
     * Configure the command
82
     * @return void
83
     */
84
    protected function configure()
85
    {
86
        $this->setName('run')
87
            ->addArgument('paths', InputArgument::IS_ARRAY, 'Path to source to check.')
88
            ->addOption('configuration', 'c', InputOption::VALUE_OPTIONAL, 'Path to the configuration file', 'churn.yml')  // @codingStandardsIgnoreLine
89
            ->setDescription('Check files')
90
            ->setHelp('Checks the churn on the provided path argument(s).');
91
    }
92
93
    /**
94
     * Execute the command
95
     * @param  InputInterface  $input  Input.
96
     * @param  OutputInterface $output Output.
97
     * @return void
98
     */
99
    protected function execute(InputInterface $input, OutputInterface $output)
100
    {
101
        $this->startTime = microtime(true);
102
        $this->setupProcessor($input->getOption('configuration'));
103
104
        $this->filesCollection = $this->getPhpFiles($input->getArgument('paths'));
105
        $this->filesCount = $this->filesCollection->count();
106
        $this->runningProcesses = new Collection;
107
        $this->completedProcessesArray = [];
108
        while ($this->filesCollection->hasFiles() || $this->runningProcesses->count()) {
109
            $this->getProcessResults();
110
        }
111
        $completedProcesses = new Collection($this->completedProcessesArray);
112
113
        $results = $this->resultsParser
114
            ->parse($completedProcesses)
115
            ->normalizeAgainst($this->config);
116
        $this->displayResults($output, $results);
117
    }
118
119
    /**
120
     * Gets the output from processes and stores them in the completedProcessArray member.
121
     * @return void
122
     */
123
    private function getProcessResults()
124
    {
125
        for ($index = $this->runningProcesses->count(); $this->filesCollection->hasFiles() > 0 && $index < $this->config->getParallelJobs(); $index++) {
126
            $file = $this->filesCollection->getNextFile();
127
128
            $process = $this->processFactory->createGitCommitProcess($file);
129
            $process->start();
130
            $this->runningProcesses->put($process->getKey(), $process);
131
132
            $process = $this->processFactory->createCyclomaticComplexityProcess($file);
133
            $process->start();
134
            $this->runningProcesses->put($process->getKey(), $process);
135
        }
136
137
        foreach ($this->runningProcesses as $file => $process) {
138
            if ($process->isSuccessful()) {
139
                $this->runningProcesses->forget($process->getKey());
140
                $this->completedProcessesArray[$process->getFileName()][$process->getType()] = $process;
141
            }
142
        }
143
    }
144
145
    /**
146
     * Displays the results in a table.
147
     * @param  OutputInterface  $output  Output.
148
     * @param  ResultCollection $results Results Collection.
149
     * @return void
150
     */
151
    protected function displayResults(OutputInterface $output, ResultCollection $results)
152
    {
153
        $totalTime = microtime(true) - $this->startTime;
154
        echo "\n
155
    ___  _   _  __  __  ____  _  _     ____  _   _  ____
156
   / __)( )_( )(  )(  )(  _ \( \( )___(  _ \( )_( )(  _ \
157
  ( (__  ) _ (  )(__)(  )   / )  ((___))___/ ) _ (  )___/
158
   \___)(_) (_)(______)(_)\_)(_)\_)   (__)  (_) (_)(__)      https://github.com/bmitch/churn-php\n\n";
159
160
        $table = new Table($output);
161
        $table->setHeaders(['File', 'Times Changed', 'Complexity', 'Score']);
162
        $table->addRows($results->toArray());
163
164
        $table->render();
165
166
        echo "  "
167
            . $this->filesCount
168
            . " files analysed in {$totalTime} seconds using "
169
            . $this->config->getParallelJobs()
170
            . " parallel jobs.\n\n";
171
    }
172
173
    /**
174
     * @param string $configFile Relative path churn.yml configuration file.
175
     * @return void
176
     */
177
    private function setupProcessor(string $configFile)
178
    {
179
        $this->config = Config::create(Yaml::parse(@file_get_contents($configFile)) ?? []);
180
        $this->processFactory = new ProcessFactory($this->config);
181
    }
182
183
    /**
184
     * @param array $directory Directories.
185
     * @return FileCollection
186
     */
187
    private function getPhpFiles(array $directory): FileCollection
188
    {
189
        $fileManager = new FileManager($this->config->getFileExtensions(), $this->config->getFilesToIgnore());
190
191
        return $fileManager->getPhpFiles($directory);
192
    }
193
}
194