diff options
Diffstat (limited to 'py-nuitka-build')
| -rwxr-xr-x | py-nuitka-build | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/py-nuitka-build b/py-nuitka-build new file mode 100755 index 0000000..3b14427 --- /dev/null +++ b/py-nuitka-build @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# +# Nuitka Build Helper Script +# +# Compiles Python scripts into standalone executables using Nuitka with +# dependency management via uv. + +set -euo pipefail + +_parse_dependecies() { + cat <<EOF | python3 - "$1" +import platform +import re +import sys +import tomllib + +REGEX = r"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$" + + +def read(script: str) -> dict | None: + name = "script" + matches = list(filter(lambda m: m.group("type") == name, re.finditer(REGEX, script))) + if len(matches) > 1: + raise ValueError(f"Multiple {name} blocks found") + elif len(matches) == 1: + content = "".join( + line[2:] if line.startswith("# ") else line[1:] + for line in matches[0].group("content").splitlines(keepends=True) + ) + return tomllib.loads(content) + else: + return {} + + +with open(sys.argv[1], "r") as fd: + script = fd.read() + metadata = read(script) + python_version = metadata.get("requires-python", platform.python_version()) + dependencies = metadata.get("dependencies", []) + print(python_version) + if dependencies: + print("\n".join(dependencies)) +EOF +} + +main() { + + if [[ $# -ne 1 ]]; then + echo "Usage: $0 <python_script.py>" >&2 + exit 1 + fi + + local script="$1" + + if [[ ! -f "$script" ]]; then + echo "Error: Script '$script' not found" >&2 + exit 2 + fi + + { + local python_version + local -a dependencies=() + IFS= read -r python_version + readarray -t dependencies + + local cmd=(uv run) + cmd+=(--python "$python_version") + for dependency in "${dependencies[@]}"; do + cmd+=(--with "$dependency") + done + + cmd+=(--with 'Nuitka[onefile]') + cmd+=(python -m nuitka --standalone --onefile "$script") + + "${cmd[@]}" + } < <(_parse_dependecies "$script") + +} + +main "$@" |
