aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/obs/lib/debian.py
blob: 6703f8b4e58fb211f2a88c2fc75773d9747a457f (plain)
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
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2022 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
import datetime
import os
import shlex
import lib
import lib.git

# Imports that may not be available during startup, ignore it here and rely on
# lib.check_required_programs() checking this later on (possibly after the
# script executed itself in docker if using --docker).
try:
    import packaging.version
except ImportError:
    pass

def control_add_depend(project, pkgname, version):
    """ :param pkgname: of the meta-package to depend on (e.g. osmocom-nightly)
        :param version: of the meta-pkgname to depend on or None """
    repo_path = lib.git.get_repo_path(project)

    if version:
        depend = f"{pkgname} (= {version})"
    else:
        depend = pkgname

    cmd = ["sed", f"s/^Depends: /Depends: {depend}, /", "-i", "debian/control"]
    lib.run_cmd(cmd, cwd=repo_path)


def changelog_add_entry(project, version):
    """ :param version: for the new changelog entry """
    feed = lib.args.feed
    repo_path = lib.git.get_repo_path(project)
    changelog_path = f"{repo_path}/debian/changelog"

    changelog_old = open(changelog_path).read()

    # Package name might be different from project name, read it from changelog
    pkgname = changelog_old.split(" ", 1)[0]
    assert pkgname

    # Debian doesn't allow '-' in version
    version = version.replace("-", ".")

    # Debian changelog requires this specific date format
    date = datetime.datetime.now(datetime.timezone.utc)
    date_str = date.strftime("%a, %d %b %Y %H:%M:%S %z")

    # Add new changelog entry
    with open(changelog_path, "w") as f:
        f.write(f"{pkgname} ({version}) unstable; urgency=medium\n")
        f.write("\n")
        f.write("  * Automatically generated changelog entry for building the"
                f" Osmocom {feed} feed\n")
        f.write("\n")
        f.write(f" -- Osmocom OBS scripts <info@osmocom.org>  {date_str}\n")
        f.write("\n")
        f.write(changelog_old)


def fix_source_format(project):
    """ Always use format "3.0 (native)" (e.g. limesuite has "3.0 (quilt)")."""
    repo_path = lib.git.get_repo_path(project)
    format_path = f"{repo_path}/debian/source/format"
    if not os.path.exists(format_path):
        return

    expected = "3.0 (native)"
    current = open(format_path, "r").read().rstrip()

    if current == expected:
        return

    print(f"{project}: fixing debian/source/format ({current} => {expected})")
    open(format_path, "w").write(f"{expected}\n")


def get_last_version_from_changelog(project):
    repo_path = lib.git.get_repo_path(project)
    changelog_path = f"{repo_path}/debian/changelog"

    assert os.path.exists(changelog_path), f"{project}: missing debian/changelog"

    changelog = open(changelog_path).read()
    assert changelog, f"{project}: debian/changelog is empty"

    ret = changelog.split("(", 1)[1].split(")", 1)[0]
    assert ret, f"{project}: couldn't find last version in debian/changelog"

    return ret


def changelog_add_entry_if_needed(project, version):
    """ Adjust the changelog if the version in the changelog is different from
        the given version. """
    version_changelog = get_last_version_from_changelog(project)

    # Don't use a lower number (OS#6173)
    try:
        if packaging.version.parse(version_changelog.split("-")[0]) > \
                packaging.version.parse(version.split("-")[0]):
            print(f"{project}: WARNING: version from changelog"
                  f" ({version_changelog}) is higher than version based on git tag"
                  f" ({version}), using version from changelog (git tag not pushed"
                  " yet?)")
            return
    except packaging.version.InvalidVersion:
        # packaging.version.parse can parse the version numbers used in Osmocom
        # projects (where we need the above check), but not e.g. some versions
        # from wireshark. Don't abort here if that is the case.
        pass

    if version_changelog == version:
        return

    print(f"{project}: adding debian/changelog entry ({version_changelog} =>"
          f" {version})")
    changelog_add_entry(project, version)


def build_source_package(project):
    fix_source_format(project)
    print(f"{project}: building debian source package")
    lib.run_cmd(["dpkg-buildpackage", "-S", "-uc", "-us", "-d"],
                cwd=lib.git.get_repo_path(project))


def move_files_to_output(project):
    path_output = lib.get_output_path(project)
    lib.run_cmd(f"mv *.tar* *.dsc {shlex.quote(path_output)}", shell=True,
                cwd=lib.config.path_cache)