.PHONY: help build test clean lint fmt check install uninstall
.PHONY: release-dry release tag docs examples
.PHONY: completion completions pre-commit setup
.PHONY: release-patch release-minor release-major
.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 "$(RED)❌ Direct publishing is deprecated!$(RESET)"
@echo "$(YELLOW)Use the new CI-driven release process:$(RESET)"
@echo " 1. $(BLUE)make release-dry$(RESET) @echo " 2. $(BLUE)git add Cargo.toml Cargo.lock$(RESET)"
@echo " 3. $(BLUE)git commit -m 'Bump version to v$(VERSION)'$(RESET)"
@echo " 4. $(BLUE)make tag$(RESET) @echo ""
@echo "$(GREEN)✅ This ensures CI validation before publishing to crates.io$(RESET)"
@exit 1
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 tag and release!$(RESET)"
@echo "$(YELLOW)Next steps:$(RESET)"
@echo " 1. $(BLUE)git add Cargo.toml Cargo.lock$(RESET)"
@echo " 2. $(BLUE)git commit -m 'Bump version to v$(VERSION)'$(RESET)"
@echo " 3. $(BLUE)make tag$(RESET)
release-patch:
@echo "$(BOLD)🚀 Starting patch release process...$(RESET)"
@current=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
echo "$(YELLOW)Current version: $$current$(RESET)"; \
$(MAKE) bump-patch; \
new=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
echo "$(BLUE)Running release workflow for v$$new...$(RESET)"; \
$(MAKE) release-workflow; \
echo "$(BLUE)Committing version bump...$(RESET)"; \
git add Cargo.toml Cargo.lock; \
git commit -m "Bump version to v$$new"; \
echo "$(BLUE)Pushing commits to origin...$(RESET)"; \
git push origin; \
echo "$(BLUE)Creating and pushing tag...$(RESET)"; \
$(MAKE) tag; \
echo "$(GREEN)✅ Patch release v$$new complete! CI will handle publishing.$(RESET)"
release-minor:
@echo "$(BOLD)🚀 Starting minor release process...$(RESET)"
@current=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
echo "$(YELLOW)Current version: $$current$(RESET)"; \
$(MAKE) bump-minor; \
new=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
echo "$(BLUE)Running release workflow for v$$new...$(RESET)"; \
$(MAKE) release-workflow; \
echo "$(BLUE)Committing version bump...$(RESET)"; \
git add Cargo.toml Cargo.lock; \
git commit -m "Bump version to v$$new"; \
echo "$(BLUE)Pushing commits to origin...$(RESET)"; \
git push origin; \
echo "$(BLUE)Creating and pushing tag...$(RESET)"; \
$(MAKE) tag; \
echo "$(GREEN)✅ Minor release v$$new complete! CI will handle publishing.$(RESET)"
release-major:
@echo "$(BOLD)🚀 Starting major release process...$(RESET)"
@current=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
echo "$(YELLOW)Current version: $$current$(RESET)"; \
$(MAKE) bump-major; \
new=$$(grep '^version =' Cargo.toml | head -1 | cut -d '"' -f 2); \
echo "$(BLUE)Running release workflow for v$$new...$(RESET)"; \
$(MAKE) release-workflow; \
echo "$(BLUE)Committing version bump...$(RESET)"; \
git add Cargo.toml Cargo.lock; \
git commit -m "Bump version to v$$new"; \
echo "$(BLUE)Pushing commits to origin...$(RESET)"; \
git push origin; \
echo "$(BLUE)Creating and pushing tag...$(RESET)"; \
$(MAKE) tag; \
echo "$(GREEN)✅ Major release v$$new complete! CI will handle publishing.$(RESET)"
prepare-release:
@echo "$(BLUE)Preparing release for $(BINARY_NAME)...$(RESET)"
@echo "$(YELLOW)Current version: $(VERSION)$(RESET)"
@echo ""
@echo "$(BLUE)Quick release options:$(RESET)"
@echo " $(GREEN)make release-patch$(RESET) @echo " $(GREEN)make release-minor$(RESET) @echo " $(GREEN)make release-major$(RESET) @echo ""
@echo "$(GREEN)✅ Or manually: bump version, make release-workflow, make tag$(RESET)"
all: clean build test lint
dev: build test
ready: ci-check build-release