1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# 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 + ")")
|