CompareCommand::execute()   B
last analyzed

Complexity

Conditions 5
Paths 16

Size

Total Lines 85

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 85
ccs 0
cts 64
cp 0
rs 8.0161
c 0
b 0
f 0
cc 5
nc 16
nop 2
crap 30

How to fix   Long Method   

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
namespace PHPSemVerCheckerGit\Console\Command;
4
5
use Gitter\Client;
6
use PHPSemVerChecker\Analyzer\Analyzer;
7
use PHPSemVerChecker\Finder\Finder;
8
use PHPSemVerChecker\Reporter\Reporter;
9
use PHPSemVerChecker\Scanner\Scanner;
10
use PHPSemVerCheckerGit\Filter\SourceFilter;
11
use PHPSemVerCheckerGit\Reporter\JsonReporter;
12
use Symfony\Component\Console\Helper\ProgressBar;
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
18
class CompareCommand extends BaseCommand {
19
	protected function configure()
20
	{
21
		$this
22
			->setName('compare')
23
			->setDescription('Compare a set of files to determine what semantic versioning change needs to be done')
24
			->setDefinition([
25
				new InputArgument('before', InputArgument::REQUIRED, 'A branch/tag/commit to check'),
26
				new InputArgument('after', InputArgument::REQUIRED, 'A branch/tag/commit to against'),
27
				new InputOption('include-before', null,  InputOption::VALUE_OPTIONAL, 'List of paths to include <info>(comma separated)</info>'),
28
				new InputOption('include-after', null, InputOption::VALUE_OPTIONAL, 'List of paths to include <info>(comma separated)</info>'),
29
				new InputOption('exclude-before', null,  InputOption::VALUE_REQUIRED, 'List of paths to exclude <info>(comma separated)</info>'),
30
				new InputOption('exclude-after', null, InputOption::VALUE_REQUIRED, 'List of paths to exclude <info>(comma separated)</info>'),
31
				new InputOption('config', null, InputOption::VALUE_REQUIRED, 'A configuration file to configure php-semver-checker-git'),
32
				new InputOption('to-json', null, InputOption::VALUE_REQUIRED, 'Output the result to a JSON file')
33
			]);
34
	}
35
36
	protected function execute(InputInterface $input, OutputInterface $output)
37
	{
38
		$startTime = microtime(true);
39
40
		$targetDirectory = getcwd();
41
		$commitBefore = $this->config->get('before');
42
		$commitAfter = $this->config->get('after');
43
44
		$includeBefore = $this->config->get('include-before');
45
		$excludeBefore = $this->config->get('exclude-before');
46
47
		$includeAfter = $this->config->get('include-after');
48
		$excludeAfter = $this->config->get('exclude-after');
49
50
		$finder = new Finder();
51
		$sourceFilter = new SourceFilter();
52
		$beforeScanner = new Scanner();
53
		$afterScanner = new Scanner();
54
55
		$client = new Client();
56
57
		$repository = $client->getRepository($targetDirectory);
58
59
		$modifiedFiles = $repository->getModifiedFiles($commitBefore, $commitAfter);
60
		$modifiedFiles = array_filter($modifiedFiles, function ($modifiedFile) {
61
			return substr($modifiedFile, -4) === '.php';
62
		});
63
64
		$initialBranch = $repository->getCurrentBranch();
65
66
		$repository->checkout($commitBefore . ' --');
67
68
		$sourceBefore = $finder->findFromString($targetDirectory, $includeBefore, $excludeBefore);
69
		$sourceBeforeMatchedCount = count($sourceBefore);
70
		$sourceBefore = $sourceFilter->filter($sourceBefore, $modifiedFiles);
71
		$progress = new ProgressBar($output, count($sourceBefore));
72
		foreach ($sourceBefore as $file) {
73
			$beforeScanner->scan($file);
74
			$progress->advance();
75
		}
76
77
		$progress->clear();
78
79
		$repository->checkout($commitAfter . ' --');
80
81
		$sourceAfter = $finder->findFromString($targetDirectory, $includeAfter, $excludeAfter);
82
		$sourceAfterMatchedCount = count($sourceAfter);
83
		$sourceAfter = $sourceFilter->filter($sourceAfter, $modifiedFiles);
84
		$progress = new ProgressBar($output, count($sourceAfter));
85
		foreach ($sourceAfter as $file) {
86
			$afterScanner->scan($file);
87
			$progress->advance();
88
		}
89
90
		$progress->clear();
91
92
		if ($initialBranch) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $initialBranch of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
93
			$repository->checkout($initialBranch);
94
		}
95
96
		$progress->clear();
97
98
		$registryBefore = $beforeScanner->getRegistry();
99
		$registryAfter = $afterScanner->getRegistry();
100
101
		$analyzer = new Analyzer();
102
		$report = $analyzer->analyze($registryBefore, $registryAfter);
103
104
		$reporter = new Reporter($report);
105
		$reporter->setFullPath(true);
106
		$reporter->output($output);
107
108
		$toJson = $this->config->get('to-json');
109
		if ($toJson) {
110
			$commitBeforeHash = $repository->getCommit($commitBefore)->getHash();
111
			$commitAfterHash = $repository->getCommit($commitAfter)->getHash();
112
			$jsonReporter = new JsonReporter($report, $toJson, $commitBeforeHash, $commitAfterHash);
113
			$jsonReporter->output();
114
		}
115
116
		$duration = microtime(true) - $startTime;
117
		$output->writeln('');
118
		$output->writeln('[Scanned files] Before: ' . count($sourceBefore) . ' ('.$sourceBeforeMatchedCount.' unfiltered), After: ' . count($sourceAfter) . ' ('.$sourceAfterMatchedCount.' unfiltered)');
119
		$output->writeln('Time: ' . round($duration, 3) . ' seconds, Memory: ' . round(memory_get_peak_usage() / 1024 / 1024, 3) . ' MB');
120
	}
121
}
122