Completed
Pull Request — master (#87)
by
unknown
01:43
created

ChurnCommand::minScoreExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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