Gemini CLI excels at batch code analysis, making it ideal for automated code reviews, security audits, and quality checks across entire codebases. This guide covers how to process multiple files, generate reports, and integrate Gemini CLI into automated workflows.
Prerequisites
Before starting, ensure you have:
- Gemini CLI installed (see How to Install Gemini CLI)
- Node.js 20+ installed
- jq installed for JSON parsing (optional but recommended)
To install jq:
macOS:
brew install jq
Windows (PowerShell):
winget install jqlang.jq
Linux (Debian/Ubuntu):
sudo apt-get install jq
Non-Interactive Mode for Scripting
Gemini CLI supports non-interactive mode, which is essential for automation. Pass your prompt directly without entering the interactive shell.
Basic Non-Interactive Usage
# Simple prompt
gemini "What is the gcloud command to deploy to Cloud Run"
# With the -p flag (equivalent)
gemini -p "Explain the purpose of this Dockerfile"
# Piping file content
cat src/auth.py | gemini -p "Review this authentication code for security issues"
# Using file redirection
gemini -p "Summarize this log file:" < application.log
Getting Structured JSON Output
For scripting, use --output-format json to get parseable output:
gemini -p "Explain Docker containers" --output-format json
This returns a JSON object containing:
response: The AI-generated textstats: Token usage and model informationmetadata: Request details
Parsing JSON Output with jq
Extract specific fields from the JSON response:
# Extract just the response text
gemini -p "What is Kubernetes?" --output-format json | jq -r '.response'
# Get token statistics
gemini -p "Explain microservices" --output-format json | jq '.stats'
# Save structured output to file
gemini -p "Analyze this code" --output-format json > analysis.json
Analyzing Multiple Files
Gemini CLI provides several methods for analyzing multiple files simultaneously.
Using @ Directory References
Reference entire directories with the @ syntax:
# Analyze all files in a directory
gemini "Review the code quality in @./src/"
# Multiple directory references
gemini "Compare the authentication approach in @./api/auth/ versus @./lib/security/"
# Specific file patterns
gemini "Find security issues in @./src/**/*.ts"
The trailing slash indicates a directory reference. Gemini CLI recursively includes files while respecting .gitignore patterns.
Using the read_many_files Tool
For more control, use the built-in read_many_files tool in interactive mode:
gemini
> Read all TypeScript files in src/ and identify unused exports
The tool supports parameters like:
recursive: Search subdirectories (default: true)exclude: Glob patterns to skip (e.g.,["**/*.test.ts"])useDefaultExcludes: Skip node_modules, .git, etc. (default: true)respect_git_ignore: Honor .gitignore patterns (default: true)
Batch Processing with Shell Scripts
Basic Batch Analysis Script (macOS/Linux)
Process multiple files and generate individual reports:
#!/bin/bash
# analyze-files.sh - Batch code analysis with Gemini CLI
OUTPUT_DIR="./analysis-reports"
mkdir -p "$OUTPUT_DIR"
for file in src/*.py; do
if [ -f "$file" ]; then
echo "Analyzing: $file"
result=$(cat "$file" | gemini -p "Analyze this Python code for:
1. Potential bugs
2. Security vulnerabilities
3. Performance issues
4. Code style improvements
Provide specific line numbers and suggestions." --output-format json)
# Extract response and save
echo "$result" | jq -r '.response' > "$OUTPUT_DIR/$(basename "$file").analysis.md"
# Rate limit protection
sleep 2
fi
done
echo "Analysis complete. Reports saved to $OUTPUT_DIR"
Make executable and run:
chmod +x analyze-files.sh
./analyze-files.sh
Windows PowerShell Batch Script
# analyze-files.ps1 - Batch code analysis for Windows
$OutputDir = ".\analysis-reports"
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
Get-ChildItem -Path ".\src\*.py" | ForEach-Object {
$file = $_
Write-Host "Analyzing: $($file.Name)"
$content = Get-Content $file.FullName -Raw
$prompt = @"
Analyze this Python code for:
1. Potential bugs
2. Security vulnerabilities
3. Performance issues
4. Code style improvements
Provide specific line numbers and suggestions.
$content
"@
$result = gemini -p $prompt --output-format json | ConvertFrom-Json
$result.response | Out-File "$OutputDir\$($file.BaseName).analysis.md"
# Rate limit protection
Start-Sleep -Seconds 2
}
Write-Host "Analysis complete. Reports saved to $OutputDir"
Recursive Directory Analysis
Analyze an entire codebase with a consolidated report:
#!/bin/bash
# full-codebase-review.sh
PROJECT_DIR="${1:-.}"
REPORT_FILE="codebase-review-$(date +%Y%m%d).md"
echo "# Codebase Review Report" > "$REPORT_FILE"
echo "Generated: $(date)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# Use Gemini CLI's directory reference for full context
gemini "Perform a comprehensive code review of @$PROJECT_DIR/
Include:
1. Architecture overview
2. Code quality assessment
3. Security concerns
4. Performance bottlenecks
5. Recommended improvements
Format as markdown with sections." --output-format json | jq -r '.response' >> "$REPORT_FILE"
echo "Report saved to: $REPORT_FILE"
Automated Code Review Workflows
Git Pre-Commit Hook
Create .git/hooks/pre-commit:
#!/bin/bash
# Pre-commit hook for automated code review
# Get staged files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|py|go)$')
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
echo "Running Gemini code review on staged files..."
# Create temporary file with all changes
DIFF_CONTENT=$(git diff --cached)
result=$(echo "$DIFF_CONTENT" | gemini -p "Review these code changes for:
1. Bugs or logic errors
2. Security vulnerabilities
3. Breaking changes
If critical issues found, start response with 'BLOCK:' followed by the reason.
Otherwise start with 'PASS:' followed by any suggestions." --output-format json)
response=$(echo "$result" | jq -r '.response')
if echo "$response" | grep -q "^BLOCK:"; then
echo "Code review failed:"
echo "$response"
exit 1
fi
echo "Code review passed:"
echo "$response"
exit 0
Make executable:
chmod +x .git/hooks/pre-commit
Pull Request Analysis Script
#!/bin/bash
# pr-review.sh - Analyze PR changes
BASE_BRANCH="${1:-main}"
# Get diff against base branch
DIFF=$(git diff origin/$BASE_BRANCH...HEAD)
if [ -z "$DIFF" ]; then
echo "No changes to review"
exit 0
fi
result=$(echo "$DIFF" | gemini -p "Review this pull request diff for:
1. **Bugs**: Logic errors, edge cases, null handling
2. **Security**: Injection, authentication, data exposure
3. **Performance**: N+1 queries, memory leaks, blocking calls
4. **Code Quality**: Naming, complexity, duplication
Format as markdown with severity levels (Critical/Warning/Info)." --output-format json)
echo "$result" | jq -r '.response' > pr-review.md
echo "PR review saved to pr-review.md"
Using the Code Review Extension
Gemini CLI has an official Code Review extension for structured reviews.
Installing the Extension
gemini extensions install https://github.com/gemini-cli-extensions/code-review
Verify installation:
gemini extensions list
Running Code Reviews
In interactive mode:
gemini
> /code-review
In non-interactive mode (for CI/CD):
gemini -p "/code-review" --yolo
The extension analyzes changes on your current branch and identifies:
- Code quality issues
- Potential bugs
- Security vulnerabilities
- Style inconsistencies
CI/CD Integration
GitHub Actions Example
# .github/workflows/code-review.yml
name: Gemini Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Gemini CLI
run: npm install -g @google/gemini-cli
- name: Run Code Review
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
run: |
git diff origin/${{ github.base_ref }}...HEAD > changes.diff
cat changes.diff | gemini -p "Review these changes and provide feedback in markdown format" --output-format json | jq -r '.response' > review.md
- name: Post Review Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: review
});
GitLab CI Example
# .gitlab-ci.yml
code-review:
stage: test
image: node:20
script:
- npm install -g @google/gemini-cli
- git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD > changes.diff
- cat changes.diff | gemini -p "Review these code changes" --output-format json | jq -r '.response' > review.md
- cat review.md
artifacts:
paths:
- review.md
only:
- merge_requests
variables:
GEMINI_API_KEY: $GEMINI_API_KEY
Generating Consolidated Reports
Multi-File Analysis Report
#!/bin/bash
# generate-report.sh - Create consolidated analysis report
REPORT="code-analysis-report.md"
cat > "$REPORT" << 'EOF'
# Code Analysis Report
Generated: $(date)
## Summary
EOF
# Security Analysis
echo "## Security Analysis" >> "$REPORT"
gemini "Analyze @./src/ for security vulnerabilities. List findings by severity." --output-format json | jq -r '.response' >> "$REPORT"
echo "" >> "$REPORT"
# Performance Analysis
echo "## Performance Analysis" >> "$REPORT"
gemini "Identify performance bottlenecks in @./src/. Focus on database queries, loops, and memory usage." --output-format json | jq -r '.response' >> "$REPORT"
echo "" >> "$REPORT"
# Code Quality
echo "## Code Quality" >> "$REPORT"
gemini "Assess code quality in @./src/. Check for duplication, complexity, and naming conventions." --output-format json | jq -r '.response' >> "$REPORT"
echo "Report generated: $REPORT"
CSV Output for Tracking
#!/bin/bash
# issues-to-csv.sh - Extract issues as CSV
echo "file,severity,category,description" > issues.csv
for file in src/*.ts; do
result=$(cat "$file" | gemini -p "List issues in this code as JSON array with fields: severity (high/medium/low), category, description. Return ONLY valid JSON array, no markdown." --output-format json)
issues=$(echo "$result" | jq -r '.response')
# Parse JSON issues and append to CSV
echo "$issues" | jq -r --arg file "$file" '.[] | [$file, .severity, .category, .description] | @csv' >> issues.csv 2>/dev/null
sleep 2
done
echo "Issues exported to issues.csv"
Performance Tips
Optimize for Rate Limits
# Process in batches with delays
BATCH_SIZE=5
COUNT=0
for file in src/**/*.ts; do
# Process file...
COUNT=$((COUNT + 1))
if [ $((COUNT % BATCH_SIZE)) -eq 0 ]; then
echo "Processed $COUNT files, pausing..."
sleep 10
fi
done
Combine Files for Fewer Requests
Instead of analyzing files individually, combine related files:
# Combine all files in a module for single analysis
gemini "Analyze the entire authentication module: @./src/auth/" --output-format json
Use Streaming for Long Operations
For real-time feedback during long analyses:
gemini -p "Comprehensive review of @./src/" --output-format stream-json
Troubleshooting
"Rate limit exceeded" Errors
Add delays between requests or reduce batch size:
sleep 3 # Wait 3 seconds between requests
JSON Parsing Errors
Ensure you are using --output-format json and validate with jq:
gemini -p "test" --output-format json | jq '.' || echo "Invalid JSON"
Tool Permission Errors in Non-Interactive Mode
Add --yolo flag to auto-approve tool operations (use with caution):
gemini -p "Fix all linting errors in @./src/" --yolo
Large Directory Timeouts
For very large codebases, analyze subdirectories separately:
for dir in src/*/; do
gemini "Analyze @$dir" --output-format json > "reports/$(basename $dir).json"
done