summaryrefslogtreecommitdiffstats
path: root/scripts/osmo-depcheck/parse.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/osmo-depcheck/parse.py')
-rw-r--r--scripts/osmo-depcheck/parse.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/scripts/osmo-depcheck/parse.py b/scripts/osmo-depcheck/parse.py
new file mode 100644
index 0000000..c6297d6
--- /dev/null
+++ b/scripts/osmo-depcheck/parse.py
@@ -0,0 +1,116 @@
+# 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(gitdir, repo):
+ """ Parse the PKG_CHECK_MODULES statements of a configure.ac file.
+
+ :param gitdir: parent folder of all locally cloned git repositories
+ :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 = gitdir + "/" + 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