165 lines
6.1 KiB
PHP
Executable File
165 lines
6.1 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
require('vendor/autoload.php');
|
|
|
|
$Parsedown = new Parsedown();
|
|
|
|
$inputDir = getenv('PLUGIN_INPUT_PATH') ?: 'cmake-build-ci';
|
|
$outputDir = getenv('PLUGIN_OUTPUT_PATH') ?: '.reports';
|
|
$reportTitle = getenv('PLUGIN_REPORT_TITLE') ?: 'Report';
|
|
$verbose = filter_var(getenv('PLUGIN_DEBUG'), FILTER_VALIDATE_BOOLEAN) ?: false;
|
|
$output = '';
|
|
|
|
if ($verbose) {
|
|
echo "Current settings:\n";
|
|
echo "\tcurrent working directory: " . getcwd() . "\n";
|
|
echo "\tinput directory: $inputDir\n";
|
|
echo "\toutput directory: $outputDir\n";
|
|
echo "\n";
|
|
}
|
|
|
|
if (!is_dir($inputDir)) {
|
|
echo "Invalid report input path, it should be a directory\n";
|
|
return 1;
|
|
}
|
|
|
|
if (!file_exists($outputDir)) {
|
|
mkdir($outputDir, 0777, true);
|
|
}
|
|
|
|
$htmlHeader = sprintf(
|
|
'<!DOCTYPE html><html><head><meta charset="utf-8"><title>%s</title><style>%s</style></head><body>',
|
|
$reportTitle,
|
|
'*,:after,:before{box-sizing:border-box}body{color:#444;font:18px/1.6 Georgia,Times New Roman,Times,serif;margin:40px auto;padding:0 20px}h1,h2,h3,h4,h5{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:1.2}a{color:#07c;text-decoration:none}a:hover{color:#059;text-decoration:underline}hr{border:0;margin:25px 0}table{border-collapse:collapse;border-spacing:0;padding-bottom:25px;text-align:left}hr,td,th{border-bottom:1px solid #ddd}button,select{background:#ddd;border:0;font-size:14px;padding:9px 20px}input,table{font-size:1pc}input,td,th{padding:5px;vertical-align:bottom}button:hover,code,pre{background:#eee}pre{overflow-x:scroll;padding:8px;font-size:14px}textarea{border-color:#ccc}.row{display:block;min-height:1px;width:auto}.row:after{clear:both;content:"";display:table}.row .c{float:left}.g2,.g3,.g3-2,.m2,.m3,.m3-2,table{width:100%}@media(min-width:8in){.g2{width:50%}.m2{margin-left:50%}.g3{width:33.33%}.g3-2{width:66.66%}.m3{margin-left:33.33%}.m3-2{margin-left:66.66%}}'
|
|
);
|
|
$htmlFooter = '</body></html>';
|
|
|
|
$output .= sprintf("%s\n%s\n\n\n", $reportTitle, str_repeat('=', strlen($reportTitle)));
|
|
|
|
$coverageInfoFile = join_paths($inputDir, 'coverage.info');
|
|
$outputLcov = [];
|
|
exec('lcov --rc lcov_branch_coverage=1 --list ' . $coverageInfoFile, $outputLcov);
|
|
|
|
array_shift($outputLcov);
|
|
|
|
$headerCovreport= 'Coverage report';
|
|
$output .= sprintf("%s\n%s\n\n\n", $headerCovreport, str_repeat('-', strlen($headerCovreport)));
|
|
$output .= sprintf("%s\n", '```');
|
|
$output .= implode("\n", $outputLcov);
|
|
$output .= sprintf("\n");
|
|
$output .= sprintf("%s\n\n", '```');
|
|
|
|
$output .= sprintf("%s\n\n", '[See full coverage report](coverage/index.html)');
|
|
|
|
if($verbose) {
|
|
echo "Coverage report:\n";
|
|
echo implode("\n", $outputLcov) . "\n\n";
|
|
}
|
|
|
|
$inputReportDir = join_paths($inputDir, 'Testing');
|
|
$inputReportFolder = '';
|
|
foreach (new DirectoryIterator($inputReportDir) as $fileInfo) {
|
|
if ($fileInfo->isDot()) continue;
|
|
if (preg_match('/\d+-\d+/', $fileInfo->getFilename())) {
|
|
$inputReportFolder = $fileInfo->getFilename();
|
|
break;
|
|
}
|
|
}
|
|
|
|
function join_paths(...$paths) {
|
|
return preg_replace('~[/\\\\]+~', DIRECTORY_SEPARATOR, implode(DIRECTORY_SEPARATOR, $paths));
|
|
}
|
|
|
|
$inputReportFile = join_paths($inputReportDir, $inputReportFolder, 'DynamicAnalysis.xml');
|
|
$xmlstr = file_get_contents($inputReportFile);
|
|
|
|
$tests = new SimpleXMLElement($xmlstr);
|
|
|
|
$countTests = count($tests->DynamicAnalysis->Test);
|
|
$numTest = 1;
|
|
|
|
$testMapping = [];
|
|
$typeMapping = [
|
|
'FIM' => 'Free Invalid Memory',
|
|
'FMM' => 'Free Mismatched Memory',
|
|
'UMR' => 'Uninitialised Memory Read',
|
|
'UMC' => 'Uninitialised Memory Conditional',
|
|
'IPW' => 'Invalid Pointer Write',
|
|
];
|
|
|
|
$headerMemreport = 'Memory check report';
|
|
$output .= sprintf("%s\n%s\n\n\n", $headerMemreport, str_repeat('-', strlen($headerMemreport)));
|
|
|
|
$memLeaksFound = count($tests->DynamicAnalysis->Test) != 0;
|
|
|
|
$outputMem = '';
|
|
|
|
if ($memLeaksFound) {
|
|
$outputMem .= sprintf("%s\n", '```');
|
|
foreach ($tests->DynamicAnalysis->Test as $test) {
|
|
$testMapping[$numTest] = $test->Name;
|
|
$outputMem .= sprintf("%d/%d MemCheck #%d: %s\n", $numTest, $countTests, $numTest, $test->Name);
|
|
|
|
$numResult = 1;
|
|
foreach ($test->Results->Defect as $result) {
|
|
$type = $result->attributes()->{'type'}->__toString();
|
|
$outputMem .= sprintf("\t%d: %s %s : %d\n",
|
|
$numResult,
|
|
str_repeat('.', 40),
|
|
($typeMapping[$type] ?? $type), $result);
|
|
$numResult++;
|
|
}
|
|
$numTest++;
|
|
}
|
|
$outputMem .= sprintf("%s\n\n", '```');
|
|
|
|
$outputMem .= sprintf("\n");
|
|
foreach (new DirectoryIterator(join_paths($inputReportDir, 'Temporary')) as $fileInfo) {
|
|
if ($fileInfo->isDot()) continue;
|
|
if (preg_match('/MemoryChecker/', $fileInfo->getFilename())) {
|
|
$memReport = file_get_contents($fileInfo->getPathname());
|
|
if (strlen($memReport) == 0) continue;
|
|
|
|
$number = explode('.', $fileInfo->getFilename())[1];
|
|
$testName = $testMapping[$number];
|
|
|
|
$headerMemreport = sprintf("Report #%d %s:", $number, $testName);
|
|
$outputMem .= sprintf("%s\n%s\n\n", $headerMemreport, str_repeat('-', strlen($headerMemreport)));
|
|
|
|
$memReport = file_get_contents($fileInfo->getPathname());
|
|
|
|
$outputMem .= sprintf("%s\n", '```');
|
|
$outputMem .= sprintf("%s", $memReport);
|
|
$outputMem .= sprintf("%s\n\n", '```');
|
|
}
|
|
}
|
|
} else {
|
|
$outputMem .= sprintf("%s\n\n", "NO MEMORY ISSUES, well done!");
|
|
}
|
|
|
|
if($verbose) {
|
|
echo "Memory check report\n";
|
|
echo $outputMem;
|
|
}
|
|
|
|
$output .= sprintf("%s", $outputMem);
|
|
|
|
file_put_contents(join_paths($outputDir, 'report.html'), $htmlHeader . $Parsedown->text($output) . $htmlFooter);
|
|
|
|
$coverageDirectoryOut = join_paths($outputDir, 'coverage');
|
|
mkdir($coverageDirectoryOut);
|
|
foreach (
|
|
$iterator = new \RecursiveIteratorIterator(
|
|
new \RecursiveDirectoryIterator(join_paths($inputDir, 'coverage'), \RecursiveDirectoryIterator::SKIP_DOTS),
|
|
\RecursiveIteratorIterator::SELF_FIRST) as $item
|
|
) {
|
|
if ($item->isDir()) {
|
|
mkdir(join_paths($coverageDirectoryOut, $iterator->getSubPathname()));
|
|
} else {
|
|
copy($item, join_paths($coverageDirectoryOut, $iterator->getSubPathname()));
|
|
}
|
|
}
|
|
|
|
return 0;
|