1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PhpGitHooks\Command; |
4
|
|
|
|
5
|
|
|
use PhpGitHooks\Application\CodeSniffer\CheckCodeStyleCodeSnifferPreCommitExecutor; |
6
|
|
|
use PhpGitHooks\Application\Config\HookConfigInterface; |
7
|
|
|
use PhpGitHooks\Application\Message\MessageConfigData; |
8
|
|
|
use PhpGitHooks\Application\PhpCsFixer\FixCodeStyleCsFixerPreCommitExecutor; |
9
|
|
|
use PhpGitHooks\Application\PhpMD\CheckPhpMessDetectionPreCommitExecutor; |
10
|
|
|
use PhpGitHooks\Application\PhpUnit\UnitTestPreCommitExecutor; |
11
|
|
|
use PhpGitHooks\Container; |
12
|
|
|
use PhpGitHooks\Infrastructure\Git\ExtractCommitedFiles; |
13
|
|
|
use Symfony\Component\Console\Application; |
14
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
15
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class QualityCodeTool. |
19
|
|
|
*/ |
20
|
|
|
class QualityCodeTool extends Application |
21
|
|
|
{ |
22
|
|
|
/** @var OutputInterface */ |
23
|
|
|
private $output; |
24
|
|
|
/** @var array */ |
25
|
|
|
private $files; |
26
|
|
|
/** @var Container */ |
27
|
|
|
private $container; |
28
|
|
|
/** @var OutputHandler */ |
29
|
|
|
private $outputTitleHandler; |
30
|
|
|
/** @var HookConfigInterface */ |
31
|
|
|
private $configData; |
32
|
|
|
|
33
|
|
|
const PHP_FILES = '/^(.*)(\.php)$/'; |
34
|
|
|
const JSON_FILES = '/^(.*)(\.json)$/'; |
35
|
|
|
const COMPOSER_FILES = '/^composer\.(json|lock)$/'; |
36
|
|
|
|
37
|
|
|
public function __construct() |
38
|
|
|
{ |
39
|
|
|
$this->container = new Container(); |
40
|
|
|
$this->outputTitleHandler = new OutputHandler(); |
41
|
|
|
$this->configData = $this->container->get('pre.commit.config'); |
42
|
|
|
|
43
|
|
|
parent::__construct('Code Quality Tool'); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @param InputInterface $input |
48
|
|
|
* @param OutputInterface $output |
49
|
|
|
*/ |
50
|
|
|
public function doRun(InputInterface $input, OutputInterface $output) |
51
|
|
|
{ |
52
|
|
|
$this->output = $output; |
53
|
|
|
|
54
|
|
|
$this->output->writeln('<fg=white;options=bold;bg=red>Pre-commit tool</fg=white;options=bold;bg=red>'); |
55
|
|
|
$this->extractCommitFiles(); |
56
|
|
|
|
57
|
|
|
$this->execute(); |
58
|
|
|
|
59
|
|
|
if (true === $this->existsFiles()) { |
60
|
|
|
$this->output->writeln(GoodJobLogo::paint($this->getRightMessage())); |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
private function extractCommitFiles() |
65
|
|
|
{ |
66
|
|
|
$this->outputTitleHandler->setTitle('Fetching files'); |
67
|
|
|
$this->output->write($this->outputTitleHandler->getTitle()); |
68
|
|
|
|
69
|
|
|
$commitFiles = new ExtractCommitedFiles(); |
70
|
|
|
|
71
|
|
|
$this->files = $commitFiles->getFiles(); |
72
|
|
|
|
73
|
|
|
$result = true === $this->existsFiles() ? '0k' : 'No files changed'; |
74
|
|
|
$this->output->writeln($this->outputTitleHandler->getSuccessfulStepMessage($result)); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @return array |
79
|
|
|
*/ |
80
|
|
|
private function processingFiles() |
81
|
|
|
{ |
82
|
|
|
$files = [ |
83
|
|
|
'php' => false, |
84
|
|
|
'composer' => false, |
85
|
|
|
'json' => false, |
86
|
|
|
]; |
87
|
|
|
|
88
|
|
|
foreach ($this->files as $file) { |
89
|
|
View Code Duplication |
if (true === (bool) preg_match(self::PHP_FILES, $file)) { |
|
|
|
|
90
|
|
|
$files['php'] = true; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
View Code Duplication |
if (true === (bool) preg_match(self::COMPOSER_FILES, $file)) { |
|
|
|
|
94
|
|
|
$files['composer'] = true; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
View Code Duplication |
if (true === (bool) preg_match(self::JSON_FILES, $file)) { |
|
|
|
|
98
|
|
|
$files['json'] = true; |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
return $files; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
private function execute() |
106
|
|
|
{ |
107
|
|
|
if (true === $this->isProcessingAnyComposerFile()) { |
108
|
|
|
$this->container->get('check.composer.files.pre.commit.executor') |
109
|
|
|
->run($this->output, $this->files); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
if (true === $this->isProcessingAnyJsonFile()) { |
113
|
|
|
$this->container->get('check.json.syntax.pre.commit.executor') |
114
|
|
|
->run($this->output, $this->files, self::JSON_FILES); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
if (true === $this->isProcessingAnyPhpFile()) { |
118
|
|
|
$this->container->get('check.php.syntax.lint.pre.commit.executor') |
119
|
|
|
->run($this->output, $this->files); |
120
|
|
|
|
121
|
|
|
/** @var FixCodeStyleCsFixerPreCommitExecutor $csFixer */ |
122
|
|
|
$csFixer = $this->container->get('fix.code.style.cs.fixer.pre.commit.executor'); |
123
|
|
|
$csFixer->run($this->output, $this->files, self::PHP_FILES); |
124
|
|
|
|
125
|
|
|
/** @var CheckCodeStyleCodeSnifferPreCommitExecutor $codeSniffer */ |
126
|
|
|
$codeSniffer = $this->container->get('check.code.style.code.sniffer.pre.commit.executor'); |
127
|
|
|
$codeSniffer->run($this->output, $this->files, self::PHP_FILES); |
128
|
|
|
|
129
|
|
|
/** @var CheckPhpMessDetectionPreCommitExecutor $messDetector */ |
130
|
|
|
$messDetector = $this->container->get('check.php.mess.detection.pre.commit.executor'); |
131
|
|
|
$messDetector->run($this->output, $this->files, self::PHP_FILES); |
132
|
|
|
|
133
|
|
|
/** @var UnitTestPreCommitExecutor $phpUnit */ |
134
|
|
|
$phpUnit = $this->container->get('unit.test.pre.commit.executor'); |
135
|
|
|
$phpUnit->run($this->output); |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @return bool |
141
|
|
|
*/ |
142
|
|
|
private function isProcessingAnyComposerFile() |
143
|
|
|
{ |
144
|
|
|
$files = $this->processingFiles(); |
145
|
|
|
|
146
|
|
|
return $files['composer']; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @return bool |
151
|
|
|
*/ |
152
|
|
|
private function isProcessingAnyPhpFile() |
153
|
|
|
{ |
154
|
|
|
$files = $this->processingFiles(); |
155
|
|
|
|
156
|
|
|
return $files['php']; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @return bool |
161
|
|
|
*/ |
162
|
|
|
private function isProcessingAnyJsonFile() |
163
|
|
|
{ |
164
|
|
|
$files = $this->processingFiles(); |
165
|
|
|
|
166
|
|
|
return $files['json']; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* @return bool |
171
|
|
|
*/ |
172
|
|
|
private function existsFiles() |
173
|
|
|
{ |
174
|
|
|
return count($this->files) > 1 ? true : false; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* @return string |
179
|
|
|
*/ |
180
|
|
|
private function getRightMessage() |
181
|
|
|
{ |
182
|
|
|
$messages = $this->configData->getMessages(); |
183
|
|
|
|
184
|
|
|
return $messages[MessageConfigData::KEY_RIGHT_MESSAGE]; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.