File: setup.py

package info (click to toggle)
mini-buildd 2.4.4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,632 kB
  • sloc: python: 9,993; sql: 1,597; sh: 1,497; lisp: 90; javascript: 90; cpp: 70; makefile: 69
file content (146 lines) | stat: -rw-r--r-- 6,226 bytes parent folder | download | duplicates (5)
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
import glob
import os
import re
import shutil
import subprocess

import debian.changelog
import setuptools
import setuptools.command.build_py


def fopen(path, mode="r", **kwargs):
    return open(path, mode, encoding="UTF-8", **kwargs)


def deb2pep440(debian_version):
    """Get PEP 440 compliant version string from Debian version (``setuptools >=66`` mandates PEP 440)"""
    pos = debian_version.find("~")
    return debian_version if pos < 0 else debian_version[0:pos]


# Get version from debian/changelog
with open("./debian/changelog", "rb") as F:
    MINI_BUILDD_VERSION = str(debian.changelog.Changelog(file=F).version)


PY_ARGCOMPLETE = shutil.which("register-python-argcomplete")
print(f"I: Found p-r-argcomplete executable: {PY_ARGCOMPLETE}")


class Scripts():
    _INSTALL_PATHS = {1: "usr/bin/", 8: "usr/sbin/"}

    def __init__(self):
        # Auto-generate Debian install files.
        self.debian_install = {
            1: fopen("debian/mini-buildd-utils.install", "w"),
            8: fopen("debian/mini-buildd.install", "w"),
        }
        # dh_bash-completion format is very limited. The only way to automate this is to write the resp. configs here.
        self.debian_bash_completion = {
            1: fopen("debian/mini-buildd-utils.bash-completion", "w"),
            8: fopen("debian/mini-buildd.bash-completion", "w"),
        }

        for i in 1, 8:
            self.debian_install[i].write("# Generated by setup.py\n")

        # Static install contents for mini-buildd-util
        self.debian_install[1].write(("share/emacs/site-lisp/*.el /usr/share/emacs/site-lisp/\n"))

        # Static install contents for mini-buildd
        self.debian_install[8].write(("share/package-templates/ /usr/share/mini-buildd/\n"
                                      "etc/schroot/\n"
                                      "etc/sudoers.d/\n"
                                      "etc/profile.d/\n"))

    def setup(self, prog_path, section):
        prog = os.path.basename(prog_path)
        man_page_file = f"{prog_path}.{section}"

        # Hack to get the DESCRIPTION from script for '--name' argument. See: https://lintian.debian.org/tags/manpage-has-useless-whatis-entry.html
        with fopen(f"{prog_path}") as prog_file:
            name = re.search(r'DESCRIPTION.*=.*"(.+?)"', prog_file.read()).group(1)

        print(f"I: Generating {man_page_file}...")
        subprocess.run([prog_path, "--help"], check=True, stdout=subprocess.DEVNULL)  # Pre-test to get 'error debug' from prog itself to stderr (help2man call below will not show them).
        subprocess.check_call(["help2man", "--no-info", "--name", name, "--version-string", MINI_BUILDD_VERSION, "--section", str(section), "--output", man_page_file, prog_path])

        # bash completion (python only)
        with fopen(f"{prog_path}") as prog_file:
            if re.match(r"#!/usr/bin/python", prog_file.readline()):
                bash_completion_file = f"src/{prog}.bash-completion"
                print(f"I: Generating {bash_completion_file}...")
                os.makedirs(os.path.dirname(bash_completion_file), exist_ok=True)
                with fopen(bash_completion_file, "w") as bash_completion:
                    bash_completion.write(f'eval "$({PY_ARGCOMPLETE} --shell=bash "{prog}")"\n')
                self.debian_bash_completion[section].write(f"{bash_completion_file} {prog}\n")

        self.debian_install[section].write(f"{prog_path} {self._INSTALL_PATHS[section]}\n")


class VersionPy(setuptools.command.build_py.build_py):
    def run(self):
        version_file = "src/mini_buildd/version.py"
        print(f"I: Generating {version_file}...")
        with fopen(version_file, "w") as init_py:
            init_py.write(f"""\
__version__ = "{MINI_BUILDD_VERSION}"
""")


class BuildPy(setuptools.command.build_py.build_py):
    def run(self):
        VersionPy(self.distribution).run()

        scripts = Scripts()
        scripts.setup("src/mini-buildd", 8)

        scripts.setup("src/mini-buildd-self-signed-certificate", 8)
        scripts.setup("src/mini-buildd-backup", 8)
        scripts.setup("src/mini-buildd-debootstrap-uname-2.6", 8)
        scripts.setup("src/mini-buildd-ssh-setup", 8)
        scripts.setup("src/mini-buildd-ssh-uploader-command", 8)
        scripts.setup("src/mini-buildd-debug-build", 8)
        scripts.setup("src/mini-buildd-cruft", 8)
        scripts.setup("src/mini-buildd-import-08x", 8)

        scripts.setup("src/mini-buildd-api", 1)
        scripts.setup("src/mini-buildd-events", 1)
        scripts.setup("src/mini-buildd-dput", 1)
        scripts.setup("src/mini-buildd-internals", 1)
        scripts.setup("src/mini-buildd-bootstrap-apt", 1)
        scripts.setup("src/mini-buildd-super-portext", 1)

        super().run()

        # Auto-minifying some files. minify breaks "html" django templates, so skipped.
        for extension in ["css", "svg", "js"]:
            for f in glob.glob(f"{self.build_lib}/**/*.{extension}", recursive=True):
                print(f"I: Minifying {f}...")
                minified = f + ".minified"
                subprocess.check_call(["minify", "--output", minified, f])
                os.replace(minified, f)


def package_data_files(*patterns):
    """Little helper to collect file lists for package_data"""
    package_path = "src/mini_buildd/"
    for pattern in patterns:
        for f in glob.glob(f"{package_path}{pattern}", recursive=True):  # python 3.10's "root_dir" would help, but we need to support >=3.6.
            yield f[len(package_path):]


setuptools.setup(
    cmdclass={"version_py": VersionPy, "build_py": BuildPy},
    name="mini-buildd",
    version=deb2pep440(MINI_BUILDD_VERSION),  # Taint Debian version to make setuptools not warn
    description="Mini Debian build daemon",
    author="Stephan Sürken",
    author_email="absurd@debian.org",
    package_dir={"": "src"},
    packages=setuptools.find_packages("src"),                         # All traditional (dir has "__init__.py") packages: ['mini_buildd', 'mini_buildd.models']
    package_data={
        "mini_buildd": list(package_data_files("**/*.css", "**/*.js", "**/*.svg", "**/*.html", "templatetags/**/*.py")),
    })