Files
semios-packages/x.py
T
2026-06-28 16:31:35 +08:00

163 lines
4.4 KiB
Python

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)