Skip to content

Instantly share code, notes, and snippets.

@jeffery
Created September 11, 2011 13:30
Show Gist options
  • Save jeffery/1209581 to your computer and use it in GitHub Desktop.
Save jeffery/1209581 to your computer and use it in GitHub Desktop.
Script to inspect PHP_Depend results
#!/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