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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2022 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
import glob
import os
import pathlib
import sys
import lib.config
import lib.debian
import lib.rpm_spec
def checkout_for_feed(project):
""" checkout a commit, either latest tag or master or 20YY branch """
feed = lib.args.feed
branch = lib.args.git_branch
if branch:
lib.git.checkout(project, f"origin/{branch}")
elif feed == "latest":
lib.git.checkout_latest_tag(project)
elif feed in ["master", "nightly"]:
lib.git.checkout_default_branch(project)
else: # 2022q1 etc
lib.git.checkout(project, f"origin/{feed}")
def get_git_version(project):
""" :returns: the string from git-version-gen, e.g. '1.7.0.10-76bdb' """
repo_path = lib.git.get_repo_path(project)
# Run git-version-gen if it is in the repository
script_path = f"{repo_path}/git-version-gen"
if os.path.exists(script_path):
ret = lib.run_cmd([script_path, "."], cwd=repo_path).output
if not ret:
lib.exit_error_cmd(ret, "empty output from git-version-gen")
return ret
# Generate a version string similar to git-version-gen, but run use git
# describe --tags, so it works with non-annotated tags as well (needed for
# e.g. limesuite's tags).
pattern = lib.git.get_latest_tag_pattern(project)
pattern = pattern.replace("^", "", 1)
pattern = pattern.replace("$", "", -1)
result = lib.run_cmd(["git", "describe",
"--abbrev=4",
"--tags",
f"--match={pattern}",
"HEAD"], cwd=repo_path, check=False)
if result.returncode == 128:
print(f"{project}: has no git tags, using 0.0.0 as version")
commit = lib.run_cmd(["git", "rev-parse", "HEAD"],
cwd=repo_path).output[0:4]
count = lib.run_cmd(["git", "rev-list", "--count", "HEAD"],
cwd=repo_path).output.rstrip()
return f"0.0.0.{count}-{commit}"
if result.returncode != 0:
lib.exit_error_cmd(result, "command failed unexpectedly")
ret = result.output.rstrip()
# Like git-version-gen:
# * Change the first '-' to '.'
# * Remove the 'g' in git describe's output string
# * Remove the leading 'v'
ret = ret.replace("-", ".", 1)
ret = ret.replace("-g", "-", 1)
if ret.startswith("v"):
ret = ret[1:]
return ret
def get_version_for_feed(project):
if lib.args.feed == "latest":
# There's always a tag if we are here. If there was none, the build
# would have been skipped for latest.
ret = lib.git.get_latest_tag(project)
return ret[1:] if ret.startswith("v") else ret
ret = get_git_version(project)
# Try to get the last version from the debian/changelog if we can't get
# it with git-version-gen, like it was done in the previous OBS scripts
if ret == "UNKNOWN":
ret = lib.debian.get_last_version_from_changelog(project)
# cut off epoch, we retrieve it separately in get_epoch() below
if ":" in ret:
ret = ret.split(":")[1]
# Append the conflict_version to increase the version even if the commit
# did not change (OS#5135)
conflict_version = lib.args.conflict_version
if conflict_version:
ret = f"{ret}.{conflict_version}"
return ret
def get_epoch(project):
""" The osmo-gbproxy used to have the same package version as osmo-sgsn
until 2021 where it was split into its own git repository. From then
on, osmo-gbproxy has a 0.*.* package version, which is smaller than
the previous 1.*.* from osmo-sgsn. We had to set the epoch to 1 for
osmo-gbproxy so package managers know these 0.*.* versions are higher
than the previous 1.*.* ones that are still found in e.g. debian 11.
The epoch is set in debian/changelog, retrieve it from there.
:returns: the epoch number if set, e.g. "1" or an empty string """
version_epoch = lib.debian.get_last_version_from_changelog(project)
if ":" in version_epoch:
return version_epoch.split(":")[0]
return ""
def prepare_project_open5gs():
""" Download the subproject sources here, so the package can be built in
OBS without Internet access. """
lib.run_cmd(["meson", "subprojects", "download"],
cwd=lib.git.get_repo_path("open5gs"))
def prepare_project_limesuite():
""" Fix bug in 23.10: https://github.com/myriadrf/LimeSuite/pull/386 """
lib.run_cmd(["mv", "-v",
"liblimesuite22.09-1.install",
"liblimesuite23.10-1.install"],
cwd=f"{lib.git.get_repo_path('limesuite')}/debian",
check=False)
def run_generate_build_dep(project):
""" Run contrib/generate_build_dep.sh if it exists in the given project, to
to download sources for dependencies (see e.g. osmo_dia2gsup.git). """
repo_path = lib.git.get_repo_path(project)
script_path = "contrib/generate_build_dep.sh"
if os.path.exists(f"{repo_path}/{script_path}"):
print(f"{project}: running {script_path}")
lib.run_cmd(script_path, cwd=repo_path)
def write_tarball_version(project, version):
repo_path = lib.git.get_repo_path(project)
with open(f"{repo_path}/.tarball-version", "w") as f:
f.write(f"{version}\n")
def write_commit_txt(project):
""" Write the current git commit to commit_$commit.txt file, so it gets
uploaded to OBS along with the rest of the source package. This allows
figuring out if the source package is still up-to-date or not for the
master feed. """
output_path = lib.get_output_path(project)
commit = lib.git.get_head(project)
print(f"{project}: adding commit_{commit}.txt")
pathlib.Path(f"{output_path}/commit_{commit}.txt").touch()
def build(project, gerrit_id=0):
conflict_version = lib.args.conflict_version
feed = lib.args.feed
version_append = lib.args.version_append
lib.git.clone(project)
lib.git.clean(project)
if gerrit_id > 0:
lib.git.checkout_from_review(project, gerrit_id)
else:
checkout_for_feed(project)
version = get_version_for_feed(project)
if version_append:
version += version_append
epoch = get_epoch(project)
version_epoch = f"{epoch}:{version}" if epoch else version
has_rpm_spec = lib.rpm_spec.get_spec_in_path(project) is not None
print(f"{project}: building source package {version_epoch}")
write_tarball_version(project, version_epoch)
if project in lib.config.projects_osmocom and not lib.args.no_meta:
metapkg = lib.args.conflict_pkgname or f"osmocom-{feed}"
lib.debian.control_add_depend(project, metapkg, conflict_version)
if has_rpm_spec:
lib.rpm_spec.add_depend(project, metapkg, conflict_version)
lib.debian.changelog_add_entry_if_needed(project, version_epoch)
os.makedirs(lib.get_output_path(project))
lib.remove_cache_extra_files()
project_specific_func = f"prepare_project_{os.path.basename(project)}"
if project_specific_func in globals():
print(f"{project}: running {project_specific_func}")
globals()[project_specific_func]()
if project in lib.config.projects_osmocom:
run_generate_build_dep(project)
lib.debian.build_source_package(project)
lib.debian.move_files_to_output(project)
if has_rpm_spec:
lib.rpm_spec.generate(project, version, epoch)
lib.rpm_spec.copy_to_output(project)
if feed == "master":
write_commit_txt(project)
lib.remove_cache_extra_files()
return version_epoch
def requires_osmo_gsm_manuals_dev(project):
""" Check if an already built source package has osmo-gsm-manuals-dev in
Build-Depends of the .dsc file """
path_dsc = glob.glob(f"{lib.get_output_path(project)}/*.dsc")
assert len(path_dsc) == 1, f"failed to get dsc path for {project}"
with open(path_dsc[0], "r") as handle:
for line in handle.readlines():
if line.startswith("Build-Depends:") \
and "osmo-gsm-manuals-dev" in line:
return True
return False
|