threatflux-binary-analysis 0.2.0

Comprehensive binary analysis library with multi-format support, disassembly, and security analysis
Documentation
#!/bin/bash
#
# Pre-commit hook template for ThreatFlux repositories
# This hook runs the same checks as CI/CD locally before allowing commits
#
# Installation: Copy to .git/hooks/pre-commit and make executable
#

set -e

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

# Function to print colored output
print_status() {
    echo -e "${BLUE}[PRE-COMMIT]${NC} $1"
}

print_success() {
    echo -e "${GREEN}$1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}$1${NC}"
}

# Function to check if command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to install missing tools
install_missing_tools() {
    local missing_tools=()
    
    if ! command_exists cargo; then
        print_error "Rust/Cargo not installed. Please install Rust first."
        exit 1
    fi
    
    if ! command_exists cargo-fmt; then
        print_status "Installing rustfmt..."
        rustup component add rustfmt
    fi
    
    if ! command_exists cargo-clippy; then
        print_status "Installing clippy..."
        rustup component add clippy
    fi
    
    if ! command_exists cargo-audit; then
        print_status "Installing cargo-audit..."
        cargo install cargo-audit
    fi
    
    if ! command_exists cargo-deny; then
        print_status "Installing cargo-deny..."
        cargo install cargo-deny
    fi
    
    # Check for system dependencies based on repository
    if [[ -f "Cargo.toml" ]] && grep -q "capstone" Cargo.toml; then
        if [[ "$OSTYPE" == "darwin"* ]]; then
            if ! brew list libcapstone &>/dev/null; then
                print_warning "libcapstone not found. Install with: brew install capstone"
            fi
        elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
            if ! dpkg -l | grep -q libcapstone-dev; then
                print_warning "libcapstone-dev not found. Install with: sudo apt-get install libcapstone-dev pkg-config"
            fi
        fi
    fi
}

# Main pre-commit checks
run_precommit_checks() {
    print_status "Running pre-commit checks..."
    
    # Install missing tools
    install_missing_tools
    
    # 1. Check for TODO/FIXME/XXX comments in staged files
    print_status "Checking for TODO/FIXME/XXX comments..."
    if git diff --cached --name-only | grep "\.rs$" | xargs grep -Hn "TODO\|FIXME\|XXX\|HACK" 2>/dev/null; then
        print_error "Found TODO/FIXME/XXX comments in staged files. Please resolve or document them."
        exit 1
    fi
    print_success "No problematic comments found"
    
    # 2. Rust formatting check
    print_status "Checking Rust formatting..."
    if ! cargo fmt --all -- --check; then
        print_error "Code formatting issues found. Run 'cargo fmt' to fix."
        exit 1
    fi
    print_success "Formatting check passed"
    
    # 3. Clippy linting
    print_status "Running Clippy lints..."
    if ! cargo clippy --all-targets --all-features -- -D warnings; then
        print_error "Clippy lints failed. Fix warnings and try again."
        exit 1
    fi
    print_success "Clippy checks passed"
    
    # 4. Tests
    print_status "Running tests..."
    if ! cargo test --all-features; then
        print_error "Tests failed. Fix failing tests before committing."
        exit 1
    fi
    print_success "All tests passed"
    
    # 5. Security audit
    print_status "Running security audit..."
    if ! cargo audit; then
        print_warning "Security vulnerabilities found. Review and address if possible."
        # Don't fail the commit for audit issues, just warn
    else
        print_success "No security vulnerabilities found"
    fi
    
    # 6. Cargo deny checks
    print_status "Running cargo deny checks..."
    
    # Create temporary deny.toml if it doesn't exist
    TEMP_DENY=""
    if [[ ! -f "deny.toml" ]]; then
        TEMP_DENY="deny.toml"
        cat > deny.toml << 'EOF'
[advisories]
version = 2
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
unmaintained = "all"
yanked = "deny"
ignore = []

[licenses]
allow = [
    "MIT",
    "Apache-2.0",
    "Apache-2.0 WITH LLVM-exception",
    "BSD-2-Clause",
    "BSD-3-Clause",
    "ISC",
    "Unicode-3.0",
    "Unicode-DFS-2016",
    "CC0-1.0",
]

[bans]
multiple-versions = "warn"
deny = []
skip = []

[sources]
unknown-registry = "warn"
unknown-git = "warn"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
EOF
    fi
    
    if ! cargo deny check; then
        if [[ -n "$TEMP_DENY" ]]; then
            rm -f "$TEMP_DENY"
        fi
        print_error "Cargo deny checks failed. Review dependency issues."
        exit 1
    fi
    
    # Clean up temporary deny.toml
    if [[ -n "$TEMP_DENY" ]]; then
        rm -f "$TEMP_DENY"
    fi
    print_success "Cargo deny checks passed"
    
    # 7. Build check
    print_status "Running build check..."
    if ! cargo build --all-features; then
        print_error "Build failed. Fix compilation errors."
        exit 1
    fi
    print_success "Build completed successfully"
    
    # 8. Documentation check
    print_status "Checking documentation..."
    if ! cargo doc --all-features --no-deps; then
        print_warning "Documentation build failed. Consider fixing doc comments."
        # Don't fail commit for doc issues, just warn
    else
        print_success "Documentation builds successfully"
    fi
    
    # 9. Check for large files (>10MB)
    print_status "Checking for large files..."
    large_files=$(git diff --cached --name-only | xargs ls -la 2>/dev/null | awk '$5 > 10485760 {print $9}' || true)
    if [[ -n "$large_files" ]]; then
        print_error "Large files detected (>10MB):"
        echo "$large_files"
        print_error "Consider using Git LFS for large files."
        exit 1
    fi
    print_success "No large files detected"
    
    # 10. Check for secrets (basic patterns)
    print_status "Scanning for potential secrets..."
    if git diff --cached | grep -E "(password|secret|token|key|api[_-]?key).*=.*['\"][^'\"]{16,}['\"]" >/dev/null 2>&1; then
        print_error "Potential secrets detected in staged changes!"
        print_error "Please review and ensure no real secrets are being committed."
        exit 1
    fi
    print_success "No obvious secrets detected"
    
    print_success "All pre-commit checks passed! 🎉"
}

# Run the checks
run_precommit_checks