osmo-ci/scripts/osmo-depcheck/parse.py

117 lines
3.9 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2018 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
import sys
import fnmatch
# Same folder
import config
def error(line_i, message):
""" Print a configure.ac error message with the line number.
:param line_i: the zero based line counter """
print("ERROR: configure.ac line " + str(line_i+1) + ": " + message)
sys.exit(1)
def repository(library, version):
""" Find the git repository that contains a certain library. Based on the
information in config.py.
:param library: the name as referenced in the PKG_CHECK_MODULES
statement. For example: "libosmoabis"
:param version: for example "0.5.0"
:returns: the repository name, e.g. "libosmo-abis" """
for repo, libraries in config.repos.items():
if library in libraries:
print(" * " + library + ":" + version + " (part of " + repo + ")")
return repo
print(" * " + library + ":" + version)
return library
def library_is_relevant(library):
""" :returns: True when we would build the library in question from source,
False otherwise. """
for pattern in config.relevant_library_patterns:
if fnmatch.fnmatch(library, pattern):
return True
return False
def parse_condition(line):
""" Find the PKG_CHECK_MODULES conditions in any line from a configure.ac.
Example lines:
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.10.0)
PKG_CHECK_MODULES(LIBSYSTEMD, libsystemd)
:returns: * None when there's no condition in that line
* a string like "libosmocore >= 0.1.0" """
# Only look at PKG_CHECK_MODULES lines
if "PKG_CHECK_MODULES" not in line:
return
# Extract the condition
ret = line.split(",")[1].split(")")[0].strip()
# Only look at Osmocom libraries
library = ret.split(" ")[0]
if library_is_relevant(library):
return ret
def library_version(line_i, condition):
""" Get the library and version strings from a condition.
:param line_i: the zero based line counter
:param condition: a condition like "libosmocore >= 0.1.0" """
# Split by space and remove empty list elements
split = list(filter(None, condition.split(" ")))
if len(split) != 3:
error(line_i, "invalid condition format, expected something"
" like 'libosmocore >= 0.10.0' but got: '" +
condition + "'")
library, operator, version = split
# Right operator
if operator == ">=":
return (library, version)
# Wrong operator
error(line_i, "invalid operator, expected '>=' but got: '" +
operator + "'")
def configure_ac(workdir, repo):
""" Parse the PKG_CHECK_MODULES statements of a configure.ac file.
:param workdir: path to where all data (git, build, install) is stored
:param repo: the repository to look at (e.g. "osmo-bts")
:returns: a dictionary like the following:
{"libosmocore": "0.11.0",
"libosmo-abis": "0.5.0"} """
# Read configure.ac
path = workdir + "/git/" + repo + "/configure.ac"
with open(path) as handle:
lines = handle.readlines()
# Parse the file into ret
ret = {}
for i in range(0, len(lines)):
# Parse the line
condition = parse_condition(lines[i])
if not condition:
continue
(library, version) = library_version(i, condition)
# Add to ret (with duplicate check)
repo_dependency = repository(library, version)
if repo_dependency in ret and version != ret[repo_dependency]:
error(i, "found multiple PKG_CHECK_MODULES statements for " +
repo_dependency + ".git, and they have different"
" versions!")
ret[repo_dependency] = version
return ret