]>
Commit | Line | Data |
---|---|---|
cef80743 ML |
1 | #!/usr/bin/env python3 |
2 | ||
3 | import argparse | |
4 | import datetime | |
5 | import os | |
6 | import shutil | |
7 | import subprocess | |
8 | import sys | |
9 | import tempfile | |
10 | from jinja2 import Environment, FileSystemLoader | |
11 | ||
12 | ||
13 | def version_str() -> str: | |
14 | try: | |
15 | return subprocess.check_output(["git", "describe"]).strip().decode("utf-8") | |
16 | except subprocess.CalledProcessError: | |
17 | return "0" | |
18 | ||
19 | ||
20 | def prep_tree(package) -> tuple: | |
21 | tmpdir = tempfile.mkdtemp() | |
22 | builddir = os.path.join(tmpdir, package) | |
23 | fwdir = os.path.join(builddir, "updates") | |
24 | targetdir = "dist" | |
25 | ||
26 | os.makedirs(targetdir, exist_ok=True) | |
27 | os.makedirs(builddir, exist_ok=False) | |
28 | os.makedirs(fwdir, exist_ok=False) | |
29 | ||
30 | subprocess.check_output(["./copy-firmware.sh", fwdir]) | |
31 | shutil.copy("WHENCE", os.path.join(builddir, "WHENCE")) | |
32 | ||
33 | return (tmpdir, builddir, fwdir, targetdir) | |
34 | ||
35 | ||
36 | def build_deb_package(package, builddir) -> None: | |
37 | env = Environment(loader=FileSystemLoader(os.path.join("contrib", "templates"))) | |
38 | ||
39 | d = { | |
40 | "package": package, | |
41 | "date": datetime.datetime.now() | |
42 | .astimezone() | |
43 | .strftime("%a, %d %b %Y %H:%M:%S %z"), | |
44 | "version": version_str(), | |
45 | } | |
46 | ||
47 | templates = { | |
48 | "debian.control": "control", | |
49 | "debian.changelog": "changelog", | |
50 | "debian.copyright": "copyright", | |
51 | } | |
52 | ||
53 | os.makedirs(os.path.join(builddir, "debian")) | |
54 | for f in templates: | |
55 | template = env.get_template(f) | |
56 | with open(os.path.join(builddir, "debian", templates[f]), "w") as w: | |
57 | w.write(template.render(d)) | |
58 | ||
59 | with open(os.path.join(builddir, "debian", "install"), "w") as w: | |
60 | w.write("updates lib/firmware\n") | |
61 | ||
62 | with open(os.path.join(builddir, "debian", "docs"), "w") as w: | |
63 | w.write("WHENCE\n") | |
64 | ||
65 | with open(os.path.join(builddir, "debian", "rules"), "w") as w: | |
66 | w.write("#!/usr/bin/make -f\n") | |
67 | w.write("%:\n") | |
68 | w.write("\tdh $@\n") | |
69 | os.chmod(os.path.join(builddir, "debian", "rules"), 0o755) | |
70 | ||
71 | os.mkdir(os.path.join(builddir, "debian", "source")) | |
72 | with open(os.path.join(builddir, "debian", "source", "format"), "w") as w: | |
73 | w.write("3.0 (native)\n") | |
74 | ||
75 | # build the package | |
76 | os.environ["DEB_BUILD_OPTIONS"] = "nostrip" | |
77 | subprocess.check_output(["dpkg-buildpackage", "-us", "-uc", "-b"], cwd=builddir) | |
78 | ||
79 | # result is in tmpdir (not builddir!) | |
80 | return os.path.join( | |
81 | "..", | |
82 | "{package}_{version}_all.deb".format(package=package, version=version_str()), | |
83 | ) | |
84 | ||
85 | ||
86 | def build_rpm_package(package, builddir) -> None: | |
87 | ||
88 | v = version_str().replace("-", "_") | |
89 | env = Environment(loader=FileSystemLoader(os.path.join("contrib", "templates"))) | |
90 | ||
91 | d = { | |
92 | "package": package, | |
93 | "version": v, | |
94 | "cwd": builddir, | |
95 | } | |
96 | ||
97 | template = env.get_template("rpm.spec") | |
98 | with open(os.path.join(builddir, "package.spec"), "wt") as w: | |
99 | w.write(template.render(d)) | |
100 | cmd = ["rpmbuild", "-bb", "--build-in-place", "package.spec"] | |
101 | subprocess.check_call(cmd, cwd=builddir, stderr=subprocess.STDOUT) | |
102 | ||
103 | # result is in ~/rpmbuild/RPMS/noarch/ | |
104 | for root, dirs, files in os.walk( | |
105 | os.path.join(os.getenv("HOME"), "rpmbuild", "RPMS", "noarch") | |
106 | ): | |
107 | for f in files: | |
108 | if f.startswith(package) and f.endswith(".rpm") and v in f: | |
109 | return os.path.join(root, f) | |
110 | raise FileNotFoundError("RPM package not found") | |
111 | ||
112 | ||
113 | def parse_args(): | |
114 | parser = argparse.ArgumentParser("Build upstream packages using Jinja2 templates") | |
115 | parser.add_argument("--deb", help="Build DEB package", action="store_true") | |
116 | parser.add_argument("--rpm", help="Build RPM package", action="store_true") | |
117 | parser.add_argument("--debug", help="Enable debug output", action="store_true") | |
118 | args = parser.parse_args() | |
119 | ||
120 | if not (args.rpm or args.deb) or (args.rpm and args.deb): | |
121 | parser.print_help() | |
122 | sys.exit(1) | |
123 | ||
124 | return args | |
125 | ||
126 | ||
127 | if __name__ == "__main__": | |
128 | args = parse_args() | |
129 | ||
130 | package = "linux-firmware-upstream" | |
131 | tmpdir, builddir, fwdir, targetdir = prep_tree(package) | |
132 | ||
133 | try: | |
134 | if args.deb: | |
135 | result = build_deb_package(package, builddir) | |
136 | elif args.rpm: | |
137 | result = build_rpm_package(package, builddir) | |
138 | shutil.copy(os.path.join(builddir, result), targetdir) | |
139 | print( | |
140 | "Built package: {}".format( | |
141 | os.path.join(targetdir, os.path.basename(result)) | |
142 | ) | |
143 | ) | |
144 | finally: | |
145 | if not args.debug: | |
146 | shutil.rmtree(tmpdir) |