385 lines
11 KiB
Plaintext
385 lines
11 KiB
Plaintext
# ©AngelaMos | 2026
|
|
# justfile.example
|
|
#
|
|
# Annotated justfile template for Cybersecurity-Projects.
|
|
# Copy into your project root, rename to `justfile`, and replace
|
|
# every <PLACEHOLDER> with your actual values. Delete sections
|
|
# that don't apply to your project's stack.
|
|
#
|
|
# Docs: https://just.systems/man/en/
|
|
# Cheat: https://cheatography.com/linux-china/cheat-sheets/justfile/
|
|
#
|
|
# Install just:
|
|
# cargo install just (from source)
|
|
# brew install just (macOS)
|
|
# apt install just (Debian/Ubuntu 24.04+)
|
|
# pipx install rust-just (via pipx)
|
|
#
|
|
# Usage:
|
|
# just list all available recipes
|
|
# just <recipe> run a recipe
|
|
# just -n <recipe> dry-run (print commands without executing)
|
|
|
|
|
|
# ── Settings ──────────────────────────────────────────────────────────────────
|
|
# These apply globally to every recipe in the file.
|
|
|
|
# Load .env file into environment for all recipes.
|
|
set dotenv-load
|
|
|
|
# Export all `just` variables as environment variables to child processes.
|
|
set export
|
|
|
|
# Use bash in strict mode (-u = error on unset vars, -c = command string).
|
|
# This gives consistent behavior across macOS/Linux regardless of login shell.
|
|
set shell := ["bash", "-uc"]
|
|
|
|
# Windows equivalent (only takes effect on Windows, ignored elsewhere).
|
|
set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]
|
|
|
|
|
|
# ── Variables ─────────────────────────────────────────────────────────────────
|
|
# Variables defined here are available in all recipes via {{name}}.
|
|
# Backtick expressions run shell commands at parse time.
|
|
|
|
project := file_name(justfile_directory())
|
|
version := `git describe --tags --always 2>/dev/null || echo "dev"`
|
|
|
|
# Project-specific paths — change these to match your layout.
|
|
# Python-only project: src_dir := "src"
|
|
# Fullstack project: src_dir := "backend/src"
|
|
src_dir := "<src>"
|
|
test_dir := "<tests>"
|
|
package := "<package-name>"
|
|
|
|
|
|
# ── Default ───────────────────────────────────────────────────────────────────
|
|
# The first recipe is the default (runs when you type `just` with no args).
|
|
# --unsorted preserves the order defined in this file instead of alphabetizing.
|
|
|
|
default:
|
|
@just --list --unsorted
|
|
|
|
|
|
# =============================================================================
|
|
# Linting and Formatting
|
|
# =============================================================================
|
|
# Ruff handles both linting and formatting for Python.
|
|
# `*ARGS` is a variadic parameter — any extra flags you pass get forwarded.
|
|
# Example: just ruff --fix
|
|
|
|
[group('lint')]
|
|
ruff *ARGS:
|
|
ruff check {{src_dir}}/ {{test_dir}}/ {{ARGS}}
|
|
|
|
[group('lint')]
|
|
ruff-fix:
|
|
ruff check {{src_dir}}/ {{test_dir}}/ --fix
|
|
ruff format {{src_dir}}/ {{test_dir}}/
|
|
|
|
[group('lint')]
|
|
ruff-format:
|
|
ruff format {{src_dir}}/ {{test_dir}}/
|
|
|
|
[group('lint')]
|
|
pylint *ARGS:
|
|
pylint {{src_dir}}/{{package}} {{ARGS}}
|
|
|
|
# Dependency recipes — `lint` runs `ruff` then `pylint` in order.
|
|
[group('lint')]
|
|
lint: ruff pylint
|
|
|
|
|
|
# =============================================================================
|
|
# Frontend Linting (delete this section for Python-only projects)
|
|
# =============================================================================
|
|
# Biome is an all-in-one linter/formatter for JS/TS (replaces ESLint+Prettier).
|
|
# Alternatives: eslint + prettier (shown commented below)
|
|
|
|
[group('frontend')]
|
|
biome *ARGS:
|
|
cd frontend && pnpm biome check . {{ARGS}}
|
|
|
|
[group('frontend')]
|
|
biome-fix:
|
|
cd frontend && pnpm biome check --write .
|
|
|
|
[group('frontend')]
|
|
stylelint *ARGS:
|
|
cd frontend && pnpm stylelint '**/*.scss' {{ARGS}}
|
|
|
|
[group('frontend')]
|
|
stylelint-fix:
|
|
cd frontend && pnpm stylelint '**/*.scss' --fix
|
|
|
|
[group('frontend')]
|
|
tsc *ARGS:
|
|
cd frontend && pnpm tsc --noEmit {{ARGS}}
|
|
|
|
# Alternative: ESLint + Prettier (uncomment if not using Biome)
|
|
# [group('frontend')]
|
|
# eslint *ARGS:
|
|
# cd frontend && pnpm eslint . {{ARGS}}
|
|
#
|
|
# [group('frontend')]
|
|
# eslint-fix:
|
|
# cd frontend && pnpm eslint . --fix
|
|
#
|
|
# [group('frontend')]
|
|
# prettier *ARGS:
|
|
# cd frontend && pnpm prettier --check "src/**/*.{ts,tsx,css}" {{ARGS}}
|
|
#
|
|
# [group('frontend')]
|
|
# prettier-fix:
|
|
# cd frontend && pnpm prettier --write "src/**/*.{ts,tsx,css}"
|
|
|
|
|
|
# =============================================================================
|
|
# Type Checking
|
|
# =============================================================================
|
|
|
|
[group('types')]
|
|
mypy *ARGS:
|
|
mypy {{src_dir}}/ {{ARGS}}
|
|
|
|
# ty is Astral's experimental type checker (fast, Rust-based).
|
|
# Uncomment if your project uses it.
|
|
# [group('types')]
|
|
# ty *ARGS:
|
|
# ty check {{ARGS}}
|
|
|
|
[group('types')]
|
|
typecheck: mypy
|
|
|
|
|
|
# =============================================================================
|
|
# Testing
|
|
# =============================================================================
|
|
|
|
[group('test')]
|
|
pytest *ARGS:
|
|
pytest {{test_dir}}/ {{ARGS}}
|
|
|
|
[group('test')]
|
|
test: pytest
|
|
|
|
[group('test')]
|
|
test-cov:
|
|
pytest {{test_dir}}/ --cov={{src_dir}}/{{package}} --cov-report=term-missing --cov-report=html
|
|
|
|
|
|
# =============================================================================
|
|
# CI / Quality
|
|
# =============================================================================
|
|
# Composite recipes that chain multiple checks.
|
|
# `ci` is the full pipeline; `check` is the fast subset (no tests).
|
|
|
|
[group('ci')]
|
|
ci: lint typecheck test
|
|
|
|
[group('ci')]
|
|
check: ruff mypy
|
|
|
|
|
|
# =============================================================================
|
|
# Docker Compose — Production (delete if no Docker)
|
|
# =============================================================================
|
|
# These wrap `docker compose` (compose.yml).
|
|
# Default params use `service='backend'` syntax — overridable at call site.
|
|
|
|
[group('docker')]
|
|
up *ARGS:
|
|
docker compose up {{ARGS}}
|
|
|
|
[group('docker')]
|
|
start *ARGS:
|
|
docker compose up -d {{ARGS}}
|
|
|
|
[group('docker')]
|
|
down *ARGS:
|
|
docker compose down {{ARGS}}
|
|
|
|
[group('docker')]
|
|
stop:
|
|
docker compose stop
|
|
|
|
[group('docker')]
|
|
build *ARGS:
|
|
docker compose build {{ARGS}}
|
|
|
|
[group('docker')]
|
|
rebuild:
|
|
docker compose build --no-cache
|
|
|
|
[group('docker')]
|
|
logs *SERVICE:
|
|
docker compose logs -f {{SERVICE}}
|
|
|
|
[group('docker')]
|
|
ps:
|
|
docker compose ps
|
|
|
|
[group('docker')]
|
|
shell service='backend':
|
|
docker compose exec -it {{service}} /bin/bash
|
|
|
|
|
|
# =============================================================================
|
|
# Docker Compose — Dev (delete if no Docker)
|
|
# =============================================================================
|
|
# Same commands but targeting dev.compose.yml.
|
|
|
|
[group('dev')]
|
|
dev-up *ARGS:
|
|
docker compose -f dev.compose.yml up {{ARGS}}
|
|
|
|
[group('dev')]
|
|
dev-start *ARGS:
|
|
docker compose -f dev.compose.yml up -d {{ARGS}}
|
|
|
|
[group('dev')]
|
|
dev-down *ARGS:
|
|
docker compose -f dev.compose.yml down {{ARGS}}
|
|
|
|
[group('dev')]
|
|
dev-stop:
|
|
docker compose -f dev.compose.yml stop
|
|
|
|
[group('dev')]
|
|
dev-build *ARGS:
|
|
docker compose -f dev.compose.yml build {{ARGS}}
|
|
|
|
[group('dev')]
|
|
dev-rebuild:
|
|
docker compose -f dev.compose.yml build --no-cache
|
|
|
|
[group('dev')]
|
|
dev-logs *SERVICE:
|
|
docker compose -f dev.compose.yml logs -f {{SERVICE}}
|
|
|
|
[group('dev')]
|
|
dev-ps:
|
|
docker compose -f dev.compose.yml ps
|
|
|
|
[group('dev')]
|
|
dev-shell service='backend':
|
|
docker compose -f dev.compose.yml exec -it {{service}} /bin/bash
|
|
|
|
|
|
# =============================================================================
|
|
# Database — Docker (delete if no database)
|
|
# =============================================================================
|
|
# Alembic migrations executed inside the running backend container.
|
|
|
|
[group('db')]
|
|
migrate *ARGS:
|
|
docker compose exec backend alembic upgrade {{ARGS}}
|
|
|
|
[group('db')]
|
|
migration message:
|
|
docker compose exec backend alembic revision --autogenerate -m "{{message}}"
|
|
|
|
[group('db')]
|
|
rollback:
|
|
docker compose exec backend alembic downgrade -1
|
|
|
|
[group('db')]
|
|
db-history:
|
|
docker compose exec backend alembic history --verbose
|
|
|
|
[group('db')]
|
|
db-current:
|
|
docker compose exec backend alembic current
|
|
|
|
|
|
# =============================================================================
|
|
# Database — Local (no Docker) (delete if no database)
|
|
# =============================================================================
|
|
|
|
[group('db-local')]
|
|
migrate-local *ARGS:
|
|
cd backend && uv run alembic upgrade {{ARGS}}
|
|
|
|
[group('db-local')]
|
|
migration-local message:
|
|
cd backend && uv run alembic revision --autogenerate -m "{{message}}"
|
|
|
|
[group('db-local')]
|
|
rollback-local:
|
|
cd backend && uv run alembic downgrade -1
|
|
|
|
[group('db-local')]
|
|
db-history-local:
|
|
cd backend && uv run alembic history --verbose
|
|
|
|
[group('db-local')]
|
|
db-current-local:
|
|
cd backend && uv run alembic current
|
|
|
|
|
|
# =============================================================================
|
|
# Setup
|
|
# =============================================================================
|
|
# First-time project bootstrap. For fullstack projects, chain sub-recipes.
|
|
|
|
[group('setup')]
|
|
setup:
|
|
@echo "Setting up development environment..."
|
|
uv sync --all-extras
|
|
@echo "Setup complete!"
|
|
|
|
# Fullstack alternative (uncomment and replace the simple setup above):
|
|
# [group('setup')]
|
|
# setup: setup-backend setup-frontend env
|
|
# @echo "Setup complete!"
|
|
#
|
|
# [group('setup')]
|
|
# setup-backend:
|
|
# @echo "Setting up backend..."
|
|
# cd backend && uv sync
|
|
# @echo "Backend ready!"
|
|
#
|
|
# [group('setup')]
|
|
# setup-frontend:
|
|
# @echo "Setting up frontend..."
|
|
# cd frontend && pnpm install
|
|
# @echo "Frontend ready!"
|
|
#
|
|
# [group('setup')]
|
|
# env:
|
|
# @if [ ! -f .env ]; then cp .env.example .env; echo "Created .env from .env.example"; fi
|
|
# @echo ".env ready — update with your values."
|
|
|
|
|
|
# =============================================================================
|
|
# Utilities
|
|
# =============================================================================
|
|
|
|
[group('util')]
|
|
info:
|
|
@echo "Project: {{project}}"
|
|
@echo "Version: {{version}}"
|
|
@echo "OS: {{os()}} ({{arch()}})"
|
|
|
|
# The `-` prefix ignores errors (e.g., dir doesn't exist). Keeps going.
|
|
[group('util')]
|
|
clean:
|
|
-rm -rf .mypy_cache
|
|
-rm -rf .pytest_cache
|
|
-rm -rf .ruff_cache
|
|
-rm -rf htmlcov
|
|
-rm -f .coverage
|
|
-rm -rf dist
|
|
-rm -rf build
|
|
@echo "Cache directories cleaned"
|
|
|
|
# [confirm(...)] prompts for Y/n before running — safety net for destructive ops.
|
|
[group('util')]
|
|
[confirm("Remove all build artifacts, caches, and virtual environment?")]
|
|
nuke:
|
|
@echo "Nuking everything..."
|
|
-rm -rf .mypy_cache .pytest_cache .ruff_cache htmlcov dist build
|
|
-rm -f .coverage
|
|
-rm -rf .venv
|
|
@echo "Nuke complete!"
|