BINARY_NAME = ocloc
CARGO = cargo
INSTALL_PATH = ~/.cargo/bin
VERSION := $(shell sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)
BASE ?= HEAD~1
HEAD ?= HEAD
RED = \033[0;31m
GREEN = \033[0;32m
YELLOW = \033[1;33m
BLUE = \033[0;34m
NC = \033[0m
.DEFAULT_GOAL := help
.PHONY: help
help:
@echo "$(BLUE)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo "$(BLUE) ocloc Build System $(NC)"
@echo "$(BLUE)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo ""
@echo "$(YELLOW)Available targets:$(NC)"
@echo ""
@grep -E '^## ' Makefile | sed 's/## / $(GREEN)make /' | sed 's/: /$(NC) - /'
@echo ""
@echo "$(YELLOW)Quick start:$(NC)"
@echo " $(GREEN)make build$(NC) - Build in debug mode"
@echo " $(GREEN)make release$(NC) - Build optimized release"
@echo " $(GREEN)make install$(NC) - Install to system"
@echo ""
.PHONY: build
build:
@echo "$(YELLOW)Building debug version...$(NC)"
@$(CARGO) build
@echo "$(GREEN)✓ Debug build complete$(NC)"
.PHONY: release
release:
@echo "$(YELLOW)Building release version...$(NC)"
@$(CARGO) build --release
@echo "$(GREEN)✓ Release build complete$(NC)"
@echo "Binary location: target/release/$(BINARY_NAME)"
.PHONY: tag-release
tag-release:
@echo "$(YELLOW)Tagging release v$(VERSION)...$(NC)"
@if [ -n "$(shell git status --porcelain)" ]; then \
echo "$(RED)Working tree not clean. Commit or stash changes before tagging.$(NC)"; \
exit 1; \
fi
@if git rev-parse "v$(VERSION)" >/dev/null 2>&1; then \
echo "$(RED)Tag v$(VERSION) already exists.$(NC)"; \
exit 1; \
fi
@git tag -a v$(VERSION) -m "ocloc $(VERSION)"
@git push origin v$(VERSION)
@echo "$(GREEN)✓ Tagged and pushed v$(VERSION)$(NC)"
.PHONY: release-all
release-all: check release tag-release
@echo "$(GREEN)✓ Release workflow complete for v$(VERSION)$(NC)"
.PHONY: publish-crates-dry
publish-crates-dry:
@echo "$(YELLOW)Running cargo publish --dry-run for v$(VERSION)...$(NC)"
@cargo publish --dry-run
@echo "$(GREEN)✓ Dry-run publish OK$(NC)"
.PHONY: publish-crates
publish-crates:
@echo "$(YELLOW)Publishing to crates.io for v$(VERSION)...$(NC)"
@cargo publish
@echo "$(GREEN)✓ Published to crates.io$(NC)"
.PHONY: bump
bump:
@if [ -z "$(VERSION)" ]; then \
echo "$(RED)VERSION not set. Usage: make bump VERSION=X.Y.Z$(NC)"; \
exit 1; \
fi
@bash scripts/bump-version.sh "$(VERSION)"
@echo "$(GREEN)✓ Bumped to $(VERSION). Review changes and commit.$(NC)"
.PHONY: install
install:
@echo "$(YELLOW)Installing ocloc...$(NC)"
@$(CARGO) install --path .
@echo "$(GREEN)✓ Installed to $(INSTALL_PATH)/$(BINARY_NAME)$(NC)"
.PHONY: uninstall
uninstall:
@echo "$(YELLOW)Uninstalling ocloc...$(NC)"
@$(CARGO) uninstall $(BINARY_NAME)
@echo "$(GREEN)✓ Uninstalled$(NC)"
.PHONY: run
run: build
@echo "$(YELLOW)Running ocloc on current directory...$(NC)"
@./target/debug/$(BINARY_NAME) .
.PHONY: run-release
run-release: release
@echo "$(YELLOW)Running ocloc on current directory...$(NC)"
@./target/release/$(BINARY_NAME) .
.PHONY: test
test:
@echo "$(YELLOW)Running tests...$(NC)"
@$(CARGO) test
@echo "$(GREEN)✓ All tests passed$(NC)"
.PHONY: test-verbose
test-verbose:
@echo "$(YELLOW)Running tests (verbose)...$(NC)"
@$(CARGO) test -- --nocapture
.PHONY: bench
bench:
@echo "$(YELLOW)Running benchmarks...$(NC)"
@$(CARGO) bench
.PHONY: bench-small
bench-small: release
@echo "$(YELLOW)Benchmarking on yt-dlp...$(NC)"
@bash scripts/benchmark-small.sh
.PHONY: bench-large
bench-large: release
@echo "$(YELLOW)Benchmarking on elasticsearch...$(NC)"
@bash scripts/benchmark-large.sh
.PHONY: diff
diff: release
@echo "$(YELLOW)Diffing $(BASE)..$(HEAD) ...$(NC)"
@./target/release/$(BINARY_NAME) diff --base "$(BASE)" --head "$(HEAD)"
.PHONY: diff-json
diff-json: release
@echo "$(YELLOW)Diffing $(BASE)..$(HEAD) (JSON) ...$(NC)"
@./target/release/$(BINARY_NAME) diff --base "$(BASE)" --head "$(HEAD)" --json > loc_diff.json
@echo "$(GREEN)✓ Wrote loc_diff.json$(NC)"
.PHONY: diff-md
diff-md: release
@echo "$(YELLOW)Diffing $(BASE)..$(HEAD) (Markdown) ...$(NC)"
@./target/release/$(BINARY_NAME) diff --base "$(BASE)" --head "$(HEAD)" --markdown > loc_diff.md
@echo "$(GREEN)✓ Wrote loc_diff.md$(NC)"
.PHONY: fmt
fmt:
@echo "$(YELLOW)Formatting code...$(NC)"
@$(CARGO) fmt
@echo "$(GREEN)✓ Code formatted$(NC)"
.PHONY: fmt-check
fmt-check:
@echo "$(YELLOW)Checking code format...$(NC)"
@$(CARGO) fmt -- --check
@echo "$(GREEN)✓ Code is properly formatted$(NC)"
.PHONY: lint
lint:
@echo "$(YELLOW)Running clippy...$(NC)"
@$(CARGO) clippy -- -D warnings
@echo "$(GREEN)✓ No linting issues$(NC)"
.PHONY: fix
fix:
@echo "$(YELLOW)Auto-fixing issues...$(NC)"
@$(CARGO) fix --allow-dirty --allow-staged
@$(CARGO) fmt
@echo "$(GREEN)✓ Issues fixed$(NC)"
.PHONY: check
check: fmt-check lint test
@echo "$(GREEN)✓ All checks passed$(NC)"
.PHONY: clean
clean:
@echo "$(YELLOW)Cleaning build artifacts...$(NC)"
@$(CARGO) clean
@rm -f Cargo.lock
@echo "$(GREEN)✓ Clean complete$(NC)"
.PHONY: doc
doc:
@echo "$(YELLOW)Generating documentation...$(NC)"
@$(CARGO) doc --open
.PHONY: doc-all
doc-all:
@echo "$(YELLOW)Generating complete documentation...$(NC)"
@$(CARGO) doc --all --open
.PHONY: setup-hooks
setup-hooks:
@echo "$(YELLOW)Installing git hooks...$(NC)"
@bash scripts/install-git-hooks.sh
@echo "$(GREEN)✓ Git hooks installed$(NC)"
.PHONY: ci
ci:
@echo "$(BLUE)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo "$(BLUE) Running CI Pipeline $(NC)"
@echo "$(BLUE)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo ""
@echo "$(YELLOW)[1/5] Checking format...$(NC)"
@$(CARGO) fmt -- --check
@echo "$(GREEN)✓ Format check passed$(NC)\n"
@echo "$(YELLOW)[2/5] Running clippy...$(NC)"
@$(CARGO) clippy -- -D warnings
@echo "$(GREEN)✓ Clippy passed$(NC)\n"
@echo "$(YELLOW)[3/5] Running tests...$(NC)"
@$(CARGO) test
@echo "$(GREEN)✓ Tests passed$(NC)\n"
@echo "$(YELLOW)[4/5] Building debug...$(NC)"
@$(CARGO) build
@echo "$(GREEN)✓ Debug build successful$(NC)\n"
@echo "$(YELLOW)[5/5] Building release...$(NC)"
@$(CARGO) build --release
@echo "$(GREEN)✓ Release build successful$(NC)\n"
@echo "$(GREEN)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo "$(GREEN) ✓ CI Pipeline Complete $(NC)"
@echo "$(GREEN)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
.PHONY: dev
dev:
@echo "$(YELLOW)Starting development mode...$(NC)"
@echo "$(YELLOW)Installing cargo-watch if not present...$(NC)"
@cargo install cargo-watch 2>/dev/null || true
@echo "$(YELLOW)Watching for changes...$(NC)"
@cargo watch -x 'run -- .'
.PHONY: compare
compare: release
@echo "$(BLUE)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo "$(BLUE) Performance Comparison: ocloc vs cloc $(NC)"
@echo "$(BLUE)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)"
@echo ""
@echo "$(YELLOW)Running cloc...$(NC)"
@time -p cloc . --quiet 2>/dev/null || echo "$(RED)cloc not installed. Install with: brew install cloc$(NC)"
@echo ""
@echo "$(YELLOW)Running ocloc...$(NC)"
@time -p ./target/release/$(BINARY_NAME) . 2>&1 | head -n 50
@echo ""
@echo "$(GREEN)Compare the 'real' time values above to see the speedup!$(NC)"
.PHONY: version
version:
@echo "$(YELLOW)ocloc version:$(NC)"
@$(CARGO) pkgid | cut -d '#' -f 2
@echo ""
@echo "$(YELLOW)Rust version:$(NC)"
@rustc --version
@echo ""
@echo "$(YELLOW)Cargo version:$(NC)"
@$(CARGO) --version
.PHONY: version-show
version-show:
@echo "$(GREEN)Version: $(VERSION)$(NC)"
.PHONY: update
update:
@echo "$(YELLOW)Updating dependencies...$(NC)"
@$(CARGO) update
@echo "$(GREEN)✓ Dependencies updated$(NC)"
.PHONY: audit
audit:
@echo "$(YELLOW)Checking for security vulnerabilities...$(NC)"
@cargo install cargo-audit 2>/dev/null || true
@cargo audit
@echo "$(GREEN)✓ Security audit complete$(NC)"
.PHONY: size
size: release
@echo "$(YELLOW)Binary size information:$(NC)"
@ls -lh target/release/$(BINARY_NAME)
@echo ""
@echo "$(YELLOW)Size breakdown:$(NC)"
@size target/release/$(BINARY_NAME) 2>/dev/null || \
(du -h target/release/$(BINARY_NAME) && \
echo "$(YELLOW)Install 'binutils' for detailed size breakdown$(NC)")
.PHONY: all
all: clean build release
@echo "$(GREEN)✓ Complete build finished$(NC)"
%:
@echo "$(RED)Error: Unknown target '$@'$(NC)"
@echo "Run '$(GREEN)make help$(NC)' to see available targets"
@exit 1