From 712b91ccb3864bfd6874b35aa2886dba63d35cb3 Mon Sep 17 00:00:00 2001 From: abel <67806187+theo-abel@users.noreply.github.com> Date: Tue, 10 Mar 2026 12:50:16 +0100 Subject: [PATCH] feat(makefile): add module build targets and helper scripts Split module image build into build-modules-sdk and build-modules-images; build-modules now depends on both. Factor container engine detection and version parsing into scripts/container-env.sh and scripts/pyproject-version.sh respectively. Add Makefile variables for SDK/module paths and image naming, update help output, and simplify clean target to remove common caches and .pyc files. --- Makefile | 75 +++++++++++++++++------------------- scripts/container-env.sh | 19 +++++++++ scripts/pyproject-version.sh | 12 ++++++ 3 files changed, 66 insertions(+), 40 deletions(-) create mode 100755 scripts/container-env.sh create mode 100755 scripts/pyproject-version.sh diff --git a/Makefile b/Makefile index cf70228..215099a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,14 @@ -.PHONY: help install sync format lint typecheck test build-modules clean +.PHONY: help install sync format lint typecheck test build-modules build-modules-sdk build-modules-images clean SHELL := /bin/bash +# Container image configuration +SDK_DIR := fuzzforge-modules/fuzzforge-modules-sdk/ +MODULE_TEMPLATE := fuzzforge-modules/fuzzforge-module-template/ +SDK_VERSION := $(shell scripts/pyproject-version.sh $(SDK_DIR)pyproject.toml) +BASE_IMG_PREFIX := $(if $(filter podman,$(FUZZFORGE_ENGINE)),localhost/,) +SDK_IMG := $(BASE_IMG_PREFIX)fuzzforge-modules-sdk:$(SDK_VERSION) + # Default target help: @echo "FuzzForge OSS Development Commands" @@ -13,6 +20,8 @@ help: @echo " make typecheck - Type check with mypy" @echo " make test - Run all tests" @echo " make build-modules - Build all module container images" + @echo " make build-modules-sdk - Build the SDK base image" + @echo " make build-modules-images - Build all module images (requires SDK image)" @echo " make clean - Clean build artifacts" @echo "" @@ -64,54 +73,40 @@ test: fi \ done -# Build all module container images +# Build all module container images (SDK first, then modules) # Uses Docker by default, or Podman if FUZZFORGE_ENGINE=podman -build-modules: - @echo "Building FuzzForge module images..." - @if [ "$$FUZZFORGE_ENGINE" = "podman" ]; then \ - if [ -n "$$SNAP" ]; then \ - echo "Using Podman with isolated storage (Snap detected)"; \ - CONTAINER_CMD="podman --root ~/.fuzzforge/containers/storage --runroot ~/.fuzzforge/containers/run"; \ - else \ - echo "Using Podman"; \ - CONTAINER_CMD="podman"; \ - fi; \ - BASE_IMG_PREFIX="localhost/"; \ - else \ - echo "Using Docker"; \ - CONTAINER_CMD="docker"; \ - BASE_IMG_PREFIX=""; \ - fi; \ - SDK_DIR="fuzzforge-modules/fuzzforge-modules-sdk/"; \ - SDK_VERSION=$$(grep -m1 '^version\s*=' "$${SDK_DIR}pyproject.toml" 2>/dev/null | sed 's/^version\s*=\s*//;s/"//g;s/\s*$$//' ); \ - [ -n "$$SDK_VERSION" ] || SDK_VERSION="0.0.1"; \ +build-modules: build-modules-sdk build-modules-images + @echo "" + @echo "✓ All modules built successfully!" + +# Build the SDK base image (also builds its Python wheel) +build-modules-sdk: + @source scripts/container-env.sh; \ echo "Building wheels for fuzzforge-modules-sdk..."; \ - (cd "$$SDK_DIR" && uv build --wheel --out-dir .wheels) || exit 1; \ - SDK_IMG="$${BASE_IMG_PREFIX}fuzzforge-modules-sdk:$$SDK_VERSION"; \ - echo "Building $$SDK_IMG..."; \ - $$CONTAINER_CMD build -t "$$SDK_IMG" "$$SDK_DIR" || exit 1; \ + (cd "$(SDK_DIR)" && uv build --wheel --out-dir .wheels) || exit 1; \ + echo "Building $(SDK_IMG)..."; \ + $$CONTAINER_CMD build -t "$(SDK_IMG)" "$(SDK_DIR)" || exit 1 + +# Build all module images (requires SDK image to exist) +build-modules-images: + @source scripts/container-env.sh; \ for module in fuzzforge-modules/*/; do \ - if [ "$$module" = "$$SDK_DIR" ] || [ "$$module" = "fuzzforge-modules/fuzzforge-module-template/" ] || [ ! -f "$$module/Dockerfile" ]; then continue; fi; \ - name=$$(basename $$module); \ - version=$$(grep -m1 '^version\s*=' "$$module/pyproject.toml" 2>/dev/null | sed 's/^version\s*=\s*//;s/"//g;s/\s*$$//'); \ - [ -n "$$version" ] || version="0.0.1"; \ + [ "$$module" = "$(SDK_DIR)" ] && continue; \ + [ "$$module" = "$(MODULE_TEMPLATE)" ] && continue; \ + [ -f "$$module/Dockerfile" ] || continue; \ + name=$$(basename "$$module"); \ + version=$$(scripts/pyproject-version.sh "$$module/pyproject.toml"); \ case $$name in \ fuzzforge-*) tag="$$name:$$version" ;; \ *) tag="fuzzforge-$$name:$$version" ;; \ esac; \ echo "Building $$tag..."; \ - $$CONTAINER_CMD build \ - --build-arg BASE_IMAGE="$$SDK_IMG" \ - -t "$$tag" "$$module" || exit 1; \ + $$CONTAINER_CMD build --build-arg BASE_IMAGE="$(SDK_IMG)" -t "$$tag" "$$module" || exit 1; \ done - @echo "" - @echo "✓ All modules built successfully!" # Clean build artifacts clean: - find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true - find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true - find . -type d -name ".mypy_cache" -exec rm -rf {} + 2>/dev/null || true - find . -type d -name ".ruff_cache" -exec rm -rf {} + 2>/dev/null || true - find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true - find . -type f -name "*.pyc" -delete 2>/dev/null || true + @for dir in __pycache__ .pytest_cache .mypy_cache .ruff_cache "*.egg-info"; do \ + find . -type d -name "$$dir" -exec rm -rf {} + 2>/dev/null || true; \ + done + @find . -type f -name "*.pyc" -delete 2>/dev/null || true diff --git a/scripts/container-env.sh b/scripts/container-env.sh new file mode 100755 index 0000000..e9fdf85 --- /dev/null +++ b/scripts/container-env.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Resolve the container engine based on FUZZFORGE_ENGINE env var. +# Usage: source scripts/container-env.sh +# Exports: CONTAINER_CMD + +if [ "${FUZZFORGE_ENGINE}" = "podman" ]; then + if [ -n "${SNAP}" ]; then + echo "Using Podman with isolated storage (Snap detected)" + CONTAINER_CMD="podman --root ~/.fuzzforge/containers/storage --runroot ~/.fuzzforge/containers/run" + else + echo "Using Podman" + CONTAINER_CMD="podman" + fi +else + echo "Using Docker" + CONTAINER_CMD="docker" +fi + +export CONTAINER_CMD diff --git a/scripts/pyproject-version.sh b/scripts/pyproject-version.sh new file mode 100755 index 0000000..0f7d941 --- /dev/null +++ b/scripts/pyproject-version.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# Extract the version from a pyproject.toml file. +# Usage: pyproject-version.sh [default] +# Prints the version string, or the default (0.0.1) if not found. + +PYPROJECT="${1:?Usage: pyproject-version.sh [default]}" +DEFAULT="${2:-0.0.1}" + +version=$(grep -m1 '^version\s*=' "${PYPROJECT}" 2>/dev/null \ + | sed 's/^version\s*=\s*//;s/"//g;s/\s*$//') + +echo "${version:-${DEFAULT}}"