Geminiintermediate

How to Use Gemini CLI for Batch Code Analysis

Learn how to use Gemini CLI for batch code analysis, automated code reviews, and processing multiple files. Includes shell scripting examples, output formatting, and CI/CD integration patterns.

12 min readUpdated January 2025

Want us to handle this for you?

Get expert help →

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 text
  • stats: Token usage and model information
  • metadata: 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

Frequently Asked Questions

Find answers to common questions

Yes, Gemini CLI can analyze entire codebases thanks to its 1 million token context window. Use directory references like @./src/ to include all files recursively, or use the read_many_files tool with glob patterns. The CLI respects .gitignore patterns and excludes common directories like node_modules by default.

Need Professional IT & Security Help?

Our team of experts is ready to help protect and optimize your technology infrastructure.