Skip to main content

GitLab code review tracking for scientific software

Project description

glreview

Track code review coverage with git-level precision. Know exactly which modules have been reviewed, at which commit, and what changed since.

The Problem

Code review is usually per-PR, but that doesn't answer: "Has this module ever been thoroughly reviewed?" Teams maintaining critical software need to know:

  • Which files have never been reviewed?
  • Which reviews are stale because the code changed?
  • How much of the codebase has review coverage?

glreview tracks review status per-module, persisted in git, integrated with GitLab issues.

What It Looks Like

$ glreview status

Review Status
─────────────────────────────────────────────────────
Reviewed:     12 modules (2,450 lines)  ██████████░░ 48%
In Progress:   2 modules (380 lines)
Needs Review: 11 modules (1,890 lines)

Stale (changed since review):
  src/core/engine.py      changed 3 days ago
  src/utils/helpers.py    changed 1 week ago

In Progress:
  src/api/handlers.py     issue #142, @alice

Needs Review:
  src/auth/oauth.py       245 lines
  src/core/scheduler.py   189 lines
  src/api/middleware.py   156 lines

Installation

Prerequisites: Python 3.9+, git repository, GitLab project

pip install glreview

For AI-assisted review features, also install Claude Code.

Quick Start

1. Configure source patterns

Add to pyproject.toml:

[tool.glreview]
sources = ["src/**/*.py"]
exclude = ["**/test_*.py", "**/_version.py"]

2. Set up GitLab authentication

export GITLAB_PRIVATE_TOKEN=glpat-xxxxxxxxxxxx

# For self-hosted GitLab:
export GITLAB_URL=https://gitlab.example.com

3. Initialize

glreview init

This creates .glreview/registry.json. Commit it to version control.

4. Start reviewing

# See what needs review
glreview status

# Start a review (creates GitLab issue)
glreview start src/mymodule.py --assignee @reviewer

# After reviewer closes the issue, sign off
glreview signoff src/mymodule.py

# Commit the updated registry
git add .glreview/ && git commit -m "review: src/mymodule.py"

Core Workflow

Review lifecycle

┌─────────────┐
│ needs_review│◄──────────────────┐
└──────┬──────┘                   │
       │ start                    │ cancel (or code changes)
       ▼                          │
┌─────────────┐                   │
│ in_progress │───────────────────┤
└──────┬──────┘                   │
       │ signoff                  │
       ▼                          │
┌─────────────┐                   │
│  reviewed   │───────────────────┘
└─────────────┘

Starting a review

# Basic - creates GitLab issue
glreview start src/module.py

# With assignee
glreview start src/module.py --assignee @alice

# Link to existing issue instead of creating new
glreview start src/module.py --issue "https://gitlab.com/.../issues/42"

Signing off

# Standard signoff (verifies GitLab issue is closed)
glreview signoff src/module.py

# Skip issue verification
glreview signoff src/module.py --skip-verify

# With explicit reviewer name
glreview signoff src/module.py --reviewer @bob

Handling changes during review

If code changes while a review is in progress:

# See what changed
glreview diff src/module.py --since-start

# Option 1: Acknowledge changes and sign off anyway
glreview signoff src/module.py --acknowledge

# Option 2: Cancel and restart at current commit
glreview cancel src/module.py --restart

Viewing diffs

# Changes since last review (deciding whether to re-review)
glreview diff src/module.py

# Changes during current review (before signing off)
glreview diff src/module.py --since-start

# Open in GitLab web UI
glreview diff src/module.py --web

AI-Assisted Review (Optional)

glreview integrates with Claude Code for automated code analysis. This is entirely optional - the core workflow works without it.

Setup

# Verify Claude CLI is installed
claude --version

# Generate project context (one-time)
glreview claude-init

This creates .glreview/context.json with project conventions, module relationships, and test file mappings. Commit it to version control.

Running AI review

# Run review (prints findings to terminal)
glreview claude-review src/module.py

# Post findings to GitLab issue
glreview claude-review src/module.py --post

# Preview the prompt without running
glreview claude-review src/module.py --dry-run

Reviews evaluate six criteria:

  • Correctness - Logic errors, wrong results, unhandled edge cases
  • Error Handling - Input validation, failure handling, resource leaks
  • Code Quality - DRY, organization, naming, appropriate abstractions
  • Testing - Coverage, meaningful assertions, edge cases
  • Documentation - Non-obvious decisions explained, API documented
  • Risk - Security, performance, data integrity (when applicable)

Each finding is rated OK, SUGGESTED, or REQUIRED.

Fixing issues

# Interactive - choose which items to fix
glreview claude-fix src/module.py

# Batch - fix all REQUIRED items automatically
glreview claude-fix src/module.py --batch

Updating context

# After significant codebase changes
glreview claude-sync

# View context for a module
glreview claude-context src/module.py

Batch Operations

Start reviews for multiple modules at once:

# Start reviews for all modules needing review
glreview batch-start

# Preview what would happen
glreview batch-start --dry-run

# Also run Claude review for each (posts to issues)
glreview batch-start --claude-review

CI Integration

Automatically sync the registry and generate reports on every push.

Setup

  1. Create a Project Access Token (Settings → Access Tokens) with write_repository scope
  2. Add as CI variable: PUSH_TOKEN
  3. Add to .gitlab-ci.yml:
review-sync:
  script:
    - pip install glreview
    - git config user.email "ci@$CI_SERVER_HOST"
    - git config user.name "GitLab CI"
    - git remote set-url origin "https://oauth2:${PUSH_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
    - git checkout $CI_COMMIT_BRANCH
    - glreview sync
    - glreview report --format markdown --output REVIEW_COVERAGE.md
    - git add .glreview/ REVIEW_COVERAGE.md
    - 'git diff --cached --quiet || git commit -m "chore: update review registry"'
    - git push origin HEAD:$CI_COMMIT_BRANCH -o ci.skip
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Run glreview ci-config for complete configuration including MR checks and release gates.

CI checks

# Fail if reviewed files have uncommitted registry changes
glreview check

# Use in CI to gate merges
glreview check --strict

Configuration Reference

Full pyproject.toml options:

[tool.glreview]
# Source file patterns (required)
sources = ["src/**/*.py", "lib/**/*.py"]

# Patterns to exclude
exclude = ["**/test_*.py", "**/_version.py", "**/conftest.py"]

# Registry file location (default: .glreview/registry.json)
registry = ".glreview/registry.json"

# Default labels for created issues
issue_labels = ["review::pending", "team::backend"]

# Custom issue template (Jinja2)
issue_template = ".glreview/issue_template.md"

# Reviewer teams (use with --assignee @team/security)
[tool.glreview.teams]
security = ["@alice", "@bob"]
frontend = ["@carol", "@dave"]

Custom issue templates

Create a Jinja2 template with access to these variables:

Variable Description
path Module path
lines Line count
current_commit Current git commit
previous_commit Last reviewed commit (re-reviews)
diff_url GitLab compare URL (re-reviews)
classes List of public classes
functions List of public functions

Commands

Command Description
init Initialize glreview in a project
status Show review progress and what needs attention
start PATH Start a review, create GitLab issue
signoff PATH Sign off on completed review
cancel PATH Cancel review (--restart to restart at HEAD)
diff PATH Show changes since last review
sync Sync registry with filesystem changes
list List all tracked modules
report Generate coverage report (markdown/json/badge)
check CI check for uncommitted changes
batch-start Start reviews for all pending modules
reviewers List configured reviewers
ci-config Print recommended CI configuration
claude-review PATH Run AI code review
claude-fix PATH Fix issues from AI review
claude-init Generate AI project context
claude-sync Update AI context
claude-context View AI context

Use glreview COMMAND --help for detailed options.

Troubleshooting

"Module not found in registry" Run glreview sync to add new files, or check your sources patterns in pyproject.toml.

"GitLab API not available" Set GITLAB_PRIVATE_TOKEN. For self-hosted GitLab, also set GITLAB_URL.

"Issue not closed" Close the GitLab issue before signing off. Use --skip-verify to bypass this check.

"File changed during review" Code was modified after start. Use --acknowledge to sign off anyway, or cancel --restart to restart.

Claude commands not working Install Claude Code CLI: https://claude.ai/code

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

glreview-0.4.0.tar.gz (85.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

glreview-0.4.0-py3-none-any.whl (60.6 kB view details)

Uploaded Python 3

File details

Details for the file glreview-0.4.0.tar.gz.

File metadata

  • Download URL: glreview-0.4.0.tar.gz
  • Upload date:
  • Size: 85.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for glreview-0.4.0.tar.gz
Algorithm Hash digest
SHA256 cdcb1a59df66345649d0b7076b70e6a4f2d0e27e96750d7c5036459a2a5d3444
MD5 de548424c386ce0dba24c290f4393686
BLAKE2b-256 48aea50961364f2824edf34a4ec374a6eb31cfbc4b82cebf6fbb36230e837918

See more details on using hashes here.

File details

Details for the file glreview-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: glreview-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 60.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for glreview-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c94238f6e1404fb4c168ce27e22befb17aae3aa48d7a2b2eb75d66c4ec1c72d7
MD5 acd02aafdc2984c2d910c5f7917a8f52
BLAKE2b-256 c4748f56433d5427d4e7c9a1d62bb7b94b958c941fcd8e8142d67a49c9b74e9b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page