# ©AngelaMos | 2026 # justfile # # A "justfile" is a list of commands you can run with `just `. # Think of it as a project's command center — instead of remembering # `uv run pytest -v`, you just type `just test`. # # Why use just instead of make? It is simpler, cross-platform, # and the syntax is easier to read. # # Show all commands: `just` # Run a command: `just ` (e.g. `just setup`) # Export every variable defined here as an environment variable for # the recipes that just runs. set export # On Linux/macOS, run recipe lines with bash and -u (error on # unset variables) and -c (read commands from a string). set shell := ["bash", "-uc"] # On Windows, fall back to PowerShell with no logo / non-interactive. set windows-shell := ["powershell.exe", "-NoLogo", "-Command"] # Make recipe arguments available to shebang scripts as `$1`, `$2`, # `$@`, and `$#`. Without this, shebang recipes only see args via the # textual `{{args}}` substitution, which is unsafe for inputs that # contain `$` (the substituted text gets re-expanded by bash). set positional-arguments # Show available commands when you run `just` with no args. default: @just --list --unsorted # ============================================================================= # Setup Commands # ============================================================================= # One-shot first-time setup — creates .venv and installs everything [group('setup')] setup: @echo "Creating virtual environment with uv..." # uv venv creates a .venv/ folder using the system Python that # matches `requires-python` in pyproject.toml. # --allow-existing makes the recipe safe to re-run after a partial install. uv venv --allow-existing @echo "" @echo "Installing dependencies (including dev tools)..." # --all-extras pulls in every optional-dependencies group (just `dev` # for us). Without this, dev tools like pytest do not get installed. uv sync --all-extras @echo "" @echo "✓ Setup complete!" @echo "" @echo "Try it out:" @echo " just run 5f4dcc3b5aa765d61d8327deb882cf99" @echo " just test" # Install runtime dependencies only (no dev tools) [group('setup')] install: uv sync # Install runtime + dev dependencies [group('setup')] install-dev: uv sync --all-extras # ============================================================================= # Testing & Quality Checks # ============================================================================= # Run the test suite [group('test')] test: @echo "Running tests..." # `uv run` runs a command inside the project's virtual environment # without us having to `source .venv/bin/activate` first. uv run pytest # Run all linters in sequence (ruff + pylint + mypy) [group('test')] lint: @echo "=== Ruff ===" uv run ruff check hash_identifier.py test_hash_identifier.py @echo "" @echo "=== Pylint ===" uv run pylint hash_identifier.py @echo "" @echo "=== Mypy ===" uv run mypy hash_identifier.py @echo "" @echo "✓ All linters passed" # Auto-format every Python file with yapf [group('test')] format: @echo "Formatting code with yapf..." # -i = in place. Edits the files directly instead of printing diffs. uv run yapf -i hash_identifier.py test_hash_identifier.py @echo "✓ Code formatted" # Auto-fix what ruff can fix on its own (unused imports, etc.) [group('test')] fix: uv run ruff check hash_identifier.py test_hash_identifier.py --fix # ============================================================================= # Run the CLI # ============================================================================= # Run hashid — pass the hash to identify after `--` # Example: just run 5f4dcc3b5aa765d61d8327deb882cf99 # just run '$2b$12$abcdefghijklmnopqrstuv' # [no-exit-message] silences just's "Recipe `run` failed with exit # code N" line when hashid exits non-zero. hashid uses exit 1 to mean # "no candidates matched" — a legitimate result, not a failure. The # exit code itself is still propagated to whoever invoked just, so # CI use cases keep working. [group('run')] [no-exit-message] run *args: #!/usr/bin/env bash # If no args were given, print a friendly usage block and exit # cleanly. Without this, `just run` (no args) would invoke # `uv run hashid` with nothing, argparse would exit 2, and just # would tack a "Recipe `run` failed" error on top — confusing for # someone just trying to see how the command works. if [ $# -eq 0 ]; then cat <<'EOF' Usage: just run -- Examples: just run -- 5f4dcc3b5aa765d61d8327deb882cf99 just run -- '$2b$12$abcdefghijklmnopqrstuv' See all options: just run -- --help EOF exit 0 fi # Forward args via "$@" — NOT via {{args}}. Why: {{args}} is a # TEXTUAL substitution done by just before bash runs the script, # so a hash like $2b$12$abc would get its $2b and $12 expanded as # bash variables and arrive at hashid mangled. "$@" hands bash the # original argv unchanged. uv run hashid "$@" # ============================================================================= # Utility / Cleanup # ============================================================================= # Delete the venv and all build / cache artifacts [group('utility')] clean: rm -rf .venv rm -rf __pycache__ rm -rf .mypy_cache .ruff_cache .pytest_cache rm -rf *.egg-info build dist rm -rf .coverage htmlcov @echo "✓ Cleaned" # Lock the exact dependency versions to uv.lock [group('utility')] lock: uv lock # Upgrade all dependencies to latest allowed versions [group('utility')] update: uv lock --upgrade uv sync --all-extras # ============================================================================= # CI Pipeline # ============================================================================= # Full pipeline: setup + lint + test. For first-time runs. [group('ci')] all: setup lint test @echo "" @echo "✓ Setup, lint, and tests all passed" # Lint + test only — what CI runs after dependencies are installed [group('ci')] ci: lint test @echo "✓ CI checks passed"