.PHONY: help build test clean lint fmt check install uninstall
.PHONY: release-dry release tag docs examples
.PHONY: completion completions pre-commit setup
.DEFAULT_GOAL := help
CARGO := cargo
TARGET_DIR := target
BINARY_NAME := askr
VERSION := $(shell grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2)
RED := \033[31m
GREEN := \033[32m
YELLOW := \033[33m
BLUE := \033[34m
BOLD := \033[1m
RESET := \033[0m
help:
@echo "$(BOLD)askr v$(VERSION) - Interactive CLI input tool$(RESET)"
@echo ""
@echo "$(BOLD)Available targets:$(RESET)"
@awk 'BEGIN {FS = ":.*##"; printf ""} /^[a-zA-Z_-]+:.*?##/ { printf " $(GREEN)%-15s$(RESET) %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
build:
@echo "$(BLUE)Building $(BINARY_NAME)...$(RESET)"
$(CARGO) build
build-release:
@echo "$(BLUE)Building $(BINARY_NAME) (release)...$(RESET)"
$(CARGO) build --release
test:
@echo "$(BLUE)Running tests...$(RESET)"
$(CARGO) test
test-verbose:
@echo "$(BLUE)Running tests (verbose)...$(RESET)"
$(CARGO) test -- --nocapture
check:
@echo "$(BLUE)Checking code...$(RESET)"
$(CARGO) check
lint:
@echo "$(BLUE)Running clippy...$(RESET)"
$(CARGO) clippy --all-targets --all-features -- -D unused-imports -D clippy::collapsible_else_if -D clippy::int_plus_one
lint-fix:
@echo "$(BLUE)Running clippy with fixes...$(RESET)"
$(CARGO) clippy --fix --allow-dirty --allow-staged
fmt:
@echo "$(BLUE)Formatting code...$(RESET)"
$(CARGO) fmt
fmt-check:
@echo "$(BLUE)Checking code formatting...$(RESET)"
$(CARGO) fmt --check
install: build-release
@echo "$(BLUE)Installing $(BINARY_NAME)...$(RESET)"
$(CARGO) install --path .
uninstall:
@echo "$(BLUE)Uninstalling $(BINARY_NAME)...$(RESET)"
$(CARGO) uninstall $(BINARY_NAME)
release-dry:
@echo "$(BLUE)Dry run release to crates.io...$(RESET)"
$(CARGO) publish --dry-run
release:
@echo "$(YELLOW)Publishing $(BINARY_NAME) v$(VERSION) to crates.io...$(RESET)"
@echo "$(RED)Warning: This will publish to crates.io!$(RESET)"
@read -p "Continue? [y/N] " -n 1 -r; \
if [[ $$REPLY =~ ^[Yy]$$ ]]; then \
echo ""; \
$(CARGO) publish; \
echo "$(GREEN)Successfully published to crates.io!$(RESET)"; \
else \
echo ""; \
echo "$(YELLOW)Release cancelled.$(RESET)"; \
fi
tag:
@echo "$(BLUE)Creating tag v$(VERSION)...$(RESET)"
git tag -a v$(VERSION) -m "Release v$(VERSION)"
git push origin v$(VERSION)
@echo "$(GREEN)Tag v$(VERSION) created and pushed!$(RESET)"
docs:
@echo "$(BLUE)Generating documentation...$(RESET)"
$(CARGO) doc --open
docs-build:
@echo "$(BLUE)Building documentation...$(RESET)"
$(CARGO) doc
completion: completions
completions: build
@echo "$(BLUE)Generating shell completions...$(RESET)"
@mkdir -p completions
./$(TARGET_DIR)/debug/$(BINARY_NAME) completion bash > completions/$(BINARY_NAME).bash
./$(TARGET_DIR)/debug/$(BINARY_NAME) completion zsh > completions/$(BINARY_NAME).zsh
./$(TARGET_DIR)/debug/$(BINARY_NAME) completion fish > completions/$(BINARY_NAME).fish
./$(TARGET_DIR)/debug/$(BINARY_NAME) completion power-shell > completions/$(BINARY_NAME).ps1
@echo "$(GREEN)Completions generated in completions/$(RESET)"
examples: build
@echo "$(BLUE)Running example scripts...$(RESET)"
@if [ -d examples ]; then \
for script in examples/*.sh; do \
echo "$(YELLOW)Running $$script...$(RESET)"; \
bash "$$script"; \
done; \
else \
echo "$(RED)No examples directory found$(RESET)"; \
fi
setup:
@echo "$(BLUE)Setting up development environment...$(RESET)"
@command -v pre-commit >/dev/null 2>&1 || { \
echo "$(YELLOW)Installing pre-commit...$(RESET)"; \
pip install pre-commit; \
}
@echo "$(BLUE)Installing pre-commit hooks...$(RESET)"
pre-commit install
@echo "$(GREEN)Development environment ready!$(RESET)"
pre-commit:
@echo "$(BLUE)Running pre-commit hooks...$(RESET)"
pre-commit run --all-files
ci-check: fmt-check lint test
@echo "$(GREEN)All CI checks passed!$(RESET)"
ci-build:
@echo "$(BLUE)Building all targets for CI...$(RESET)"
$(CARGO) build --all-targets
$(CARGO) build --all-targets --release
clean:
@echo "$(BLUE)Cleaning build artifacts...$(RESET)"
$(CARGO) clean
rm -rf completions/
update:
@echo "$(BLUE)Updating dependencies...$(RESET)"
$(CARGO) update
audit:
@echo "$(BLUE)Running security audit...$(RESET)"
$(CARGO) audit
version:
@echo "$(BOLD)Current version: $(GREEN)$(VERSION)$(RESET)"
bump-patch:
@echo "$(BLUE)Bumping patch version...$(RESET)"
@current=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
new=$$(echo $$current | awk -F. '{print $$1"."$$2"."$$3+1}'); \
sed -i.bak "s/^version = \"$$current\"/version = \"$$new\"/" Cargo.toml; \
rm Cargo.toml.bak; \
echo "$(GREEN)Version bumped from $$current to $$new$(RESET)"
bump-minor:
@echo "$(BLUE)Bumping minor version...$(RESET)"
@current=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
new=$$(echo $$current | awk -F. '{print $$1"."$$2+1".0"}'); \
sed -i.bak "s/^version = \"$$current\"/version = \"$$new\"/" Cargo.toml; \
rm Cargo.toml.bak; \
echo "$(GREEN)Version bumped from $$current to $$new$(RESET)"
bump-major:
@echo "$(BLUE)Bumping major version...$(RESET)"
@current=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
new=$$(echo $$current | awk -F. '{print $$1+1".0.0"}'); \
sed -i.bak "s/^version = \"$$current\"/version = \"$$new\"/" Cargo.toml; \
rm Cargo.toml.bak; \
echo "$(GREEN)Version bumped from $$current to $$new$(RESET)"
release-workflow: ci-check release-dry
@echo "$(GREEN)Release workflow complete. Ready to publish!$(RESET)"
@echo "$(YELLOW)Run 'make release' to publish to crates.io$(RESET)"
all: clean build test lint
dev: build test
ready: ci-check build-release