CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
.PHONY: all
all: test fmt lint build
.PHONY: build
build:
cargo build
.PHONY: release
release:
cargo build --release
.PHONY: test
test:
LOGLEVEL=WARN cargo test
.PHONY: test-matrix
test-matrix:
LOGLEVEL=WARN cargo test --all-features
LOGLEVEL=WARN cargo test --no-default-features
LOGLEVEL=WARN cargo test --features non-zero
.PHONY: scan-banned
scan-banned:
@found=$$(for f in $$(find src -name '*.rs'); do \
awk -v file="$$f" '/#\[cfg\(test\)\]/ { exit } { print file ":" NR ":" $$0 }' "$$f"; \
done \
| grep -E '\.unwrap\(\)|\.expect\(' \
| grep -v -E ':[0-9]+:[[:space:]]*(///|//!|//|\*)' \
| grep -v 'scan-banned: allow' || true); \
if [ -n "$$found" ]; then \
echo "Banned patterns found in production code:"; \
echo "$$found"; \
exit 1; \
fi; \
echo "OK: no .unwrap()/.expect() in production code"
@$(MAKE) --no-print-directory scan-indexing
.PHONY: scan-indexing
scan-indexing:
cargo clippy --lib --all-features -- -D clippy::indexing_slicing
cargo clippy --lib --no-default-features -- -D clippy::indexing_slicing
cargo clippy --lib --features non-zero -- -D clippy::indexing_slicing
@echo "OK: no unchecked indexing in production code"
.PHONY: doc-check
doc-check:
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
.PHONY: readme-check
readme-check: check-cargo-readme
@cargo readme > /tmp/positive-readme-check.md
@diff -u README.md /tmp/positive-readme-check.md \
|| (echo "README.md is out of date; run 'make readme'" && exit 1)
@echo "OK: README.md matches the crate docs"
.PHONY: release-check
release-check:
RUSTFLAGS="-D warnings" cargo build --release
.PHONY: fmt
fmt:
cargo +stable fmt --all
.PHONY: fmt-check
fmt-check:
cargo +stable fmt --check
.PHONY: lint
lint:
cargo clippy --all-targets --all-features --workspace -- -D warnings
.PHONY: lint-fix
lint-fix:
cargo clippy --fix --all-targets --all-features --allow-dirty --allow-staged --workspace -- -D warnings
.PHONY: lint-strict
lint-strict:
cargo clippy --all-targets --all-features -- \
-D warnings \
-D clippy::must_use_candidate \
-D clippy::missing_errors_doc \
-D clippy::missing_panics_doc \
-D missing_docs
cargo clippy --all-targets --no-default-features -- \
-D warnings \
-D clippy::must_use_candidate \
-D clippy::missing_errors_doc \
-D clippy::missing_panics_doc \
-D missing_docs
cargo clippy --all-targets --features non-zero -- \
-D warnings \
-D clippy::must_use_candidate \
-D clippy::missing_errors_doc \
-D clippy::missing_panics_doc \
-D missing_docs
.PHONY: clean
clean:
cargo clean
.PHONY: audit
audit: check-cargo-audit
cargo audit --deny warnings
.PHONY: check-cargo-audit
check-cargo-audit:
@command -v cargo-audit > /dev/null || (echo "Installing cargo-audit..."; cargo install cargo-audit --no-default-features)
.PHONY: check
check: fmt-check lint lint-strict test-matrix release-check doc-check readme-check scan-banned audit
@echo ""
@echo "All quality gates passed."
.PHONY: run
run:
cargo run
.PHONY: fix
fix:
cargo fix --allow-staged --allow-dirty
.PHONY: pre-push
pre-push: check
.PHONY: fixup
fixup: fix fmt lint-fix readme
.PHONY: doc
doc:
cargo clippy -- -W missing-docs
.PHONY: doc-open
doc-open:
cargo doc --open
.PHONY: publish
publish: readme
cargo login ${CARGO_REGISTRY_TOKEN}
cargo package
cargo publish
.PHONY: coverage
coverage:
export LOGLEVEL=WARN
cargo install cargo-tarpaulin
mkdir -p coverage
cargo tarpaulin --verbose --all-features --workspace --timeout 600 --out Xml --output-dir coverage
.PHONY: coverage-html
coverage-html:
export LOGLEVEL=WARN
cargo install cargo-tarpaulin
mkdir -p coverage
cargo tarpaulin --color Always --engine llvm --tests --all-targets --all-features --workspace --timeout 600 --out Html --output-dir coverage
.PHONY: open-coverage
open-coverage:
open tarpaulin-report.html
git-log:
@if [ "$(CURRENT_BRANCH)" = "HEAD" ]; then \
echo "You are in a detached HEAD state. Please check out a branch."; \
exit 1; \
fi; \
echo "Showing git log for branch $(CURRENT_BRANCH) against main:"; \
git log main..$(CURRENT_BRANCH) --pretty=full
.PHONY: create-doc
create-doc:
cargo doc --no-deps --document-private-items
.PHONY: readme
readme: check-cargo-readme create-doc
cargo readme > README.md
.PHONY: check-cargo-readme
check-cargo-readme:
@command -v cargo-readme > /dev/null || (echo "Installing cargo-readme..."; cargo install cargo-readme)
.PHONY: check-spanish
check-spanish:
@rg -n --pcre2 -e '^\s*(//|///|//!|#|/\*|\*).*?[áéíóúÁÉÍÓÚñÑ¿¡]' \
--glob '!target/*' \
--glob '!**/*.png' \
. || (echo "❌ Spanish comments found"; exit 1)
.PHONY: check-cargo-criterion
check-cargo-criterion:
@command -v cargo-criterion > /dev/null || (echo "Installing cargo-criterion..."; cargo install cargo-criterion)
.PHONY: bench
bench: check-cargo-criterion
cargo criterion --output-format=quiet
.PHONY: bench-show
bench-show:
open target/criterion/report/index.html
.PHONY: bench-save
bench-save: check-cargo-criterion
cargo criterion --output-format quiet --history-id v0.4.0 --history-description "Version 0.4.0 baseline"
.PHONY: bench-compare
bench-compare: check-cargo-criterion
cargo criterion --output-format verbose
.PHONY: bench-json
bench-json: check-cargo-criterion
cargo criterion --message-format json
.PHONY: bench-clean
bench-clean:
rm -rf target/criterion
.PHONY: workflow-coverage
workflow-coverage:
DOCKER_HOST="$${DOCKER_HOST}" act push --job code_coverage_report \
-P ubuntu-latest=catthehacker/ubuntu:latest \
--privileged
.PHONY: workflow-build
workflow-build:
DOCKER_HOST="$${DOCKER_HOST}" act push --job build \
-P ubuntu-latest=catthehacker/ubuntu:latest
.PHONY: workflow-lint
workflow-lint:
DOCKER_HOST="$${DOCKER_HOST}" act push --job lint
.PHONY: workflow-test
workflow-test:
DOCKER_HOST="$${DOCKER_HOST}" act push --job run_tests
.PHONY: workflow
workflow: workflow-build workflow-lint workflow-test workflow-coverage