import argparse import importlib import os import shutil import sys import typing import hooks import lib.arch import lib.make import lib.pkgcomposer import lib.sources os.chdir(os.path.dirname(__file__)) sys.path.append(os.path.abspath("lib")) argparser = argparse.ArgumentParser( description="SemiOS source package repository helper" ) argparser.add_argument( "--target", type=str, help="Target architecture to build the package for" ) subparsers = argparser.add_subparsers(dest="subcommand") parser_build = subparsers.add_parser("build") parser_build.add_argument("BUILD_PKGNAME") parser_clean = subparsers.add_parser("clean") parser_clean.add_argument("CLEAN_PKGNAME") parser_list = subparsers.add_parser("list") parser_list.add_argument("ITEM", choices=("all", "built", "new")) args = argparser.parse_args() if args.target: lib.arch.set_target(args.target) else: lib.arch.set_target(lib.arch.get_target()) def run_hooks(map, arg: typing.Any = None): current_dir = os.getcwd() for n in map.keys(): if n in lib.make._blocked_hooks: continue if arg: map[n](arg) else: map[n]() os.chdir(current_dir) def run_build_package(package: str): try: os.chdir(f"packages/{package}") os.makedirs("target", exist_ok=True) except Exception: print(f"No such package {package}") exit(1) package_dir = os.getcwd() importlib.import_module(f"packages.{package}.pkgbuild") # Check architecture support if not lib.make._supported_arch(lib.arch.get_target()): print(f"Architecture {lib.arch.get_target()} is not supported for this package") exit(1) # Run `pre_build` hooks run_hooks(hooks.pre_build) # Build the package if lib.make._on_build: os.chdir(lib.sources.sources_dir_name()) lib.make._on_build() else: print("on_build(): Not defined") # Run `post_build` hooks run_hooks(hooks.post_build) # Pack packages for pkgname in lib.make._pkginfo.keys(): lib.make._current_pkgname = pkgname if pkgname == lib.make._key_global: continue pkginfo = lib.make._pkginfo[pkgname] pkgver = pkginfo[lib.make._key_version] if pkginfo.get(lib.make._key_arch_any): pkgarch = "any" else: pkgarch = lib.arch.get_target() pkgfilename = f"{pkgname}={pkgver}@{pkgarch}" composer = lib.pkgcomposer.PkgComposer( f"{package_dir}/target/{pkgfilename}.pkg" ) composer.setworkdir(f"{package_dir}/target/{pkgfilename}") pkginfo[lib.make._key_on_pack](composer) # Run post_pack hooks run_hooks(hooks.post_pack, composer) manifest = { "name": pkgname, "version": pkgver, "arch": pkgarch, "dependencies": pkginfo[lib.make._key_dependencies], "provides": pkginfo[lib.make._key_provides], } composer.write_manifest(manifest) composer.write_links(pkginfo[lib.make._key_links]) composer.compose() # Build success with open(f"{package_dir}/target/build-ok.tag", "wt+") as file: file.write("OK") def run_clean_package(package: str): try: shutil.rmtree(f"packages/{package}/target") except Exception: pass def run_list(item): if item == "all": for i in os.listdir("packages"): if i.startswith("."): continue print(i) elif item == "built": for i in os.listdir("packages"): if i.startswith("."): continue if os.path.exists(f"packages/{i}/target/build-ok.tag"): print(i) elif item == "new": for i in os.listdir("packages"): if i.startswith("."): continue try: pkgbuild_mtime = os.path.getmtime(f"packages/{i}/pkgbuild.py") target_mtime = os.path.getmtime(f"packages/{i}/target/build-ok.tag") if target_mtime < pkgbuild_mtime: print(i) except Exception: print(i) if args.subcommand == "build": run_build_package(args.BUILD_PKGNAME) elif args.subcommand == "clean": run_clean_package(args.CLEAN_PKGNAME) elif args.subcommand == "list": run_list(args.ITEM) else: print("error: no action specified", file=sys.stderr) exit(1)