build.py 3.66 KB
Newer Older
1
2
#!/usr/bin/env python3

3
4
5
import locale
locale.setlocale(locale.LC_ALL, "en_US.UTF-8")

6
7
import os
import subprocess as sp
8
import re
9
import shutil
10
11
12
13
14
15
16
17
18
import tempfile
import yaml


def load_config():
    with open("packages.yml", "r") as config_file:
        return yaml.load(config_file)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
PKG_NAME_PATTERN = r"[a-zA-Z0-9.+-]+"
EPOCH_PATTERN = r"[0-9]+:"
UPSTREAM_VERSION_PATTERN = r"[a-zA-Z0-9.+-:]+"
DEBIAN_VERSION_PATTERN = r"[a-zA-Z0-9.+~]+"
EXTRACT_PATTERN = (r"extracting (?P<name>{pkg_name}) in (?P<dir>{pkg_name}-{version})"
    .format(pkg_name=PKG_NAME_PATTERN, version=UPSTREAM_VERSION_PATTERN))


def run_checked(command, **kwargs):
    try:
        return sp.run(
            command, check=True,
            stdout=sp.PIPE, stderr=sp.PIPE, universal_newlines=True,
            **kwargs)
    except sp.CalledProcessError as error:
        print(error.stderr)
        raise
36
37
    

38
39
def build_package(repo_dir, package_dir, name,
        patch_dir=None, version=None, changelog=None):
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
    with tempfile.TemporaryDirectory(dir=os.path.abspath(".")) as tempdir:
        os.chdir(tempdir)
        result = run_checked(["apt-get", "source", name])
        source_dir_candidates = [
            line for line in result.stdout.splitlines() if "extracting" in line]
        if len(source_dir_candidates) != 1:
            raise ValueError("Got inconclusive candidate directories: {}".format(
                source_dir_candidates))
        source_dir_match = re.search(EXTRACT_PATTERN, source_dir_candidates[0])
        if source_dir_match is None:
            raise ValueError("Cannot get extraction directory from {}".format(
                source_dir_candidates[0]))
        pkg_dir = source_dir_match.group("dir")
        pkg_name = source_dir_match.group("name")
        if pkg_name != name:
            raise ValueError(
                "Extracted package {} is not expected package {}".format(
                    pkg_name, name))

        debian_workdir = os.path.join(tempdir, pkg_dir, "debian")
        os.chdir(debian_workdir)
        if patch_dir is not None:
            abs_patch_dir = os.path.join(repo_dir, patch_dir)
            for patch in sorted(os.listdir(abs_patch_dir)):
                patch_file = os.path.join(abs_patch_dir, patch)
                run_checked(["quilt", "import", patch_file])

        command = ["debchange", "--preserve"]
        if version is None:
            command.append("--nmu")
        else:
            command.extend(["--newversion", version])
        def _get_log_entries():
            if changelog:
                yield changelog
            yield "Non-maintainer upload"
        for entry in _get_log_entries():
            run_checked(command + [entry])

        command = ["debuild", "-b", "-uc", "-us"]
        run_checked(command)

        deb_packages =  [
            filename
            for filename in os.listdir(tempdir)
            if filename.endswith(".deb")
        ]
87
88
89
90
        for filename in os.listdir(tempdir):
            if not filename.endswith(".deb"):
                continue
            shutil.move(os.path.join(tempdir, filename), package_dir)
91
92


93
94
def main():
    repo_dir = os.getcwd()
95
96
97
98
99
100
101
102
103
104
    config = load_config()
    maintainer = config.get("maintainer", None)
    if maintainer is not None:
        name = maintainer.get("name", None)
        mail = maintainer.get("mail", None)
        if name:
            os.environ["DEBFULLNAME"] = name
        if mail:
            os.environ["DEBEMAIL"] = mail

105
106
107
    package_dir = "packages"
    os.makedirs(package_dir, exist_ok=True)
    
108
    for package in config["packages"]:
109
        build_package(repo_dir=repo_dir, package_dir=package_dir, **package)
Robin Sonnabend's avatar
Robin Sonnabend committed
110
        os.chdir(repo_dir)
111
112
113
114
115


if __name__ == "__main__":
    main()