1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Cauditor\Analyzers; |
4
|
|
|
|
5
|
|
|
use Cauditor\Config; |
6
|
|
|
use Cauditor\Exception; |
7
|
|
|
use MatthiasMullie\PathConverter\Converter as PathConverter; |
8
|
|
|
use PDepend\Application; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* @author Matthias Mullie <[email protected]> |
12
|
|
|
* @copyright Copyright (c) 2016, Matthias Mullie. All rights reserved. |
13
|
|
|
* @license LICENSE MIT |
14
|
|
|
*/ |
15
|
|
|
class PDepend implements AnalyzerInterface |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* pdepend XML filename. |
19
|
|
|
* |
20
|
|
|
* @var string |
21
|
|
|
*/ |
22
|
|
|
protected $xml = 'pdepend.xml'; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* cauditor JSON filename. |
26
|
|
|
* |
27
|
|
|
* @var string |
28
|
|
|
*/ |
29
|
|
|
protected $json = 'cauditor.json'; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var string |
33
|
|
|
*/ |
34
|
|
|
protected $buildPath; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var Config |
38
|
|
|
*/ |
39
|
|
|
protected $config; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @param Config $config |
43
|
|
|
*/ |
44
|
|
|
public function __construct(Config $config) |
45
|
|
|
{ |
46
|
|
|
$this->setConfig($config); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @param Config $config |
51
|
|
|
*/ |
52
|
|
View Code Duplication |
public function setConfig(Config $config) |
|
|
|
|
53
|
|
|
{ |
54
|
|
|
$this->config = $config; |
55
|
|
|
|
56
|
|
|
// all paths in build_path are relative to project root, which may not |
57
|
|
|
// be where this code is run from, so prepend the project root! |
58
|
|
|
$this->buildPath = $this->config['path'].DIRECTORY_SEPARATOR.$this->config['build_path']; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @return array |
63
|
|
|
* |
64
|
|
|
* @throws Exception |
65
|
|
|
*/ |
66
|
|
|
public function execute() |
67
|
|
|
{ |
68
|
|
|
exec('mkdir -p '.$this->buildPath, $output, $result); |
69
|
|
|
if ($result !== 0) { |
70
|
|
|
throw new Exception('Unable to create build directory.'); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
// let pdepend generate all metrics we'll need |
74
|
|
|
$this->pdepend(); |
75
|
|
|
|
76
|
|
|
// convert pdepend xml into cauditor json & store to file |
77
|
|
|
$json = $this->convert($this->buildPath.DIRECTORY_SEPARATOR.$this->xml); |
78
|
|
|
file_put_contents($this->buildPath.DIRECTORY_SEPARATOR.$this->json, $json); |
79
|
|
|
|
80
|
|
|
// if we expect these json files to be loaded client-side to render |
81
|
|
|
// the charts, might as well assume it'll fit in this machine's |
82
|
|
|
// memory to submit it to our API ;) |
83
|
|
|
return json_decode($json); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Runs pdepend to generate the metrics. |
88
|
|
|
* |
89
|
|
|
* @throws Exception |
90
|
|
|
*/ |
91
|
|
View Code Duplication |
protected function pdepend() |
|
|
|
|
92
|
|
|
{ |
93
|
|
|
$application = new Application(); |
94
|
|
|
$runner = $application->getRunner(); |
95
|
|
|
|
96
|
|
|
$runner->setSourceArguments(array($this->config['path'])); |
97
|
|
|
$runner->addReportGenerator('summary-xml', $this->buildPath.DIRECTORY_SEPARATOR.$this->xml); |
98
|
|
|
|
99
|
|
|
// exclude directories are evaluated relative to where pdepend is being |
100
|
|
|
// run from, not what it is running on |
101
|
|
|
$converter = new PathConverter($this->config['path'], getcwd()); |
102
|
|
|
$exclude = array_map(array($converter, 'convert'), $this->config['exclude_folders']); |
103
|
|
|
$runner->setExcludeDirectories($exclude); |
104
|
|
|
|
105
|
|
|
$status = $runner->run(); |
106
|
|
|
if ($status !== 0) { |
107
|
|
|
throw new Exception('Unable to generate pdepend metrics.'); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Transform pdepend output into the (more succinct) format cauditor |
113
|
|
|
* understands. |
114
|
|
|
* |
115
|
|
|
* @param string $xml |
116
|
|
|
* |
117
|
|
|
* @return string |
118
|
|
|
*/ |
119
|
|
|
protected function convert($xml) |
120
|
|
|
{ |
121
|
|
|
$reader = new XMLReader(); |
122
|
|
|
$reader->open($xml); |
123
|
|
|
|
124
|
|
|
$converter = new Converter(); |
125
|
|
|
$json = $converter->convert($reader); |
126
|
|
|
|
127
|
|
|
$reader->close(); |
128
|
|
|
|
129
|
|
|
return $json; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
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.