CARGO ?= cargo
RUST_MSRV ?= 1.97.1
RUST_TOOLCHAIN ?= stable
DOCKER_IMAGE ?= $(shell basename $(CURDIR))
DOCKER_TAG ?= latest
GITHUB_OWNER ?= $(shell git config --get remote.origin.url | sed -E 's#(git@github.com:|https://github.com/)##; s#/.+##' | tr '[:upper:]' '[:lower:]')
DOCKER_REGISTRY ?= ghcr.io/$(if $(GITHUB_OWNER),$(GITHUB_OWNER),local)
BINARY_NAME ?= github-actions-maintainer
BINARY_PACKAGE ?=
SBOM_MANIFEST_PATH ?= Cargo.toml
PUBLISH_PACKAGES ?=
CLIPPY_FLAGS := -D warnings \
-D clippy::all \
-D clippy::pedantic \
-D clippy::nursery \
-D clippy::cargo \
-A clippy::multiple_crate_versions \
-A clippy::module_name_repetitions \
-A clippy::missing_errors_doc \
-A clippy::missing_panics_doc \
-A clippy::must_use_candidate
RED := \033[0;31m
GREEN := \033[0;32m
YELLOW := \033[0;33m
BLUE := \033[0;34m
CYAN := \033[0;36m
NC := \033[0m
.DEFAULT_GOAL := help
.PHONY: help
help:
@echo "$(CYAN)ThreatFlux Rust Project - Available Commands$(NC)"
@echo ""
@echo "$(YELLOW)Quick Start:$(NC)"
@echo " $(GREEN)make dev-setup$(NC) Install all development tools"
@echo " $(GREEN)make template-check$(NC) Validate bootstrap placeholders"
@echo " $(GREEN)make ci$(NC) Run all CI checks locally"
@echo ""
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-18s$(NC) %s\n", $$1, $$2}'
.PHONY: dev-setup
dev-setup:
@echo "$(CYAN)Installing development tools...$(NC)"
@rustup component add rustfmt clippy llvm-tools-preview 2>/dev/null || true
@cargo install cargo-llvm-cov --locked 2>/dev/null || echo "cargo-llvm-cov already installed"
@cargo install cargo-audit --locked 2>/dev/null || echo "cargo-audit already installed"
@cargo install cargo-deny --locked 2>/dev/null || echo "cargo-deny already installed"
@cargo install cargo-cyclonedx --locked 2>/dev/null || echo "cargo-cyclonedx already installed"
@cargo install cargo-hack --locked 2>/dev/null || echo "cargo-hack already installed"
@python3 -m pip install --user pre-commit 2>/dev/null || echo "pre-commit already available"
@echo "$(GREEN)Development tools installed!$(NC)"
.PHONY: install-hooks
install-hooks:
@echo "$(CYAN)Installing git hooks...$(NC)"
@mkdir -p .git/hooks
@echo '#!/bin/sh\nmake pre-commit' > .git/hooks/pre-commit
@chmod +x .git/hooks/pre-commit
@echo "$(GREEN)Git hooks installed!$(NC)"
.PHONY: build
build:
@echo "$(CYAN)Building project...$(NC)"
@$(CARGO) build --all-features
@echo "$(GREEN)Build completed!$(NC)"
.PHONY: build-release
build-release:
@echo "$(CYAN)Building release...$(NC)"
@if [ -n "$(BINARY_PACKAGE)" ]; then \
$(CARGO) build --release -p $(BINARY_PACKAGE) --bin $(BINARY_NAME) --all-features; \
else \
$(CARGO) build --release --bin $(BINARY_NAME) --all-features || $(CARGO) build --release --all-features; \
fi
@echo "$(GREEN)Release build completed!$(NC)"
.PHONY: check
check:
@echo "$(CYAN)Checking compilation...$(NC)"
@$(CARGO) check --all-features --all-targets
.PHONY: fmt
fmt:
@echo "$(CYAN)Formatting code...$(NC)"
@$(CARGO) fmt --all
@echo "$(GREEN)Formatting completed!$(NC)"
.PHONY: fmt-check
fmt-check:
@echo "$(CYAN)Checking code format...$(NC)"
@$(CARGO) fmt --all -- --check
@echo "$(GREEN)Format check passed!$(NC)"
.PHONY: lint
lint:
@echo "$(CYAN)Running clippy...$(NC)"
@$(CARGO) clippy --all-features --all-targets -- -D warnings
@echo "$(GREEN)Linting passed!$(NC)"
.PHONY: lint-strict
lint-strict:
@echo "$(CYAN)Running strict clippy...$(NC)"
@$(CARGO) clippy --all-features --all-targets -- $(CLIPPY_FLAGS)
@echo "$(GREEN)Strict linting passed!$(NC)"
.PHONY: lint-fix
lint-fix:
@echo "$(CYAN)Applying clippy fixes...$(NC)"
@$(CARGO) clippy --all-features --all-targets --fix --allow-dirty --allow-staged -- -D warnings
@echo "$(GREEN)Fixes applied!$(NC)"
.PHONY: test
test:
@echo "$(CYAN)Running tests...$(NC)"
@$(CARGO) test --all-features
@echo "$(GREEN)Tests passed!$(NC)"
.PHONY: test-verbose
test-verbose:
@echo "$(CYAN)Running tests (verbose)...$(NC)"
@$(CARGO) test --all-features -- --nocapture
.PHONY: test-doc
test-doc:
@echo "$(CYAN)Running doc tests...$(NC)"
@$(CARGO) test --doc --all-features
@echo "$(GREEN)Doc tests passed!$(NC)"
.PHONY: test-features
test-features:
@echo "$(CYAN)Testing feature combinations...$(NC)"
@echo "$(BLUE) No default features...$(NC)"
@$(CARGO) check --workspace --no-default-features
@echo "$(BLUE) All features...$(NC)"
@$(CARGO) check --workspace --all-features
@echo "$(BLUE) Default features only...$(NC)"
@$(CARGO) check --workspace
@echo "$(GREEN)Feature checks passed!$(NC)"
.PHONY: test-features-full
test-features-full:
@echo "$(CYAN)Testing full feature powerset...$(NC)"
@cargo hack check --workspace --feature-powerset --no-dev-deps
@echo "$(GREEN)Feature powerset passed!$(NC)"
.PHONY: coverage
coverage:
@echo "$(CYAN)Generating coverage...$(NC)"
@cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
@echo "$(GREEN)Coverage report: lcov.info$(NC)"
.PHONY: coverage-html
coverage-html:
@echo "$(CYAN)Generating HTML coverage...$(NC)"
@cargo llvm-cov --all-features --workspace --html
@echo "$(GREEN)Report: target/llvm-cov/html/index.html$(NC)"
.PHONY: coverage-summary
coverage-summary:
@echo "$(CYAN)Coverage summary:$(NC)"
@cargo llvm-cov --all-features --workspace --summary-only
.PHONY: audit
audit:
@echo "$(CYAN)Running security audit...$(NC)"
@cargo audit
@echo "$(GREEN)Security audit passed!$(NC)"
.PHONY: deny
deny:
@echo "$(CYAN)Running cargo-deny...$(NC)"
@cargo deny check
@echo "$(GREEN)Deny checks passed!$(NC)"
.PHONY: sbom
sbom:
@echo "$(CYAN)Generating SBOM...$(NC)"
@mkdir -p sbom
@rm -f sbom/*.json
@cargo cyclonedx --manifest-path $(SBOM_MANIFEST_PATH) --all-features --format json --spec-version 1.5 --override-filename $(BINARY_NAME)-sbom
@find . -maxdepth 4 -name '$(BINARY_NAME)-sbom.json' -exec mv {} sbom/ \;
@echo "$(GREEN)SBOM written to sbom/$(BINARY_NAME)-sbom.json$(NC)"
.PHONY: security
security: audit deny
@echo "$(GREEN)All security checks passed!$(NC)"
.PHONY: docs
docs:
@echo "$(CYAN)Building documentation...$(NC)"
@RUSTDOCFLAGS="-D warnings" $(CARGO) doc --all-features --no-deps
@echo "$(GREEN)Documentation built!$(NC)"
.PHONY: docs-open
docs-open:
@$(CARGO) doc --all-features --no-deps --open
.PHONY: bench
bench:
@echo "$(CYAN)Running benchmarks...$(NC)"
@$(CARGO) bench --all-features
.PHONY: bench-check
bench-check:
@echo "$(CYAN)Checking benchmarks...$(NC)"
@$(CARGO) bench --all-features --no-run
@echo "$(GREEN)Benchmarks compile!$(NC)"
.PHONY: msrv
msrv:
@echo "$(CYAN)Checking MSRV ($(RUST_MSRV))...$(NC)"
@rustup toolchain install $(RUST_MSRV) --profile minimal >/dev/null 2>&1 || true
@rustup run $(RUST_MSRV) cargo check --workspace --all-features
@echo "$(GREEN)MSRV check passed!$(NC)"
.PHONY: docker-build
docker-build:
@echo "$(CYAN)Building Docker image...$(NC)"
@docker build \
--build-arg BINARY_NAME=$(BINARY_NAME) \
--build-arg BINARY_PACKAGE=$(BINARY_PACKAGE) \
--build-arg SBOM_MANIFEST_PATH=$(SBOM_MANIFEST_PATH) \
-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_TAG) .
@echo "$(GREEN)Docker image built: $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_TAG)$(NC)"
.PHONY: docker-push
docker-push:
@echo "$(CYAN)Pushing Docker image...$(NC)"
@docker push $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_TAG)
@echo "$(GREEN)Docker image pushed!$(NC)"
.PHONY: pre-commit
pre-commit: fmt-check lint test-doc
.PHONY: template-check
template-check:
@echo "$(CYAN)Checking for template placeholders...$(NC)"
@python3 scripts/check_template_placeholders.py
@echo "$(GREEN)No unresolved template placeholders found!$(NC)"
.PHONY: ci
ci: template-check fmt-check lint test test-features docs security
.PHONY: ci-quick
ci-quick: template-check fmt-check lint check
.PHONY: all
all: ci coverage bench-check
.PHONY: release-check
release-check:
@echo "$(CYAN)Checking release readiness...$(NC)"
@$(CARGO) check --all-features
@$(CARGO) test --all-features
@$(CARGO) clippy --all-features --all-targets -- -D warnings
@python3 scripts/check_template_placeholders.py
@echo "$(GREEN)Release readiness checks passed!$(NC)"
.PHONY: clean
clean:
@echo "$(CYAN)Cleaning artifacts...$(NC)"
@$(CARGO) clean
@rm -rf lcov.info sbom dist
@echo "$(GREEN)Cleaned!$(NC)"
.PHONY: f l t b c
f: fmt
l: lint
t: test
b: build
c: check