diff --git a/.github/scripts/book.sh b/.github/scripts/book.sh new file mode 100755 index 00000000..761ee072 --- /dev/null +++ b/.github/scripts/book.sh @@ -0,0 +1,81 @@ +#!/bin/sh +# Assemble the combined documentation site into _book +# - Copies API docs (pdoc), coverage, test report, and marimushka exports +# - Generates a links.json consumed by minibook +# +# This script mirrors the logic previously embedded in the Makefile `book` target +# for maintainability and testability. It is POSIX-sh compatible. + +set -e + +BLUE="\033[36m" +YELLOW="\033[33m" +RESET="\033[0m" + +printf "%b[INFO] Building combined documentation...%b\n" "$BLUE" "$RESET" +printf "%b[INFO] Assembling book...%b\n" "$BLUE" "$RESET" + +printf "%b[INFO] Delete the _book folder...%b\n" "$BLUE" "$RESET" +rm -rf _book +printf "%b[INFO] Create empty _book folder...%b\n" "$BLUE" "$RESET" +mkdir -p _book + +# Start building links.json content without jq +LINKS_ENTRIES="" + +#printf "%b[INFO] Copy API docs...%b\n" "$BLUE" "$RESET" +#if [ -f _pdoc/index.html ]; then +# mkdir -p _book/pdoc +# cp -r _pdoc/* _book/pdoc +# LINKS_ENTRIES='"API": "./pdoc/index.html"' +#fi + +printf "%b[INFO] Copy coverage report...%b\n" "$BLUE" "$RESET" +if [ -f _tests/html-coverage/index.html ]; then + mkdir -p _book/tests/html-coverage + cp -r _tests/html-coverage/* _book/tests/html-coverage + #if [ -n "$LINKS_ENTRIES" ]; then + # LINKS_ENTRIES="$LINKS_ENTRIES, \"Coverage\": \"./tests/html-coverage/index.html\"" + #else + LINKS_ENTRIES='"Coverage": "./tests/html-coverage/index.html"' + #fi +else + printf "%b[WARN] No coverage report found or directory is empty%b\n" "$YELLOW" "$RESET" +fi + +printf "%b[INFO] Copy test report...%b\n" "$BLUE" "$RESET" +if [ -f _tests/html-report/report.html ]; then + mkdir -p _book/tests/html-report + cp -r _tests/html-report/* _book/tests/html-report + if [ -n "$LINKS_ENTRIES" ]; then + LINKS_ENTRIES="$LINKS_ENTRIES, \"Test Report\": \"./tests/html-report/report.html\"" + else + LINKS_ENTRIES='"Test Report": "./tests/html-report/report.html"' + fi +else + printf "%b[WARN] No test report found or directory is empty%b\n" "$YELLOW" "$RESET" +fi + +#printf "%b[INFO] Copy notebooks...%b\n" "$BLUE" "$RESET" +#if [ -f _marimushka/index.html ]; then +# mkdir -p _book/marimushka +# cp -r _marimushka/* _book/marimushka +# if [ -n "$LINKS_ENTRIES" ]; then +# LINKS_ENTRIES="$LINKS_ENTRIES, \"Notebooks\": \"./marimushka/index.html\"" +# else +# LINKS_ENTRIES='"Notebooks": "./marimushka/index.html"' +# fi +# printf "%b[INFO] Copied notebooks into _book/marimushka%b\n" "$BLUE" "$RESET" +#else +# printf "%b[WARN] No notebooks found or directory is empty%b\n" "$YELLOW" "$RESET" +#fi + +# Write final links.json +if [ -n "$LINKS_ENTRIES" ]; then + printf '{%s}\n' "$LINKS_ENTRIES" > _book/links.json +else + printf '{}\n' > _book/links.json +fi + +printf "%b[INFO] Generated links.json:%b\n" "$BLUE" "$RESET" +cat _book/links.json diff --git a/.gitignore b/.gitignore index 4b974123..933b4afc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,9 @@ build sandbox .DS_Store -tests/dockerfiles/ +_tests +_book + .tox/ docs/_build/ media/logo_design/ diff --git a/Makefile b/Makefile index dd22c0e0..39522056 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ RESET := \033[0m .PHONY: install install-uv test fmt UV_INSTALL_DIR := ./bin +TESTS_FOLDER := tests +SOURCE_FOLDER := pypfopt ##@ Bootstrap install-uv: ## ensure uv (and uvx) are installed locally @@ -33,13 +35,29 @@ install-uv: ## ensure uv (and uvx) are installed locally fi install: install-uv ## install - @printf "${BLUE}[INFO] Creating virtual environment...${RESET}\n" - # Create the virtual environment - @./bin/uv venv --python 3.12 || { printf "${RED}[ERROR] Failed to create virtual environment${RESET}\n"; exit 1; } - @printf "${BLUE}[INFO] Installing dependencies${RESET}\n" + # Create the virtual environment only if it doesn't exist + @if [ ! -d ".venv" ]; then \ + ./bin/uv venv --python 3.12 || { printf "${RED}[ERROR] Failed to create virtual environment${RESET}\n"; exit 1; }; \ + else \ + printf "${BLUE}[INFO] Using existing virtual environment at .venv, skipping creation${RESET}\n"; \ + fi + + # Install the dependencies from pyproject.toml @./bin/uv sync --all-extras --frozen || { printf "${RED}[ERROR] Failed to install dependencies${RESET}\n"; exit 1; } +clean: ## clean + @printf "${BLUE}Cleaning project...${RESET}\n" + # do not clean .env files + @git clean -d -X -f -e .env -e '.env.*' + @rm -rf dist build *.egg-info .coverage .pytest_cache + @printf "${BLUE}Removing local branches with no remote counterpart...${RESET}\n" + @git fetch --prune + @git branch -vv \ + | grep ': gone]' \ + | awk '{print $1}' \ + | xargs -r git branch -D 2>/dev/null || true + ##@ Development and Testing test: install ## run all tests @printf "${BLUE}[INFO] Running tests...${RESET}\n" @@ -49,7 +67,15 @@ test: install ## run all tests fmt: install-uv ## check the pre-commit hooks and the linting @./bin/uvx pre-commit run --all-files - @./bin/uvx deptry . + +deptry: install-uv ## run deptry if pyproject.toml exists + @./bin/uvx deptry "${SOURCE_FOLDER}" + +##@ Documentation +book: test ## compile the companion book + @/bin/sh .github/scripts/book.sh + @./bin/uvx minibook --title "${BOOK_TITLE}" --subtitle "${BOOK_SUBTITLE}" --links "$$(python3 -c 'import json,sys; print(json.dumps(json.load(open("_book/links.json"))))')" --output "_book" + @touch "_book/.nojekyll" ##@ Meta help: ## Display this help message