from invoke import task import os import shutil import sys @task def cleanbuild(c): """Clean build: fullclean and build the project""" c.run("idf.py fullclean") c.run("idf.py build") @task def build(c): """Build the project""" c.run("idf.py build") @task def flash(c): """Flash the project to device""" c.run("idf.py flash") @task def monitor(c, port="/dev/ttyUSB0"): """Monitor serial output from device""" c.run(f"idf.py monitor -p {port}") @task def run(c, port="/dev/ttyUSB0"): """Build, flash, and monitor in sequence""" build(c) flash(c) monitor(c, port) @task def clean(c): """Clean build artifacts""" c.run("idf.py fullclean") @task def config(c): """Open menuconfig to edit project settings""" c.run("idf.py menuconfig --color-scheme=monochrome", pty=True) @task def saveconfig(c): """Save current config as sdkconfig.defaults""" c.run("idf.py save-defconfig") @task def update(c): """Update project dependencies""" c.run("idf.py update-dependencies") @task def reset(c): """Reset project to clean state: remove build, config, and managed components""" if os.path.exists("sdkconfig"): os.remove("sdkconfig") if os.path.exists("sdkconfig.old"): os.remove("sdkconfig.old") if os.path.exists("build"): shutil.rmtree("build") if os.path.exists("managed_components"): shutil.rmtree("managed_components") @task def format(c): """Format all source files with clang-format, black, prettier, nixfmt, and svgo""" missing_tools = [] print("Formatting C files...") result = c.run( "find main components -name '*.c' -o -name '*.h' | xargs clang-format -i", warn=True, hide=False, ) if result.exited == 127 or (not result.ok and result.exited != 0): # Check if tool exists check = c.run("command -v clang-format", warn=True, hide=True) if not check.ok: missing_tools.append("clang-format") print("Formatting Python files...") result = c.run("black tasks.py", warn=True, hide=False) if result.exited == 127 or (not result.ok and result.exited != 0): check = c.run("command -v black", warn=True, hide=True) if not check.ok: missing_tools.append("black") print("Formatting Nix files...") result = c.run("nixfmt flake.nix", warn=True, hide=False) if result.exited == 127 or (not result.ok and result.exited != 0): check = c.run("command -v nixfmt", warn=True, hide=True) if not check.ok: missing_tools.append("nixfmt") print("Formatting SVG files...") result = c.run( "find . -name '*.svg' -not -path './build/*' -not -path './managed_components/*' | xargs -r svgo", warn=True, hide=False, ) if result.exited == 127 or (not result.ok and result.exited != 0): check = c.run("command -v svgo", warn=True, hide=True) if not check.ok: missing_tools.append("svgo") print("Formatting other files...") result = c.run( "prettier --write '**/*.{js,json,yaml,yml,md,html,css}'", warn=True, hide=False ) if result.exited == 127 or (not result.ok and result.exited != 0): check = c.run("command -v prettier", warn=True, hide=True) if not check.ok: missing_tools.append("prettier") if missing_tools: print("\n" + "=" * 60) print(f"❌ ERROR: Missing formatting tools: {', '.join(missing_tools)}") print("=" * 60) print("Please install them or reload the nix-shell.") print("=" * 60 + "\n") sys.exit(1) else: print("\n" + "=" * 60) print("✅ All files formatted successfully!") print("=" * 60 + "\n") @task def format_check(c): """Check if all files are formatted correctly""" missing_tools = [] format_errors = [] print("Checking C file formatting...") result = c.run( "find main components -name '*.c' -o -name '*.h' | xargs clang-format --dry-run --Werror", warn=True, ) if result: if result.return_code == 127: # Command not found missing_tools.append("clang-format") elif not result.ok: format_errors.append("C files") print("Checking Python file formatting...") result = c.run("black --check tasks.py", warn=True) if result: if result.return_code == 127: missing_tools.append("black") elif not result.ok: format_errors.append("Python files") print("Checking Nix file formatting...") result = c.run("nixfmt --check flake.nix", warn=True) if result: if result.return_code == 127: missing_tools.append("nixfmt") elif not result.ok: format_errors.append("Nix files") print("Checking other file formatting...") result = c.run("prettier --check '**/*.{js,json,yaml,yml,md,html,css}'", warn=True) if result: if result.return_code == 127: missing_tools.append("prettier") elif not result.ok: format_errors.append("JS/JSON/YAML/HTML/CSS files") if missing_tools: print(f"\n❌ ERROR: Missing formatting tools: {', '.join(missing_tools)}") print("Please install them or reload the nix-shell.") sys.exit(1) if format_errors: print(f"\n❌ ERROR: Formatting issues in: {', '.join(format_errors)}") print("Run 'invoke format' to fix them.") sys.exit(1) print("\n✅ All files are correctly formatted!")