.DEFAULT_GOAL := help
BINARY_NAME := octocode
VERSION := $(shell grep '^version =' Cargo.toml | cut -d '"' -f2)
RUST_VERSION := $(shell rustc --version)
TARGET_DIR := target
RELEASE_DIR := $(TARGET_DIR)/release
DEBUG_DIR := $(TARGET_DIR)/debug
TARGETS := x86_64-unknown-linux-musl \
aarch64-unknown-linux-musl \
x86_64-pc-windows-msvc \
aarch64-pc-windows-msvc \
x86_64-apple-darwin \
aarch64-apple-darwin
GREEN := \033[0;32m
YELLOW := \033[0;33m
RED := \033[0;31m
BLUE := \033[0;34m
NC := \033[0m
GIT_AVAILABLE := $(shell git status >/dev/null 2>&1 && echo "yes" || echo "no")
.PHONY: help
help:
@echo "$(BLUE)octocode v$(VERSION)$(NC)"
@echo "$(BLUE)Rust version: $(RUST_VERSION)$(NC)"
@echo ""
@echo "$(YELLOW)Available targets:$(NC)"
@awk 'BEGIN {FS = ":.*##"; printf ""} /^[a-zA-Z_-]+:.*?##/ { printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
.PHONY: install-deps
install-deps:
@echo "$(YELLOW)Installing development dependencies...$(NC)"
rustup component add clippy rustfmt
cargo install cargo-audit cargo-outdated cargo-machete cargo-nextest
@echo "$(GREEN)Dependencies installed successfully$(NC)"
.PHONY: install-targets
install-targets:
@echo "$(YELLOW)Installing compilation targets...$(NC)"
@for target in $(TARGETS); do \
echo "Installing $$target..."; \
rustup target add $$target; \
done
@echo "$(GREEN)Compilation targets installed$(NC)"
.PHONY: check
check:
@echo "$(YELLOW)Running cargo check...$(NC)"
cargo check --all-targets --all-features
.PHONY: build
build:
@echo "$(YELLOW)Building $(BINARY_NAME) in debug mode...$(NC)"
cargo build
.PHONY: build-release
build-release:
@echo "$(YELLOW)Building $(BINARY_NAME) in release mode...$(NC)"
cargo build --release
@echo "$(GREEN)Release binary built: $(RELEASE_DIR)/$(BINARY_NAME)$(NC)"
.PHONY: build-static
build-static:
@echo "$(YELLOW)Building static binary...$(NC)"
ifeq ($(shell uname),Darwin)
cargo build --release --target x86_64-apple-darwin
cargo build --release --target aarch64-apple-darwin
else ifeq ($(shell uname),Linux)
ifeq ($(shell uname -m),x86_64)
cargo build --release --target x86_64-unknown-linux-musl
else
cargo build --release --target aarch64-unknown-linux-musl
endif
else
cargo build --release
endif
@echo "$(GREEN)Static binary built successfully$(NC)"
.PHONY: build-all
build-all: install-targets
@echo "$(YELLOW)Building for all supported platforms...$(NC)"
@for target in $(TARGETS); do \
echo "Building for $$target..."; \
cargo build --release --target $$target; \
if [ $$? -eq 0 ]; then \
echo "$(GREEN)✓ $$target built successfully$(NC)"; \
else \
echo "$(RED)✗ $$target build failed$(NC)"; \
fi; \
done
.PHONY: test
test:
@echo "$(YELLOW)Running tests...$(NC)"
cargo test
.PHONY: test-verbose
test-verbose:
@echo "$(YELLOW)Running tests with verbose output...$(NC)"
cargo test -- --nocapture
.PHONY: test-nextest
test-nextest:
@echo "$(YELLOW)Running tests with nextest...$(NC)"
cargo nextest run
.PHONY: lint
lint:
@echo "$(YELLOW)Running clippy lints...$(NC)"
cargo clippy --all-targets --all-features -- -D warnings
.PHONY: lint-fix
lint-fix:
@echo "$(YELLOW)Running clippy with automatic fixes...$(NC)"
cargo clippy --all-targets --all-features --fix --allow-dirty -- -D warnings
.PHONY: format
format:
@echo "$(YELLOW)Formatting code...$(NC)"
cargo fmt
.PHONY: format-check
format-check:
@echo "$(YELLOW)Checking code formatting...$(NC)"
cargo fmt -- --check
.PHONY: audit
audit:
@echo "$(YELLOW)Running security audit...$(NC)"
cargo audit
.PHONY: outdated
outdated:
@echo "$(YELLOW)Checking for outdated dependencies...$(NC)"
cargo outdated
.PHONY: unused-deps
unused-deps:
@echo "$(YELLOW)Checking for unused dependencies...$(NC)"
cargo machete
.PHONY: clean
clean:
@echo "$(YELLOW)Cleaning build artifacts...$(NC)"
cargo clean
@echo "$(GREEN)Build artifacts cleaned$(NC)"
.PHONY: clean-target
clean-target:
@echo "$(YELLOW)Cleaning target directory...$(NC)"
rm -rf $(TARGET_DIR)
@echo "$(GREEN)Target directory cleaned$(NC)"
.PHONY: install
install: build-release
@echo "$(YELLOW)Installing $(BINARY_NAME)...$(NC)"
cargo install --path .
@echo "$(GREEN)$(BINARY_NAME) installed successfully$(NC)"
.PHONY: uninstall
uninstall:
@echo "$(YELLOW)Uninstalling $(BINARY_NAME)...$(NC)"
cargo uninstall $(BINARY_NAME)
@echo "$(GREEN)$(BINARY_NAME) uninstalled successfully$(NC)"
.PHONY: install-completions
install-completions: build-release
@echo "$(YELLOW)Installing shell completions...$(NC)"
@./scripts/install-completions.sh
@echo "$(GREEN)Shell completions installed!$(NC)"
.PHONY: test-completions
test-completions: build-release
@echo "$(YELLOW)Testing shell completion generation...$(NC)"
@./scripts/test-completions.sh
.PHONY: run
run:
@echo "$(YELLOW)Running $(BINARY_NAME) in debug mode...$(NC)"
cargo run
.PHONY: run-release
run-release:
@echo "$(YELLOW)Running $(BINARY_NAME) in release mode...$(NC)"
cargo run --release
.PHONY: size
size: build-release
@echo "$(YELLOW)Binary size information:$(NC)"
@if [ -f "$(RELEASE_DIR)/$(BINARY_NAME)" ]; then \
ls -lh $(RELEASE_DIR)/$(BINARY_NAME); \
file $(RELEASE_DIR)/$(BINARY_NAME); \
else \
echo "$(RED)Release binary not found. Run 'make build-release' first.$(NC)"; \
fi
.PHONY: bench
bench:
@echo "$(YELLOW)Running benchmarks...$(NC)"
cargo bench
.PHONY: doc
doc:
@echo "$(YELLOW)Generating documentation...$(NC)"
cargo doc --no-deps --open
.PHONY: doc-private
doc-private:
@echo "$(YELLOW)Generating documentation (including private)...$(NC)"
cargo doc --no-deps --document-private-items --open
.PHONY: release-dry
release-dry:
@echo "$(YELLOW)Dry run of cargo release...$(NC)"
cargo publish --dry-run
.PHONY: release
release: test lint audit
@echo "$(YELLOW)Publishing to crates.io...$(NC)"
cargo publish
.PHONY: git-tag
git-tag:
ifeq ($(GIT_AVAILABLE),yes)
@echo "$(YELLOW)Creating git tag v$(VERSION)...$(NC)"
git tag -a v$(VERSION) -m "Release v$(VERSION)"
git push origin v$(VERSION)
@echo "$(GREEN)Git tag v$(VERSION) created and pushed$(NC)"
else
@echo "$(RED)Not in a git repository$(NC)"
endif
.PHONY: ci
ci: format-check lint test audit
@echo "$(GREEN)All CI checks passed!$(NC)"
.PHONY: ci-quick
ci-quick: format-check lint test
@echo "$(GREEN)Quick CI checks passed!$(NC)"
.PHONY: setup
setup: install-deps install-targets
@echo "$(GREEN)Development environment setup complete!$(NC)"
.PHONY: info
info:
@echo "$(BLUE)Project Information:$(NC)"
@echo " Name: $(BINARY_NAME)"
@echo " Version: $(VERSION)"
@echo " Rust version: $(RUST_VERSION)"
@echo " Target directory: $(TARGET_DIR)"
@echo " Release directory: $(RELEASE_DIR)"
@echo " Supported targets: $(TARGETS)"
@if [ -f "$(RELEASE_DIR)/$(BINARY_NAME)" ]; then \
echo " Release binary: $(GREEN)✓ Available$(NC)"; \
else \
echo " Release binary: $(RED)✗ Not built$(NC)"; \
fi
$(TARGET_DIR):
mkdir -p $(TARGET_DIR)
$(RELEASE_DIR): $(TARGET_DIR)
mkdir -p $(RELEASE_DIR)
$(DEBUG_DIR): $(TARGET_DIR)
mkdir -p $(DEBUG_DIR)