/ scripts / ci-setup.sh
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