Commit cef8c614 authored by Sandro Knauß's avatar Sandro Knauß Committed by Ben Cooksley

Create a YAML file for further processing the output of abi-compliance-checker.

Differential Revision:
parent 437191fd
......@@ -13,8 +13,11 @@
import os
import logging
import argparse
import decimal
import re
import subprocess
import sys
import yaml
from helperslib import Packages
from helperslib.Version import Version
......@@ -57,6 +60,25 @@ class Library:
return candidate
def parseACCOutputToDict(stdout):
"""Parse output of abi-compliance-checker for further processing and returning a dict.
extract binary/source compatibility from acc
and calculate a simple bool for the compatibibility.
checkBlock = re.compile(br"""^Binary compatibility: (?P<binary>[0-9.]+)%\s*
Source compatibility: (?P<source>[0-9.]+)%\s*$""", re.M)
m =
m['binary'] = decimal.Decimal(m['binary'].decode())
m['source'] = decimal.Decimal(m['source'].decode())
compatibility = m['binary'] == 100 and m['source'] == 100
return {
'binaryCompatibility': float(m['binary']),
'sourceCompatibility': float(m['source']),
'compatibility': compatibility,
# Make sure logging is ready to go
......@@ -137,6 +159,9 @@ for l in libraries:
# Safe the overall retval state
retval = 0
# the dictonary that will be written to abi-compatibility-results.yaml
resultsYamlFile = {}
for l in libraries:
library = l.library
libname = library['libname']
......@@ -152,17 +177,45 @@ for l in libraries:"check %s(old) -> %s(new)", candidate['scmRevision'], library['scmRevision'])
reportPath = "compat_reports/{libname}_compat_report.html".format(libname=libname)
# Basic result yml information
yml = {
'reportPath': reportPath,
'ownCommit': scmRevision,
'otherCommit': candidate['scmRevision'],
resultsYamlFile[libname] = yml
if candidate['scmRevision'] in HASH2TAG:
yml['tag'] = HASH2TAG[candidate['scmRevision']].version
# check ABI and write compat reports
cmd = ["abi-compliance-checker",
"-report-path", "compat_reports/{libname}_compat_report.html".format(libname=libname),
cmd = [
"-report-path", reportPath,
"-l", libname,
"--old", oldLibraryPath,
"--new", newLibraryPath]
ret =
if ret != 0:
logging.error("abi-compliance-checker exited with %s", ret)
retval = ret
"--new", newLibraryPath,
logging.debug(" ".join(cmd))
prog =, check=True, capture_output=True)
except subprocess.CalledProcessError as e:
if e.returncode == 1: # that means that we are not compatible, but still valid output.
logging.warning("abi-compliance-checker exited with 1:\n%s", prog.stdout.decode())
logging.error("abi-compliance-checker exited with %s:\nstdout:\n\ŧ%s\nstderr:\n\t%s", e.returncode, e.stdout.decode(), e.stderr.decode())
retval = e.returncode
yml['error'] = e.returncode
with open('abi-compatibility-results.yaml', 'w') as f:
f.write(yaml.dump(resultsYamlFile, default_flow_style=False))
# We had an issue with one of the ABIs
if retval != 0:
......@@ -133,6 +133,9 @@ timestamps {
// Save the ABI Compatibility reports for developers to review if necessary
archiveArtifacts artifacts: 'compat_reports/*_compat_report.html', onlyIfSuccessful: false, allowEmptyArchive: true
// Save the ABI Compatibility results yaml file
archiveArtifacts artifacts: 'abi-compatibility-results.yaml', onlyIfSuccessful: false, allowEmptyArchive: true
// cppcheck is not supported by Pipeline at the moment, so we don't run that for now
// See
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment