""" Command to compile services and packages with Nuitka """
import importlib
import logging
import os.path
import subprocess
import sys
from importlib.util import find_spec
import typer
from fastiot.cli.typer_app import DEFAULT_CONTEXT_SETTINGS, extras_cmd
[docs]@extras_cmd.command(context_settings=DEFAULT_CONTEXT_SETTINGS)
def nuitka_compile(package_name: str = typer.Argument(default=None, help='The package to compile, e.g. `fastiot`'),
src_dir: str = typer.Option(default='src', help="The location of source files",
exists=True, file_okay=False),
out_dir: str = typer.Option(default='output',
help="The location for output files. It is relative to src_dir"),
install_nuitka: bool = typer.Option(default=False, help="Will try to install Nuitka using pip.")):
"""
Compiles the selected path as .so file using nuitka. Please make sure to have Nuitka installed as this is an
optional dependency.
"""
if install_nuitka:
logging.info("Trying to install Nuitka for you, please be patient!")
exit_code = subprocess.call("/usr/bin/env python3 -m pip install -U nuitka".split(), cwd=src_dir)
if exit_code != 0:
logging.warning("Failed to install Nuitka!")
try:
importlib.import_module("nuitka")
except ImportError:
logging.error("You have to install the package nuitka manually using `pip install nuitka` for this command "
"to be working or try using the option `--install-nuitka`")
sys.exit(3)
if package_name is None:
raise NameError("No package_name set.")
if not os.path.isdir(os.path.join(src_dir, package_name)):
raise FileNotFoundError(
f"The `{package_name}` could not be found in the specified source directory `{src_dir}`!")
recommended_packages = []
all_packages = [package_name]
all_packages += [p for p in recommended_packages if find_spec(p) is not None]
nuitka_options = f"--python-flag=no_site --remove-output --no-pyi-file --output-dir={out_dir} --lto=yes --module"
recurses = " ".join(["--include-package=" + x for x in all_packages])
nuitka_cmd = f"/usr/bin/env python3 -m nuitka {nuitka_options} {recurses} {package_name}"
logging.info(nuitka_cmd)
exit_code = subprocess.call(f"{nuitka_cmd}".split(), cwd=src_dir)
sys.exit(exit_code)