reportly/report.php
Rick Barenthin de9cd30c0b
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
feat: initial version of reporting script
2022-08-22 13:32:31 +02:00

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;