ci-setup.sh
1 #!/bin/bash 2 set -euo pipefail 3 4 # FerrisProof CI Setup Script 5 # Installs necessary tools for local development and CI 6 7 # Colors for output 8 RED='\033[0;31m' 9 GREEN='\033[0;32m' 10 YELLOW='\033[1;33m' 11 BLUE='\033[0;34m' 12 NC='\033[0m' # No Color 13 14 log_info() { 15 echo -e "${BLUE}[INFO]${NC} $1" 16 } 17 18 log_success() { 19 echo -e "${GREEN}[SUCCESS]${NC} $1" 20 } 21 22 log_warning() { 23 echo -e "${YELLOW}[WARNING]${NC} $1" 24 } 25 26 log_error() { 27 echo -e "${RED}[ERROR]${NC} $1" 28 } 29 30 install_rust_components() { 31 log_info "Installing Rust components..." 32 33 # Essential components 34 rustup component add rustfmt clippy 35 36 # Optional but recommended components 37 if rustup component add llvm-tools-preview 2>/dev/null; then 38 log_success "llvm-tools-preview installed" 39 else 40 log_warning "llvm-tools-preview not available for this toolchain" 41 fi 42 43 log_success "Rust components installed" 44 } 45 46 install_cargo_tools() { 47 log_info "Installing useful Cargo tools..." 48 49 local tools=( 50 "cargo-audit:Security auditing" 51 "cargo-llvm-cov:Code coverage" 52 "cargo-udeps:Unused dependencies detection" 53 "cargo-watch:File watching for development" 54 "cargo-nextest:Faster test runner" 55 "cargo-deny:Dependency management" 56 ) 57 58 for tool_info in "${tools[@]}"; do 59 local tool_name="${tool_info%%:*}" 60 local tool_desc="${tool_info##*:}" 61 62 if cargo install --list | grep -q "^$tool_name "; then 63 log_info "$tool_name already installed" 64 else 65 log_info "Installing $tool_name ($tool_desc)..." 66 if cargo install "$tool_name"; then 67 log_success "$tool_name installed" 68 else 69 log_warning "Failed to install $tool_name" 70 fi 71 fi 72 done 73 } 74 75 setup_git_hooks() { 76 log_info "Setting up Git hooks..." 77 78 # Create hooks directory if it doesn't exist 79 mkdir -p .git/hooks 80 81 # Pre-commit hook 82 cat > .git/hooks/pre-commit << 'EOF' 83 #!/bin/bash 84 # FerrisProof pre-commit hook 85 86 set -e 87 88 echo "Running pre-commit checks..." 89 90 # Quick format and lint check 91 if ! cargo fmt --all -- --check; then 92 echo "❌ Code formatting issues found. Run 'cargo fmt' to fix." 93 exit 1 94 fi 95 96 if ! cargo clippy --all-targets --all-features -- -D warnings; then 97 echo "❌ Clippy warnings found. Please fix them." 98 exit 1 99 fi 100 101 # Quick build check 102 if ! cargo check --all-features; then 103 echo "❌ Build check failed." 104 exit 1 105 fi 106 107 echo "✅ Pre-commit checks passed!" 108 EOF 109 110 # Pre-push hook 111 cat > .git/hooks/pre-push << 'EOF' 112 #!/bin/bash 113 # FerrisProof pre-push hook 114 115 set -e 116 117 echo "Running pre-push checks..." 118 119 # Run the quick CI pipeline 120 if [ -f "scripts/ci-local.sh" ]; then 121 ./scripts/ci-local.sh --quick 122 else 123 echo "⚠️ Local CI script not found, running basic checks..." 124 cargo test --all-features 125 fi 126 127 echo "✅ Pre-push checks passed!" 128 EOF 129 130 # Make hooks executable 131 chmod +x .git/hooks/pre-commit .git/hooks/pre-push 132 133 log_success "Git hooks installed" 134 } 135 136 setup_vscode_settings() { 137 log_info "Setting up VS Code settings..." 138 139 mkdir -p .vscode 140 141 # VS Code settings 142 cat > .vscode/settings.json << 'EOF' 143 { 144 "rust-analyzer.cargo.features": "all", 145 "rust-analyzer.checkOnSave.command": "clippy", 146 "rust-analyzer.checkOnSave.allFeatures": true, 147 "rust-analyzer.cargo.buildScripts.enable": true, 148 "editor.formatOnSave": true, 149 "editor.codeActionsOnSave": { 150 "source.fixAll": true 151 }, 152 "[rust]": { 153 "editor.defaultFormatter": "rust-lang.rust-analyzer", 154 "editor.formatOnSave": true 155 }, 156 "files.watcherExclude": { 157 "**/target/**": true 158 }, 159 "search.exclude": { 160 "**/target": true, 161 "**/.git": true 162 } 163 } 164 EOF 165 166 # VS Code tasks 167 cat > .vscode/tasks.json << 'EOF' 168 { 169 "version": "2.0.0", 170 "tasks": [ 171 { 172 "label": "cargo check", 173 "type": "cargo", 174 "command": "check", 175 "args": ["--all-features"], 176 "group": "build", 177 "presentation": { 178 "clear": true 179 } 180 }, 181 { 182 "label": "cargo test", 183 "type": "cargo", 184 "command": "test", 185 "args": ["--all-features"], 186 "group": "test", 187 "presentation": { 188 "clear": true 189 } 190 }, 191 { 192 "label": "cargo clippy", 193 "type": "cargo", 194 "command": "clippy", 195 "args": ["--all-targets", "--all-features", "--", "-D", "warnings"], 196 "group": "build", 197 "presentation": { 198 "clear": true 199 } 200 }, 201 { 202 "label": "Local CI", 203 "type": "shell", 204 "command": "./scripts/ci-local.sh", 205 "group": "test", 206 "presentation": { 207 "clear": true 208 } 209 } 210 ] 211 } 212 EOF 213 214 log_success "VS Code settings configured" 215 } 216 217 create_makefile() { 218 log_info "Creating Makefile for common tasks..." 219 220 cat > Makefile << 'EOF' 221 # FerrisProof Makefile 222 # Common development tasks 223 224 .PHONY: help check test build clean fmt lint audit coverage doc ci-local container-build 225 226 # Default target 227 help: 228 @echo "FerrisProof Development Tasks" 229 @echo "" 230 @echo "Available targets:" 231 @echo " check - Quick check (format, lint, build)" 232 @echo " test - Run all tests" 233 @echo " build - Build in release mode" 234 @echo " clean - Clean build artifacts" 235 @echo " fmt - Format code" 236 @echo " lint - Run clippy" 237 @echo " audit - Security audit" 238 @echo " coverage - Generate coverage report" 239 @echo " doc - Generate documentation" 240 @echo " ci-local - Run local CI pipeline" 241 @echo " container - Build container image" 242 243 # Quick development checks 244 check: 245 cargo fmt --all -- --check 246 cargo clippy --all-targets --all-features -- -D warnings 247 cargo build --all-features 248 249 # Run tests 250 test: 251 cargo test --all-features 252 cargo test --all-features -- --ignored 253 254 # Build release 255 build: 256 cargo build --release --all-features 257 258 # Clean artifacts 259 clean: 260 cargo clean 261 262 # Format code 263 fmt: 264 cargo fmt --all 265 266 # Lint code 267 lint: 268 cargo clippy --all-targets --all-features -- -D warnings 269 270 # Security audit 271 audit: 272 cargo audit 273 274 # Generate coverage report 275 coverage: 276 cargo llvm-cov --all-features --workspace --html 277 278 # Generate documentation 279 doc: 280 cargo doc --all-features --no-deps --open 281 282 # Run local CI 283 ci-local: 284 ./scripts/ci-local.sh 285 286 # Build container 287 container: 288 ./scripts/container-build.sh build 289 290 # Install development dependencies 291 setup: 292 ./scripts/ci-setup.sh 293 EOF 294 295 log_success "Makefile created" 296 } 297 298 main() { 299 log_info "Setting up FerrisProof development environment..." 300 301 # Check if Rust is installed 302 if ! command -v cargo &> /dev/null; then 303 log_error "Rust/Cargo not found. Please install Rust first: https://rustup.rs/" 304 exit 1 305 fi 306 307 install_rust_components 308 install_cargo_tools 309 setup_git_hooks 310 setup_vscode_settings 311 create_makefile 312 313 log_success "Development environment setup complete! 🎉" 314 echo 315 log_info "Next steps:" 316 echo " • Run 'make check' to verify everything works" 317 echo " • Run 'make ci-local' to run the full CI pipeline" 318 echo " • Run 'make help' to see all available commands" 319 echo " • Check .vscode/settings.json for VS Code configuration" 320 } 321 322 case "${1:-}" in 323 --help|-h) 324 echo "FerrisProof CI Setup Script" 325 echo 326 echo "Usage: $0 [OPTIONS]" 327 echo 328 echo "This script sets up the development environment with:" 329 echo " • Rust components (rustfmt, clippy, etc.)" 330 echo " • Useful Cargo tools" 331 echo " • Git hooks for pre-commit/pre-push checks" 332 echo " • VS Code settings and tasks" 333 echo " • Makefile for common tasks" 334 echo 335 echo "Options:" 336 echo " --help, -h Show this help message" 337 exit 0 338 ;; 339 "") 340 main 341 ;; 342 *) 343 log_error "Unknown option: $1" 344 echo "Use --help for usage information" 345 exit 1 346 ;; 347 esac