mirror of https://gerrit.osmocom.org/osmo-ci
133 lines
5.3 KiB
Python
133 lines
5.3 KiB
Python
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# Copyright 2018 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
|
|
|
import collections
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
# Same folder
|
|
import parse
|
|
|
|
|
|
def git_clone(workdir, prefix, cache_git_fetch, repository, version):
|
|
""" Clone a missing git repository and checkout a specific version tag.
|
|
|
|
:param workdir: path to where all data (git, build, install) is stored
|
|
:param prefix: git url prefix (e.g. "git://git.osmocom.org/")
|
|
:param cache_git_fetch: list of repositories that have already been
|
|
fetched in this run of osmo-depcheck
|
|
:param repository: Osmocom git repository name (e.g. "libosmo-abis")
|
|
:param version: "master" or a version tag like "0.11.0" """
|
|
repodir = workdir + "/git/" + repository
|
|
if repository not in cache_git_fetch:
|
|
if os.path.exists(repodir):
|
|
# Fetch tags for existing source
|
|
print("Fetching tags...")
|
|
subprocess.run(["git", "-C", repodir, "fetch", "--tags", "-q"],
|
|
check=True)
|
|
else:
|
|
# Clone the source
|
|
url = prefix + repository
|
|
print("Cloning git repo: " + url)
|
|
try:
|
|
subprocess.run(["git", "-C", workdir + "/git", "clone", "-q",
|
|
url], check=True)
|
|
except subprocess.CalledProcessError:
|
|
print("NOTE: if '" + repository + "' is part of a git"
|
|
" repository with a different name, please add it to the"
|
|
" mapping in 'config.py' and try again.")
|
|
sys.exit(1)
|
|
|
|
# Only fetch the same repository once per session
|
|
cache_git_fetch.append(repository)
|
|
|
|
# Checkout the version tag
|
|
try:
|
|
subprocess.run(["git", "-C", repodir, "checkout", version, "-q"],
|
|
check=True)
|
|
except subprocess.CalledProcessError:
|
|
print("ERROR: git checkout failed! Invalid version specified?")
|
|
sys.exit(1)
|
|
|
|
|
|
def generate(workdir, prefix, cache_git_fetch, initial, rev):
|
|
""" Generate the dependency graph of an Osmocom program by cloning the git
|
|
repository, parsing the "configure.ac" file, and recursing.
|
|
|
|
:param workdir: path to where all data (git, build, install) is stored
|
|
:param prefix: git url prefix (e.g. "git://git.osmocom.org/")
|
|
:param cache_git_fetch: list of repositories that have already been
|
|
fetched in this run of osmo-depcheck
|
|
:param initial: the first program to look at (e.g. "osmo-bts")
|
|
:param rev: the git revision to check out ("master", "0.1.0", ...)
|
|
:returns: a dictionary like the following:
|
|
{"osmo-bts": {"version": "master",
|
|
"depends": {"libosmocore": "0.11.0",
|
|
"libosmo-abis": "0.5.0"}},
|
|
"libosmocore": {"version": "0.11.0",
|
|
"depends": {}},
|
|
"libosmo-abis": {"version": "0.5.0",
|
|
"depends": {"libosmocore": "0.11.0"}} """
|
|
# Iterate over stack
|
|
stack = collections.OrderedDict({initial: rev})
|
|
ret = collections.OrderedDict()
|
|
while len(stack):
|
|
# Pop program from stack
|
|
program, version = next(iter(stack.items()))
|
|
del stack[program]
|
|
|
|
# Skip when already parsed
|
|
if program in ret:
|
|
continue
|
|
|
|
# Add the programs dependencies to the stack
|
|
print("Looking at " + program + ":" + version)
|
|
git_clone(workdir, prefix, cache_git_fetch, program, version)
|
|
depends = parse.configure_ac(workdir, program)
|
|
stack.update(depends)
|
|
|
|
# Add the program to the ret
|
|
ret[program] = {"version": version, "depends": depends}
|
|
|
|
return ret
|
|
|
|
|
|
def print_dict(depends):
|
|
""" Print the whole dependency graph.
|
|
:param depends: return value from generate() above """
|
|
print("Dependency graph:")
|
|
|
|
for program, data in depends.items():
|
|
version = data["version"]
|
|
depends = data["depends"]
|
|
print(" * " + program + ":" + version + " depends: " + str(depends))
|
|
|
|
|
|
def git_latest_tag(workdir, repository):
|
|
""" Get the last release string by asking git for the latest tag.
|
|
|
|
:param workdir: path to where all data (git, build, install) is stored
|
|
:param repository: Osmocom git repository name (e.g. "libosmo-abis")
|
|
:returns: the latest git tag (e.g. "1.0.2") """
|
|
dir = workdir + "/git/" + repository
|
|
complete = subprocess.run(["git", "-C", dir, "describe", "--abbrev=0",
|
|
"master"], check=True, stdout=subprocess.PIPE)
|
|
return complete.stdout.decode().rstrip()
|
|
|
|
|
|
def print_old(workdir, depends):
|
|
""" Print dependencies tied to an old release tag
|
|
|
|
:param workdir: path to where all data (git, build, install) is stored
|
|
:param depends: return value from generate() above """
|
|
print("Dependencies on old releases:")
|
|
|
|
for program, data in depends.items():
|
|
for depend, version in data["depends"].items():
|
|
latest = git_latest_tag(workdir, depend)
|
|
if latest == version:
|
|
continue
|
|
print(" * " + program + ":" + data["version"] + " -> " +
|
|
depend + ":" + version + " (latest: " + latest + ")")
|