forked from sebastianbergmann/phpcpd
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApplication.php
More file actions
140 lines (108 loc) · 3.96 KB
/
Application.php
File metadata and controls
140 lines (108 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php declare(strict_types=1);
/*
* This file is part of PHP Copy/Paste Detector (PHPCPD).
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPCPD;
use const PHP_EOL;
use function count;
use function printf;
use Exception;
use SebastianBergmann\FileIterator\Facade;
use SebastianBergmann\PHPCPD\Detector\Detector;
use SebastianBergmann\PHPCPD\Detector\Strategy\AbstractStrategy;
use SebastianBergmann\PHPCPD\Detector\Strategy\DefaultStrategy;
use SebastianBergmann\PHPCPD\Detector\Strategy\StrategyConfiguration;
use SebastianBergmann\PHPCPD\Detector\Strategy\SuffixTreeStrategy;
use SebastianBergmann\PHPCPD\Log\PMD;
use SebastianBergmann\PHPCPD\Log\Text;
use SebastianBergmann\Timer\ResourceUsageFormatter;
use SebastianBergmann\Timer\Timer;
use SebastianBergmann\Version;
final class Application
{
private const VERSION = '6.0.3';
public function run(array $argv): int
{
$this->printVersion();
try {
$arguments = (new ArgumentsBuilder)->build($argv);
} catch (Exception $e) {
print PHP_EOL . $e->getMessage() . PHP_EOL;
return 1;
}
if ($arguments->version()) {
return 0;
}
print PHP_EOL;
if ($arguments->help()) {
$this->help();
return 0;
}
$files = (new Facade)->getFilesAsArray(
$arguments->directories(),
$arguments->suffixes(),
'',
$arguments->exclude()
);
if (empty($files)) {
print 'No files found to scan' . PHP_EOL;
return 1;
}
$config = new StrategyConfiguration($arguments);
$strategy = $this->pickStrategy($arguments->algorithm(), $config);
$timer = new Timer;
$timer->start();
$clones = (new Detector($strategy))->copyPasteDetection($files);
(new Text)->printResult($clones, $arguments->verbose());
if ($arguments->pmdCpdXmlLogfile()) {
(new PMD($arguments->pmdCpdXmlLogfile()))->processClones($clones);
}
print (new ResourceUsageFormatter)->resourceUsage($timer->stop()) . PHP_EOL;
return count($clones) > 0 ? 1 : 0;
}
private function printVersion(): void
{
printf(
'phpcpd %s by Sebastian Bergmann.' . PHP_EOL,
(new Version(self::VERSION, dirname(__DIR__)))->getVersion()
);
}
private function pickStrategy(?string $algorithm, StrategyConfiguration $config): AbstractStrategy
{
switch ($algorithm) {
case null:
case 'rabin-karp':
return new DefaultStrategy($config);
case 'suffixtree':
return new SuffixTreeStrategy($config);
default:
throw new Exception('Unsupported algorithm: ' . $algorithm);
}
}
private function help(): void
{
print <<<'EOT'
Usage:
phpcpd [options] <directory>
Options for selecting files:
--suffix <suffix> Include files with names ending in <suffix> in the analysis
(default: .php; can be given multiple times)
--exclude <path> Exclude files with <path> in their path from the analysis
(can be given multiple times)
Options for analysing files:
--fuzzy Fuzz variable names
--min-lines <N> Minimum number of identical lines (default: 5)
--min-tokens <N> Minimum number of identical tokens (default: 70)
--algorithm <name> Select which algorithm to use ('rabin-karp' (default) or 'suffixtree')
--edit-distance <N> Distance in number of edits between two clones (only for suffixtree; default: 5)
--head-equality <N> Minimum equality at start of clone (only for suffixtree; default 10)
Options for report generation:
--log-pmd <file> Write log in PMD-CPD XML format to <file>
EOT;
}
}