Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash
# Commit message hook: Validates conventional commit format
# Format: type(scope): description

set -e

COMMIT_MSG_FILE="$1"
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Skip merge commits and fixup commits
if echo "$COMMIT_MSG" | grep -qE '^(Merge|fixup!|squash!)'; then
exit 0
fi

# Conventional commit regex
# Format: type(scope): description
# type is required, scope is optional
PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|security)(\([a-z0-9_-]+\))?: .{1,100}$'

# Get first line
FIRST_LINE=$(echo "$COMMIT_MSG" | head -n1)

if echo "$FIRST_LINE" | grep -qE "$PATTERN"; then
exit 0
else
echo -e "${RED}Invalid commit message format!${NC}"
echo ""
echo "Expected format: type(scope): description"
echo ""
echo "Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, security"
echo "Valid scopes: ai, cli, core, tui, scanner, runbook, plugin, mcp, security, config, git, env, deps, ci, docs, release"
echo ""
echo "Examples:"
echo " feat(ai): add Azure OpenAI provider"
echo " fix(tui): resolve input handling issue"
echo " docs: update README with new features"
echo ""
echo "Your message: $FIRST_LINE"
exit 1
fi
83 changes: 83 additions & 0 deletions .githooks/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/bash
# Git hooks installation script for Palrun
#
# This script installs the git hooks from .githooks/ to .git/hooks/
# Run this once after cloning the repository.

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
GIT_HOOKS_DIR="$REPO_ROOT/.git/hooks"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}Installing Palrun git hooks...${NC}"
echo ""

# Ensure .git/hooks directory exists
if [ ! -d "$GIT_HOOKS_DIR" ]; then
echo -e "${RED}Error: .git/hooks directory not found${NC}"
echo "Are you in a git repository?"
exit 1
fi

# List of hooks to install
HOOKS=("pre-commit" "pre-push" "commit-msg")

for hook in "${HOOKS[@]}"; do
src="$SCRIPT_DIR/$hook"
dst="$GIT_HOOKS_DIR/$hook"

if [ -f "$src" ]; then
# Backup existing hook if it exists and is not a symlink to ours
if [ -f "$dst" ] && [ ! -L "$dst" ]; then
echo -e "${YELLOW}Backing up existing $hook hook to $hook.backup${NC}"
mv "$dst" "$dst.backup"
fi

# Create symlink
ln -sf "$src" "$dst"
chmod +x "$src"
echo -e "${GREEN}✓${NC} Installed $hook"
else
echo -e "${YELLOW}⚠${NC} $hook hook not found in .githooks/"
fi
done

echo ""
echo -e "${GREEN}Git hooks installed successfully!${NC}"
echo ""
echo "Installed hooks:"
echo " pre-commit - Format check, clippy, build verification"
echo " pre-push - Full test suite, security audit, license check"
echo " commit-msg - Conventional commit format validation"
echo ""
echo "To skip hooks temporarily, use:"
echo " git commit --no-verify"
echo " git push --no-verify"
echo ""

# Optional: Check for required tools
echo -e "${BLUE}Checking for optional tools...${NC}"

check_tool() {
if command -v "$1" &> /dev/null; then
echo -e "${GREEN}✓${NC} $1 found"
return 0
else
echo -e "${YELLOW}⚠${NC} $1 not found - install with: $2"
return 1
fi
}

check_tool "cargo-audit" "cargo install cargo-audit"
check_tool "cargo-deny" "cargo install cargo-deny"

echo ""
echo -e "${GREEN}Setup complete!${NC}"
48 changes: 48 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
# Pre-commit hook: Fast quality checks
# Runs: format check, lint (fast mode), basic tests

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${YELLOW}Running pre-commit checks...${NC}"

# 1. Format check (fast)
echo -n " Checking format... "
if cargo fmt --all --check > /dev/null 2>&1; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${RED}FAILED${NC}"
echo ""
echo "Format issues found. Run 'cargo fmt' to fix."
exit 1
fi

# 2. Clippy lint (fast mode - only changed files would be better but this is still fast with cache)
echo -n " Running clippy... "
if cargo clippy --all-features --quiet -- -D clippy::correctness -D clippy::suspicious 2>/dev/null; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${RED}FAILED${NC}"
echo ""
echo "Clippy found issues. Run 'cargo clippy --all-features' to see details."
exit 1
fi

# 3. Quick compile check (catches type errors)
echo -n " Checking build... "
if cargo check --all-features --quiet 2>/dev/null; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${RED}FAILED${NC}"
echo ""
echo "Build check failed. Run 'cargo check --all-features' to see errors."
exit 1
fi

echo -e "${GREEN}All pre-commit checks passed!${NC}"
64 changes: 64 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash
# Pre-push hook: Full quality + security checks
# Runs: tests, security audit, license check

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${YELLOW}Running pre-push checks (this may take a moment)...${NC}"

# 1. Run tests
echo -e "${BLUE}Running tests...${NC}"
if cargo test --all-features --workspace --quiet 2>/dev/null; then
echo -e " Tests: ${GREEN}OK${NC}"
else
echo -e " Tests: ${RED}FAILED${NC}"
echo ""
echo "Tests failed. Run 'cargo test --all-features' to see failures."
exit 1
fi

# 2. Security audit (if cargo-audit is installed)
if command -v cargo-audit &> /dev/null; then
echo -n " Security audit... "
if cargo audit --quiet 2>/dev/null; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${YELLOW}WARNINGS${NC} (check 'cargo audit' for details)"
# Don't fail on warnings - just inform
fi
else
echo -e " Security audit: ${YELLOW}SKIPPED${NC} (install with: cargo install cargo-audit)"
fi

# 3. License/dependency check (if cargo-deny is installed)
if command -v cargo-deny &> /dev/null; then
echo -n " License check... "
if cargo deny check licenses --quiet 2>/dev/null; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${RED}FAILED${NC}"
echo ""
echo "License check failed. Run 'cargo deny check' for details."
exit 1
fi

echo -n " Dependency check... "
if cargo deny check bans --quiet 2>/dev/null; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${YELLOW}WARNINGS${NC}"
# Don't fail - just inform
fi
else
echo -e " License check: ${YELLOW}SKIPPED${NC} (install with: cargo install cargo-deny)"
fi

echo ""
echo -e "${GREEN}All pre-push checks passed!${NC}"
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ Cargo.lock.bak

# Internal documentation (keep local)
/local-docs/

# Claude Code local files
CLAUDE.md
.claude/
Loading
Loading