| #!/usr/bin/env python3 |
| |
| import argparse |
| import datetime |
| import os |
| import shutil |
| import subprocess |
| import sys |
| import tempfile |
| from jinja2 import Environment, FileSystemLoader |
| |
| |
| def version_str() -> str: |
| try: |
| return subprocess.check_output(["git", "describe"]).strip().decode("utf-8") |
| except subprocess.CalledProcessError: |
| return "0" |
| |
| |
| def prep_tree(package) -> tuple: |
| tmpdir = tempfile.mkdtemp() |
| builddir = os.path.join(tmpdir, package) |
| fwdir = os.path.join(builddir, "updates") |
| targetdir = "dist" |
| |
| os.makedirs(targetdir, exist_ok=True) |
| os.makedirs(builddir, exist_ok=False) |
| os.makedirs(fwdir, exist_ok=False) |
| |
| subprocess.check_output(["./copy-firmware.sh", fwdir]) |
| shutil.copy("WHENCE", os.path.join(builddir, "WHENCE")) |
| |
| return (tmpdir, builddir, fwdir, targetdir) |
| |
| |
| def build_deb_package(package, builddir) -> None: |
| env = Environment(loader=FileSystemLoader(os.path.join("contrib", "templates"))) |
| |
| d = { |
| "package": package, |
| "date": datetime.datetime.now() |
| .astimezone() |
| .strftime("%a, %d %b %Y %H:%M:%S %z"), |
| "version": version_str(), |
| } |
| |
| templates = { |
| "debian.control": "control", |
| "debian.changelog": "changelog", |
| "debian.copyright": "copyright", |
| } |
| |
| os.makedirs(os.path.join(builddir, "debian")) |
| for f in templates: |
| template = env.get_template(f) |
| with open(os.path.join(builddir, "debian", templates[f]), "w") as w: |
| w.write(template.render(d)) |
| |
| with open(os.path.join(builddir, "debian", "install"), "w") as w: |
| w.write("updates lib/firmware\n") |
| |
| with open(os.path.join(builddir, "debian", "docs"), "w") as w: |
| w.write("WHENCE\n") |
| |
| with open(os.path.join(builddir, "debian", "rules"), "w") as w: |
| w.write("#!/usr/bin/make -f\n") |
| w.write("%:\n") |
| w.write("\tdh $@\n") |
| os.chmod(os.path.join(builddir, "debian", "rules"), 0o755) |
| |
| os.mkdir(os.path.join(builddir, "debian", "source")) |
| with open(os.path.join(builddir, "debian", "source", "format"), "w") as w: |
| w.write("3.0 (native)\n") |
| |
| # build the package |
| os.environ["DEB_BUILD_OPTIONS"] = "nostrip" |
| subprocess.check_output(["dpkg-buildpackage", "-us", "-uc", "-b"], cwd=builddir) |
| |
| # result is in tmpdir (not builddir!) |
| return os.path.join( |
| "..", |
| "{package}_{version}_all.deb".format(package=package, version=version_str()), |
| ) |
| |
| |
| def build_rpm_package(package, builddir) -> None: |
| |
| v = version_str().replace("-", "_") |
| env = Environment(loader=FileSystemLoader(os.path.join("contrib", "templates"))) |
| |
| d = { |
| "package": package, |
| "version": v, |
| "cwd": builddir, |
| } |
| |
| template = env.get_template("rpm.spec") |
| with open(os.path.join(builddir, "package.spec"), "wt") as w: |
| w.write(template.render(d)) |
| cmd = ["rpmbuild", "-bb", "--build-in-place", "package.spec"] |
| subprocess.check_call(cmd, cwd=builddir, stderr=subprocess.STDOUT) |
| |
| # result is in ~/rpmbuild/RPMS/noarch/ |
| for root, dirs, files in os.walk( |
| os.path.join(os.getenv("HOME"), "rpmbuild", "RPMS", "noarch") |
| ): |
| for f in files: |
| if f.startswith(package) and f.endswith(".rpm") and v in f: |
| return os.path.join(root, f) |
| raise FileNotFoundError("RPM package not found") |
| |
| |
| def parse_args(): |
| parser = argparse.ArgumentParser("Build upstream packages using Jinja2 templates") |
| parser.add_argument("--deb", help="Build DEB package", action="store_true") |
| parser.add_argument("--rpm", help="Build RPM package", action="store_true") |
| parser.add_argument("--debug", help="Enable debug output", action="store_true") |
| args = parser.parse_args() |
| |
| if not (args.rpm or args.deb) or (args.rpm and args.deb): |
| parser.print_help() |
| sys.exit(1) |
| |
| return args |
| |
| |
| if __name__ == "__main__": |
| args = parse_args() |
| |
| package = "linux-firmware-upstream" |
| tmpdir, builddir, fwdir, targetdir = prep_tree(package) |
| |
| try: |
| if args.deb: |
| result = build_deb_package(package, builddir) |
| elif args.rpm: |
| result = build_rpm_package(package, builddir) |
| shutil.copy(os.path.join(builddir, result), targetdir) |
| print( |
| "Built package: {}".format( |
| os.path.join(targetdir, os.path.basename(result)) |
| ) |
| ) |
| finally: |
| if not args.debug: |
| shutil.rmtree(tmpdir) |