feat: initial version of reporting script
This commit is contained in:
parent
0a3b838486
commit
de9cd30c0b
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!report.php
|
||||||
120
.drone.yml
Normal file
120
.drone.yml
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: main
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Fetch tags
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- git fetch --tags
|
||||||
|
- name: Update version and changelog
|
||||||
|
image: registry.riba-interactive.de/conventi:0.1.0
|
||||||
|
- name: Commit changelog updates
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- git add .
|
||||||
|
- git commit -m "version and changelog update [CI SKIP]"
|
||||||
|
- git push origin $DRONE_TARGET_BRANCH
|
||||||
|
- name: Tag commit
|
||||||
|
image: registry.riba-interactive.de/conventi:0.1.0
|
||||||
|
commands:
|
||||||
|
- export VERSION=$(conventi.sh get_version)
|
||||||
|
- git tag -am "Tagging new version $VERSION" "$VERSION"
|
||||||
|
- git push origin "$VERSION"
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
|
||||||
|
image_pull_secrets:
|
||||||
|
- dockerconfig
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: tag
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Build release
|
||||||
|
image: docker:dind
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
path: /var/run
|
||||||
|
environment:
|
||||||
|
DOCKER_USER:
|
||||||
|
from_secret: docker_user
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
from_secret: docker_password
|
||||||
|
commands:
|
||||||
|
- sleep 5 # give docker enough time to start
|
||||||
|
- echo "$DOCKER_PASSWORD" | docker login --username $DOCKER_USER --password-stdin registry.riba-interactive.de
|
||||||
|
- docker pull registry.riba-interactive.de/reportly:latest || true
|
||||||
|
- DOCKER_BUILDKIT=1 docker build --cache-from registry.riba-interactive.de/reportly:latest --tag registry.riba-interactive.de/reportly:latest .
|
||||||
|
- docker tag registry.riba-interactive.de/reportly:latest registry.riba-interactive.de/reportly:$DRONE_TAG
|
||||||
|
- docker push --all-tags registry.riba-interactive.de/reportly
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: docker
|
||||||
|
image: docker:dind
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
path: /var/run
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
temp: {}
|
||||||
|
|
||||||
|
image_pull_secrets:
|
||||||
|
- dockerconfig
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: Build and Test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Build image
|
||||||
|
image: docker:dind
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
path: /var/run
|
||||||
|
environment:
|
||||||
|
DOCKER_USER:
|
||||||
|
from_secret: docker_user
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
from_secret: docker_password
|
||||||
|
commands:
|
||||||
|
- sleep 5 # give docker enough time to start
|
||||||
|
- echo "$DOCKER_PASSWORD" | docker login --username $DOCKER_USER --password-stdin registry.riba-interactive.de
|
||||||
|
- docker pull registry.riba-interactive.de/reportly:latest || true
|
||||||
|
- DOCKER_BUILDKIT=1 docker build --cache-from registry.riba-interactive.de/reportly:latest --tag registry.riba-interactive.de/reportly:latest .
|
||||||
|
- docker tag registry.riba-interactive.de/reportly:latest registry.riba-interactive.de/reportly:build-$DRONE_BUILD_NUMBER
|
||||||
|
- docker push --all-tags registry.riba-interactive.de/reportly
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- feature/*
|
||||||
|
- bugfix/*
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: docker
|
||||||
|
image: docker:dind
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
path: /var/run
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
temp: {}
|
||||||
|
|
||||||
|
image_pull_secrets:
|
||||||
|
- dockerconfig
|
||||||
|
...
|
||||||
5
.version.json
Normal file
5
.version.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"version": "0.0.0",
|
||||||
|
"sha": "",
|
||||||
|
"url": "https://git.riba-interactive.de/rick/reportly"
|
||||||
|
}
|
||||||
8
CHANGELOG.md
Normal file
8
CHANGELOG.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file. See [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit guidelines.
|
||||||
|
|
||||||
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
FROM php:8.1-cli-alpine3.16
|
||||||
|
|
||||||
|
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories; \
|
||||||
|
apk --no-cache add \
|
||||||
|
lcov@testing \
|
||||||
|
composer; \
|
||||||
|
cd /usr/local/bin/ \
|
||||||
|
&& composer require erusev/parsedown
|
||||||
|
|
||||||
|
COPY report.php /usr/local/bin/
|
||||||
|
|
||||||
|
ENTRYPOINT ["report.php"]
|
||||||
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) year copyright holder. All Rights Reserved.
|
Copyright (c) 2022 Rick Barenthin. All Rights Reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
# reportly
|
# reportly
|
||||||
|
|
||||||
|
[](https://drone.riba-interactive.de/rick/reportly)
|
||||||
|
|||||||
164
report.php
Executable file
164
report.php
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
#!/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;
|
||||||
Loading…
Reference in New Issue
Block a user