From 0a71a35b44be1e436fd9a406145142c8f342d824 Mon Sep 17 00:00:00 2001 From: lordlogo2002 Date: Fri, 3 Apr 2026 17:54:14 +0200 Subject: [PATCH] Add build command and configuration loading for project compilation - Introduced `cmd_build` function to handle project compilation. - Added `load_config` function to load project configuration from Nutfile. - Implemented `prepare_build_directory` and `compile` functions in a new compiler module. - Updated `is_nut_workspace` function to accept a default path argument. --- nut/__main__.py | 22 ++++++++++++++++++++++ nut/commands/compiler.py | 35 +++++++++++++++++++++++++++++++++++ nut/commands/setup.py | 2 +- nut/config.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 nut/commands/compiler.py create mode 100644 nut/config.py diff --git a/nut/__main__.py b/nut/__main__.py index a76ba84..64984ac 100644 --- a/nut/__main__.py +++ b/nut/__main__.py @@ -1,5 +1,9 @@ from .cli import CLI + +from .config import load_config + from .commands.setup import is_nut_workspace, find_template_conflicts, copy_template_files +from .commands.compiler import compile def help_text(): return [ @@ -27,8 +31,26 @@ def main() -> int: help="Directory to initialize (default: current directory)", ).handle(cmd_init) + cli.command( + "build", + help="Compile the project", + description=( + "Compile the project according to the configuration in the Nutfile. " + ), + ).handle(cmd_build) + return cli.run() +def cmd_build(args, flags) -> int: + if not is_nut_workspace(): + print("Error: No Nutfile found. Please run 'nut init' to create a workspace.") + return 1 + + config = load_config() + compile(config) + + return 0 + def cmd_init(args, flags) -> int: dest_dir = args[0] force = flags["force"] diff --git a/nut/commands/compiler.py b/nut/commands/compiler.py new file mode 100644 index 0000000..321eff1 --- /dev/null +++ b/nut/commands/compiler.py @@ -0,0 +1,35 @@ +from nut.config import Config +from nut.paths import get_templates_path +from os import remove, makedirs, rmdir, listdir +import shutil + +def prepare_build_directory(path: str) -> None: + if path.exists(path): + if not path.isdir(path): + raise RuntimeError(f"Build path exists but is not a directory: {path}") + + for item in listdir(path): + item_path = path.join(path, item) + if path.isdir(item_path): + rmdir(item_path) + else: + remove(item_path) + else: + makedirs(path) + + builtins_path = get_templates_path() / "builtins" + if not path.exists(builtins_path): + raise RuntimeError(f"Builtins path does not exist: {builtins_path}, this should not happen, installation may be corrupted") + + shutil.copytree( + builtins_path, + path.join(path, "builtins"), + dirs_exist_ok=True + ) + +def compile(config: Config) -> None: + print("Compiling the project...") + + prepare_build_directory(config.buildFolder or "build") + + print("Compilation completed successfully.") diff --git a/nut/commands/setup.py b/nut/commands/setup.py index 930c86f..de9ff94 100644 --- a/nut/commands/setup.py +++ b/nut/commands/setup.py @@ -43,5 +43,5 @@ def copy_template_files(dest_dir: str, force: bool = False, checked: bool = Fals dirs_exist_ok=True ) -def is_nut_workspace(path: str) -> bool: +def is_nut_workspace(path: str = ".") -> bool: return os.path.isfile(os.path.join(path, "Nutfile")) diff --git a/nut/config.py b/nut/config.py new file mode 100644 index 0000000..82497fd --- /dev/null +++ b/nut/config.py @@ -0,0 +1,31 @@ +from .utils import read_yaml + +class Node: + def __init__(self, data): + for key, value in data.items(): + if isinstance(value, dict): + value = Node(value) + elif isinstance(value, list): + value = [ + Node(item) if isinstance(item, dict) else item + for item in value + ] + setattr(self, key, value) + + def __repr__(self): + return f"" + +class Config: + def __init__(self, path: str): + self.path = path + self.raw = read_yaml(path) + self.root = Node(self.raw) + + def __getattr__(self, item): + if not hasattr(self.root, item): + return None + + return getattr(self.root, item) + +def load_config(): + return Config("Nutfile")