Created
September 11, 2011 13:30
-
-
Save jeffery/1209581 to your computer and use it in GitHub Desktop.
Script to inspect PHP_Depend results
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
/** | |
* Usage: | |
* pdepend --summary-xml=/tmp/summary.xml /path/to/source | |
* | |
* ./inspekt.php /tmp/summary.xml --metric0 | |
*/ | |
class Inspect | |
{ | |
protected $logFile = null; | |
protected $mode = 'single'; | |
protected $metric0 = null; | |
protected $metric1 = null; | |
protected $limit = -1; | |
protected $dumpFile = false; | |
protected $type = 'method'; | |
protected $format = false; | |
public function __construct(array $options) | |
{ | |
if ($this->parseOptions($options)) { | |
$this->evaluate(); | |
} | |
} | |
protected function evaluate() | |
{ | |
switch ($this->mode) { | |
case 'single': | |
$this->evaluateSingle(); | |
break; | |
case 'ratio': | |
$this->evaluateRatio(); | |
break; | |
default: | |
fwrite(STDERR, 'Unknown mode "' . $this->mode . '".' . PHP_EOL . PHP_EOL); | |
return $this->printHelp(); | |
} | |
} | |
protected function evaluateSingle() | |
{ | |
$xpath = new DOMXPath($this->logFile); | |
$nodes = $xpath->query("//{$this->type}/@*[name(.) = '$this->metric0']/.."); | |
$result = array(); | |
foreach ($nodes as $node) { | |
if (null === ($name = $this->getName($node))) { | |
continue; | |
} | |
$result[] = array($node->getAttribute($this->metric0), $name, $this->getFile($node)); | |
} | |
$this->dumpResult($this->queryValues($this->metric0)); | |
} | |
protected function evaluateRatio() | |
{ | |
$result0 = $this->queryValues($this->metric0); | |
$result1 = $this->queryValues($this->metric1); | |
foreach ($result1 as $idx => $metric) { | |
if ($metric[0] != 0) { | |
$result0[$idx][0] /= $metric[0]; | |
} | |
} | |
$this->dumpResult($result0); | |
} | |
protected function queryValues($metric) | |
{ | |
$xpath = new DOMXPath($this->logFile); | |
$nodes = $xpath->query("//{$this->type}/@*[name(.) = '$metric']/.."); | |
$result = array(); | |
foreach ($nodes as $node) { | |
if (null === ($name = $this->getName($node))) { | |
continue; | |
} | |
$result[] = array($node->getAttribute($metric), $name, $this->getFile($node)); | |
} | |
return $result; | |
} | |
protected function getName(DOMElement $elem) | |
{ | |
if ($elem->nodeName === 'method') { | |
return $elem->parentNode->getAttribute('name') . '::' . | |
$elem->getAttribute('name') . '()'; | |
} else if ($elem->nodeName === 'class') { | |
return $elem->getAttribute('name'); | |
} else if ($elem->nodeName === 'file') { | |
return $elem->getAttribute('name'); | |
} | |
return null; | |
} | |
protected function getFile(DOMElement $elem) | |
{ | |
if ($elem->nodeName === 'method') { | |
return $elem->parentNode->getElementsByTagName('file')->item(0)->getAttribute('name'); | |
} else if ($elem->nodeName === 'class') { | |
return $elem->getElementsByTagName('file')->item(0)->getAttribute('name'); | |
} else if ($elem->nodeName === 'file') { | |
return $elem->getAttribute('name'); | |
} | |
return null; | |
} | |
protected function dumpResult(array $result) | |
{ | |
usort($result, function($a1, $a2) { | |
return bccomp($a2[0], $a1[0], 10); | |
}); | |
if ($this->limit > 0) { | |
$result = array_slice($result, 0, $this->limit); | |
} | |
echo '=============================================================================', PHP_EOL, | |
' Name | Value ', PHP_EOL, | |
'=============================================================================', PHP_EOL; | |
foreach ($result as $metric) { | |
printf(" % -55s | ", $metric[1]); | |
$this->dumpValue($metric); | |
$this->dumpFile($metric); | |
} | |
echo '=============================================================================', PHP_EOL; | |
} | |
protected function dumpValue(array $result) | |
{ | |
if ($this->format) { | |
echo number_format($result[0], 4, ',', '.'); | |
} else { | |
printf('%.4f', $result[0]); | |
} | |
echo PHP_EOL; | |
} | |
protected function dumpFile(array $result) | |
{ | |
if (false === $this->dumpFile) { | |
return; | |
} | |
if (($length = strlen($result[2])) > 55) { | |
$file = '...' . substr($result[2], $length - 50); | |
} else { | |
$file = $result[2]; | |
} | |
printf(" % -53s |%s", $file, PHP_EOL); | |
} | |
protected function parseOptions(array $options) | |
{ | |
if (in_array('-h', $options) || in_array('--help', $options)) { | |
return $this->printHelp(); | |
} | |
if (count($options) < 3 || count($options) % 2 === 0) { | |
return $this->printHelp(); | |
} | |
$log = array_shift($options); | |
if (false === file_exists($log)) { | |
fwrite( | |
STDERR, | |
'The specified <logfile> "' . $log . '" does not exist.' . | |
PHP_EOL . PHP_EOL | |
); | |
return $this->printHelp(); | |
} | |
$this->logFile = new DOMDocument(); | |
$this->logFile->load($log); | |
for ($i = 0; $i < count($options); $i+=2) { | |
switch($options[$i]) { | |
case '-m': | |
case '--mode': | |
$this->mode = $options[$i+1]; | |
break; | |
case '-m0': | |
case '--metric0': | |
$this->metric0 = $options[$i+1]; | |
break; | |
case '-m1': | |
case '--metric1': | |
$this->metric1 = $options[$i+1]; | |
break; | |
case '-l': | |
case '--limit': | |
$this->limit = (int) $options[$i+1]; | |
break; | |
case '-t': | |
case '--type': | |
$this->type = $options[$i+1]; | |
break; | |
case '-d': | |
case '--dump-file': | |
$this->dumpFile = strcasecmp('true', $options[$i+1]) === 0; | |
break; | |
case '-f': | |
case '--format': | |
$this->format = strcasecmp('true', $options[$i+1]) === 0; | |
break; | |
default: | |
fwrite( | |
STDERR, | |
'Unknown option "' . $options[$i] . '" given' . | |
PHP_EOL . PHP_EOL | |
); | |
return $this->printHelp(); | |
} | |
} | |
return true; | |
} | |
protected function printHelp() | |
{ | |
echo 'Usage: ', basename(__FILE__), ' <logfile> --metric0 <metric> [options] ', | |
PHP_EOL, PHP_EOL, | |
' -m --mode $M Analyze "single" metric or "ration" between two ',PHP_EOL, | |
' different metrics. ',PHP_EOL, | |
' -t --type $T Object to analyze: "file", "class" or "method". ',PHP_EOL, | |
' -m0 --metric0 $M Name of the metric to inspect, e.g. "ccn2" or "wmc".',PHP_EOL, | |
' -m1 --metric1 $M Second metric to inspect, used for "ratio" mode. ',PHP_EOL, | |
PHP_EOL, PHP_EOL, | |
' -l --limit $N Limits the output to $N records. ',PHP_EOL, | |
' -d --dump-file $B Adds an additional output line with the source file.',PHP_EOL, | |
' Possible values are "true" or "false". ',PHP_EOL, | |
' -f --format $B Format metric value in german number format. Useful ',PHP_EOL, | |
' to show NPath values. Values are "true" or "false". ', | |
PHP_EOL, PHP_EOL, | |
' -h --help Prints this help text. ',PHP_EOL; | |
return false; | |
} | |
public static function main(array $argv) | |
{ | |
$options = $argv; | |
array_shift($options); | |
new Inspect($options); | |
} | |
} | |
Inspect::main($argv); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment