Skip to content

Commit

Permalink
Add XML output
Browse files Browse the repository at this point in the history
  • Loading branch information
MacFJA committed May 1, 2018
1 parent b778f61 commit 77c0030
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 26 deletions.
16 changes: 13 additions & 3 deletions bin/phpca
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ $version = file_exists(__DIR__.'/version.txt') ? trim(file_get_contents(__DIR__.
$doc = <<<DOC
PhpCodeAnalyzer $version
Usage:
phpca [-v] [--no-report] [--no-progress] [--since-version=<version>] FILES...
phpca [-v] --extension=<ext> FILES...
phpca [-v] [-q] [--output=<path>] [--no-report] [--no-progress] [--since-version=<version>] FILES...
phpca [-v] [-q] [--output=<path>] --extension=<ext> FILES...
phpca -h
Options:
-h --help Show this text
-v --verbose Show more debug text
-q --quiet Don't print any messages
--output=<path> Path where to generate XML report
--extension=<ext> Look for usage a specific extension
--no-report Turn off summary report
--no-progress Turn off progress
Expand All @@ -36,6 +38,13 @@ if (isset($args['--no-progress']) && $args['--no-progress'])
else
$_ENV['--no-progress'] = false;

$_ENV['quiet'] = (isset($args['--quiet']) && $args['--quiet']);

if (isset($args['--output']))
$_ENV['output'] = $args['--output'];
else
$_ENV['output'] = null;

$analyzer = new PhpCodeAnalyzer();

if (isset($args['--since-version']) && $args['--since-version'])
Expand All @@ -48,6 +57,7 @@ else


if (!empty($args['FILES'])) {
$analyzer->printXmlStart();
foreach ($args['FILES'] as $file) {
if (is_dir($file)) {
$analyzer->analyzeDir($file);
Expand All @@ -56,7 +66,7 @@ if (!empty($args['FILES'])) {
}
}
if ((!isset($args['--no-report']) || !$args['--no-report']) && !isset($args['--extension'])) {
echo PHP_EOL;
$analyzer->printUsedExtensions();
}
$analyzer->printXmlEnd();
}
94 changes: 71 additions & 23 deletions src/PhpCodeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function loadOneExtensionData($ext) {
}

public function analyzeDir($dir) {
echo 'Scanning '.$dir.' ...'.PHP_EOL;
$this->println('Scanning '.$dir.' ...');
$this->analyzeDirInternal($dir);
}

Expand All @@ -142,8 +142,7 @@ protected function analyzeDirInternal($dir) {
}

public function analyzeFile($file) {
if (isset($_ENV['verbose']) && $_ENV['verbose'])
echo 'Analyzing file '.$file.PHP_EOL;
$this->println('Analyzing file '.$file, true);
$source = file_get_contents($file);
$tokens = token_get_all($source);

Expand All @@ -169,8 +168,10 @@ public function analyzeFile($file) {
$ext = $this->classesSet[$class_name];
if (isset($this->usedExtensions[$ext])) $this->usedExtensions[$ext]++;
else $this->usedExtensions[$ext] = 1;
if (count($this->extensions) == 1 || !isset($_ENV['--no-progress']) || !$_ENV['--no-progress'])
fwrite(STDOUT, '['.$ext.'] Class "'.$class_name.'" used in file '.$file.'['.$tokens[$i][2].']'.PHP_EOL);
$this->printXmlFileData($file, $tokens[$i][2], $ext, 'class', $class_name);
if (count($this->extensions) == 1 || !isset($_ENV['--no-progress']) || !$_ENV['--no-progress']) {
$this->println('[' . $ext . '] Class "' . $class_name . '" used in file ' . $file . '[' . $tokens[$i][2] . ']');
}
}
}
// new statement
Expand All @@ -185,8 +186,9 @@ public function analyzeFile($file) {
$ext = $this->classesSet[$class_name];
if (isset($this->usedExtensions[$ext])) $this->usedExtensions[$ext]++;
else $this->usedExtensions[$ext] = 1;
$this->printXmlFileData($file, $tokens[$i][2], $ext, 'class', $class_name);
if (count($this->extensions) == 1 || !isset($_ENV['--no-progress']) || !$_ENV['--no-progress'])
fwrite(STDOUT, '['.$ext.'] Class "'.$class_name.'" used in file '.$file.'['.$tokens[$i][2].']'.PHP_EOL);
$this->println('['.$ext.'] Class "'.$class_name.'" used in file '.$file.'['.$tokens[$i][2].']');
}
}
// extends statement
Expand All @@ -201,8 +203,9 @@ public function analyzeFile($file) {
$ext = $this->classesSet[$class_name];
if (isset($this->usedExtensions[$ext])) $this->usedExtensions[$ext]++;
else $this->usedExtensions[$ext] = 1;
$this->printXmlFileData($file, $tokens[$i][2], $ext, 'class', $class_name);
if (count($this->extensions) == 1 || !isset($_ENV['--no-progress']) || !$_ENV['--no-progress'])
fwrite(STDOUT, '['.$ext.'] Class "'.$class_name.'" used in file '.$file.'['.$tokens[$i][2].']'.PHP_EOL);
$this->println('['.$ext.'] Class "'.$class_name.'" used in file '.$file.'['.$tokens[$i][2].']');
}
}
// find other usages
Expand All @@ -212,15 +215,17 @@ public function analyzeFile($file) {
$ext = $this->functionsSet[$tokens[$i][1]];
if (isset($this->usedExtensions[$ext])) $this->usedExtensions[$ext]++;
else $this->usedExtensions[$ext] = 1;
$this->printXmlFileData($file, $tokens[$i][2], $ext, 'function', $function_name);
if (count($this->extensions) == 1 || !isset($_ENV['--no-progress']) || !$_ENV['--no-progress'])
fwrite(STDOUT, '['.$ext.'] Function "'.$function_name.'" used in file '.$file.'['.$tokens[$i][2].']'.PHP_EOL);
$this->println('['.$ext.'] Function "'.$function_name.'" used in file '.$file.'['.$tokens[$i][2].']');
} else if (isset($this->constantsSet[$tokens[$i][1]])) {
$constant_name = $tokens[$i][1];
$ext = $this->constantsSet[$tokens[$i][1]];
if (isset($this->usedExtensions[$ext])) $this->usedExtensions[$ext]++;
else $this->usedExtensions[$ext] = 1;
$this->printXmlFileData($file, $tokens[$i][2], $ext, 'constant', $constant_name);
if (count($this->extensions) == 1 || !isset($_ENV['--no-progress']) || !$_ENV['--no-progress'])
fwrite(STDOUT, '['.$ext.'] Constant "'.$constant_name.'" used in file '.$file.'['.$tokens[$i][2].']'.PHP_EOL);
$this->println('['.$ext.'] Constant "'.$constant_name.'" used in file '.$file.'['.$tokens[$i][2].']');
}
}
}
Expand Down Expand Up @@ -281,47 +286,48 @@ protected function catchAsStringUntilOpenCurlyBrace(array $tokens, $pos) {
}

public function printUsedExtensions() {
$this->println('');
if (empty($this->usedExtensions)) {
echo 'Your code has no usage of non-built-in extension.'.PHP_EOL;
$this->printMsg('Your code has no usage of non-built-in extension.');
return null;
}
echo 'Used non-built-in extensions in your code:'.PHP_EOL;
$this->println('Used non-built-in extensions in your code:');
arsort($this->usedExtensions);
foreach ($this->usedExtensions as $extension => $uses_number) {
$extension_data = $this->extensions[$extension];

if (isset($extension_data['description']))
echo '- ['.$extension.'] '.$extension_data['description'].'.';
$this->printMsg('- ['.$extension.'] '.$extension_data['description'].'.');
else
echo '- '.$extension.'.';
$this->printMsg('- '.$extension.'.');

if (isset($extension_data['php_version'])) {
echo ' This extension is bundled with php since PHP '.$extension_data['php_version'].'.';
$this->printMsg(' This extension is bundled with php since PHP '.$extension_data['php_version'].'.');
} else if (isset($extension_data['before_php_version'])) {
echo ' This extension has been bundled with php prior PHP '.$extension_data['php_version'].'.';
$this->printMsg(' This extension has been bundled with php prior PHP '.$extension_data['php_version'].'.');
} else if (isset($extension_data['no_php_version'])) {
echo ' This extension has not been bundled with php in PHP '.$extension_data['no_php_version'][0].' - '.$extension_data['no_php_version'][1].'.';
$this->printMsg(' This extension has not been bundled with php in PHP '.$extension_data['no_php_version'][0].' - '.$extension_data['no_php_version'][1].'.');
}

if (isset($extension_data['dead'])) {
echo ' This extension is seen to be dead now.';
$this->printMsg(' This extension is seen to be dead now.');
}

if (isset($extension_data['pecl_name'])) {
echo ' Extension is available in pecl: '.$extension_data['pecl_name'].'.';
$this->printMsg(' Extension is available in pecl: '.$extension_data['pecl_name'].'.');
} else if (!isset($extension_data['pecl']) || $extension_data['pecl']) {
echo ' Extension is available in pecl: '.$extension.'.';
$this->printMsg(' Extension is available in pecl: '.$extension.'.');
} else if (isset($extension_data['download_link'])) {
echo ' Extension can be downloaded from external site: '.$extension_data['download_link'].'.';
$this->printMsg(' Extension can be downloaded from external site: '.$extension_data['download_link'].'.');
}

if (isset($extension_data['windows']) && !$extension_data['windows']) {
echo ' Windows is not supported by this extension.';
$this->printMsg(' Windows is not supported by this extension.');
} else if (isset($extension_data['windows_only']) && $extension_data['windows_only']) {
echo ' Only windows is supported by this extension.';
$this->printMsg(' Only windows is supported by this extension.');
}

echo PHP_EOL;
$this->println('');
}
}

Expand All @@ -340,4 +346,46 @@ protected function getExtensionFiles()
}
return $files;
}

private function println($message, $verbose = false)
{
$this->printMsg($message.PHP_EOL, $verbose);
}

private function printMsg($message, $verbose = false)
{
if ($_ENV['quiet']) {
return '';
}
if ($_ENV['verbose'] || !$verbose) {
fwrite(STDOUT, $message);
}
}

private function printXmlFileData($file, $line, $extension, $type, $name)
{
if ($_ENV['output'] === null) {
return;
}
$pattern = '<file path="%s" extension="%s" line="%d" type="%s">%s</file>';
file_put_contents($_ENV['output'], sprintf($pattern, $file, $extension, $line, $type, $name), FILE_APPEND);
}

public function printXmlStart()
{
if ($_ENV['output'] === null) {
return;
}
$version = file_exists(__DIR__.'/../bin/version.txt') ? trim(file_get_contents(__DIR__.'/../bin/version.txt')) : null;
$pattern = '<?xml version="1.0" encoding="UTF-8"?><php-code-analyzer version="%s"><files>';
file_put_contents($_ENV['output'], sprintf($pattern, $version));
}

public function printXmlEnd()
{
if ($_ENV['output'] === null) {
return;
}
file_put_contents($_ENV['output'], '</files></php-code-analyzer>', FILE_APPEND);
}
}

0 comments on commit 77c0030

Please sign in to comment.