Skip to content

Add two-sided compare, CLI output, and a richer web UI - #4

Merged
imrajdas merged 2 commits into
mainfrom
diffr-improvements
Aug 14, 2026
Merged

Add two-sided compare, CLI output, and a richer web UI#4
imrajdas merged 2 commits into
mainfrom
diffr-improvements

Conversation

@imrajdas

@imrajdas imrajdas commented Aug 14, 2026

Copy link
Copy Markdown
Owner

This pull request introduces significant enhancements and refactoring to the core comparison logic and CLI of the diffr tool. The main changes include a complete rewrite of the file and directory comparison logic, the addition of new CLI options for greater flexibility, improved output formatting (including colorized and JSON output), and updates to dependencies and workflow configuration.

Core comparison logic and CLI improvements:

  • Major refactor: The old diff.go file has been removed and replaced with a new, modular comparison engine in compare.go, which now supports more robust directory and file comparisons, improved statistics, and extensibility for different file types. [1] [2]
  • New CLI options: The CLI now supports additional flags such as --context, --ignore-whitespace, --ignore-case, --stdout, --json, --patch, --exclude, --ignore-file, --no-default-exclude, and --no-gitignore, enabling users to customize comparison behavior and output formats. [1] [2]
  • Output enhancements: Added support for colorized diff output in the terminal (color.go) and a structured JSON output mode for integration and scripting (cli.go). [1] [2]

File type handling and extensibility:

  • Binary file support: Added logic to detect and summarize differences in binary files, including hash and size reporting, and improved patch formatting for binary changes. [1] [2]
  • Address parsing improvements: Introduced a utility for robustly parsing and displaying listen addresses and URLs for the web UI, with comprehensive tests. [1] [2]

Dependency and workflow updates:

  • Updated dependencies: Upgraded Go version to 1.26.6 and added new dependencies for PDF and gitignore support. [1] [2]
  • CI workflow: Updated GitHub Actions workflow to use the latest versions of actions and Go.

Most important changes:

1. Core comparison and CLI refactor

  • Rewrote the comparison logic in compare.go, replacing the old diff.go, enabling robust directory and file comparison, improved statistics, and extensibility for file types. [1] [2]
  • Added new CLI flags for context lines, whitespace/case ignoring, output format selection, patch file generation, exclusion patterns, and ignore file support. [1] [2]
  • Implemented structured JSON output and improved CLI reporting in cli.go.

2. Output formatting and user experience

  • Added colorized diff output for terminal display in color.go.
  • Enhanced patch generation and output, including for binary and PDF files. [1] [2]

3. File type handling

  • Introduced binary file comparison with hash and size reporting, and improved handling of binary file diffs in patches. [1] [2]

4. Address parsing and web UI

  • Added robust address parsing and display logic for the web UI, with unit tests in addr.go and addr_test.go. [1] [2]

5. Dependency and workflow updates

  • Upgraded Go version and dependencies for better compatibility and new features, and updated the CI workflow to use the latest action versions. [1] [2]

These changes significantly modernize the codebase, improve usability and extensibility, and lay the groundwork for future enhancements.

Summary by CodeRabbit

  • New Features
    • Added comprehensive file and directory comparison for text, binary, image, and PDF files.
    • Added CLI, JSON, patch-file, and colorized output options.
    • Added configurable ignore files, exclusions, whitespace/case handling, and diff context.
    • Added a responsive web dashboard with filtering, statistics, themes, and specialized media views.
    • Added image pixel-diff visualization and PDF page/text comparisons.
  • Improvements
    • Added safer server address handling and graceful shutdown.
    • Updated supported Go and build tooling versions.

Walk both trees, skip junk via ignore rules, handle binaries/images/PDFs, and add stdout/JSON plus a filterable dark-mode UI so real repos are readable instead of dumped as text.
@imrajdas
imrajdas requested a lite review from Copilot August 14, 2026 17:44
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d4721d1-6031-4ee5-8104-1289a8471c35

📥 Commits

Reviewing files that changed from the base of the PR and between 981fa80 and 1ed19b0.

⛔ Files ignored due to path filters (11)
  • go.sum is excluded by !**/*.sum
  • testdata/demo/left/assets/logo.png is excluded by !**/*.png
  • testdata/demo/left/data/blob.bin is excluded by !**/*.bin
  • testdata/demo/left/docs/notes.pdf is excluded by !**/*.pdf
  • testdata/demo/left/node_modules/left-pad/index.js is excluded by !**/node_modules/**
  • testdata/demo/left/noise.log is excluded by !**/*.log
  • testdata/demo/right/assets/logo.png is excluded by !**/*.png
  • testdata/demo/right/data/blob.bin is excluded by !**/*.bin
  • testdata/demo/right/docs/notes.pdf is excluded by !**/*.pdf
  • testdata/demo/right/node_modules/left-pad/index.js is excluded by !**/node_modules/**
  • testdata/demo/right/noise.log is excluded by !**/*.log
📒 Files selected for processing (33)
  • .github/workflows/build-check.yml
  • go.mod
  • pkg/cmd/root/root.go
  • pkg/diffr/addr.go
  • pkg/diffr/addr_test.go
  • pkg/diffr/binary.go
  • pkg/diffr/cli.go
  • pkg/diffr/color.go
  • pkg/diffr/compare.go
  • pkg/diffr/compare_test.go
  • pkg/diffr/config.go
  • pkg/diffr/diff.go
  • pkg/diffr/handler.go
  • pkg/diffr/handler_test.go
  • pkg/diffr/ignore.go
  • pkg/diffr/image.go
  • pkg/diffr/kind.go
  • pkg/diffr/pdf.go
  • pkg/diffr/text.go
  • static/static.go
  • testdata/demo/generate.go
  • testdata/demo/left/.diffrignore
  • testdata/demo/left/README.md
  • testdata/demo/left/data/config.json
  • testdata/demo/left/deprecated.txt
  • testdata/demo/left/src/app.go
  • testdata/demo/left/src/util.go
  • testdata/demo/right/.diffrignore
  • testdata/demo/right/README.md
  • testdata/demo/right/changelog.txt
  • testdata/demo/right/data/config.json
  • testdata/demo/right/src/app.go
  • testdata/demo/right/src/util.go

📝 Walkthrough

Walkthrough

The change replaces the previous web-only directory comparison with a multi-format comparison engine. It adds CLI and JSON output, ignore rules, image and PDF support, configurable HTTP serving, and an interactive dashboard.

Changes

Diffr comparison flow

Layer / File(s) Summary
Comparison contracts and input filtering
go.mod, .github/workflows/build-check.yml, pkg/diffr/config.go, pkg/diffr/compare.go, pkg/diffr/ignore.go, pkg/diffr/kind.go
The package adds comparison result types, options, file-kind detection, ignore loading, and Go toolchain updates.
File comparison engines and validation
pkg/diffr/compare.go, pkg/diffr/text.go, pkg/diffr/binary.go, pkg/diffr/image.go, pkg/diffr/pdf.go, pkg/diffr/compare_test.go, testdata/demo/*
The comparison pipeline handles text, binary, image, and PDF files. Tests and demo fixtures cover statuses, patches, filtering, normalization, and media differences.
CLI execution and output
pkg/cmd/root/root.go, pkg/diffr/cli.go, pkg/diffr/color.go
The root command binds comparison flags. CLI output supports JSON, patches, terminal color, patch files, and summary reporting.
Web server and media delivery
pkg/diffr/handler.go, pkg/diffr/addr.go, pkg/diffr/handler_test.go
Run compares inputs, serves scoped HTTP routes, renders structured results, serves media safely, launches the browser optionally, and shuts down gracefully.
Interactive diff dashboard
static/static.go
The embedded dashboard adds themes, format selection, filtering, statistics, text and PDF sections, and synchronized image comparisons.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Run
  participant Compare
  participant Output
  participant HTTPServer
  CLI->>Run: pass paths and flags
  Run->>Compare: build Options and compare paths
  Compare-->>Run: return Result
  alt CLI output requested
    Run->>Output: write JSON or patch
  else Web output requested
    Run->>HTTPServer: serve Result
    HTTPServer-->>CLI: render dashboard and media
  end
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch diffr-improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@imrajdas
imrajdas merged commit cd2786e into main Aug 14, 2026
2 of 3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes diffr by replacing the legacy diff implementation with a modular comparison engine that supports two-sided directory/file comparison, multiple file kinds (text/binary/image/PDF), richer CLI outputs (stdout patch + JSON), and a significantly expanded web UI (stats, filtering, dark mode, media viewers).

Changes:

  • Replaced the old directory-walk diff implementation with a new Compare(...) engine that produces structured results, stats, and patch output.
  • Added CLI output modes (JSON, patch/stdout) plus ignore/exclude controls and context/whitespace/case options.
  • Expanded the web UI to include filtering, dark mode, and dedicated renderers for images/PDFs/binaries.

Reviewed changes

Copilot reviewed 33 out of 44 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
testdata/demo/right/src/util.go Demo fixture (right tree) for identical Go helper
testdata/demo/right/src/app.go Demo fixture (right tree) with changed greeting
testdata/demo/right/README.md Demo fixture (right tree) README content change
testdata/demo/right/noise.log Demo fixture (right tree) ignored-by-pattern example
testdata/demo/right/node_modules/left-pad/index.js Demo fixture (right tree) default-exclude example
testdata/demo/right/data/config.json Demo fixture (right tree) JSON config changes
testdata/demo/right/changelog.txt Demo fixture (right tree) right-only file
testdata/demo/right/.diffrignore Demo fixture (right tree) ignore patterns
testdata/demo/left/src/util.go Demo fixture (left tree) for identical Go helper
testdata/demo/left/src/app.go Demo fixture (left tree) baseline greeting
testdata/demo/left/README.md Demo fixture (left tree) README baseline
testdata/demo/left/noise.log Demo fixture (left tree) ignored-by-pattern example
testdata/demo/left/node_modules/left-pad/index.js Demo fixture (left tree) default-exclude example
testdata/demo/left/deprecated.txt Demo fixture (left tree) left-only file
testdata/demo/left/data/config.json Demo fixture (left tree) JSON config baseline
testdata/demo/left/.diffrignore Demo fixture (left tree) ignore patterns
testdata/demo/generate.go Generator for demo fixture trees (including png/pdf/bin)
static/static.go Reworked embedded web UI template (dark mode, filtering, media views)
pkg/diffr/text.go Text diffing + normalization (ignore-case/whitespace) + unified diff generation
pkg/diffr/pdf.go PDF text extraction and PDF-aware comparison behavior
pkg/diffr/kind.go File kind sniffing (text/binary/image/pdf) and kind merging
pkg/diffr/image.go Image decode, pixel diff generation, and summary logic
pkg/diffr/ignore.go Default excludes + .diffrignore/.gitignore integration and --exclude support
pkg/diffr/handler.go New run path (CLI vs web), web server mux, media routes, and page-data shaping
pkg/diffr/handler_test.go Web template parsing + page-data behavior tests
pkg/diffr/diff.go Removed legacy diff implementation
pkg/diffr/config.go Added global config flags backing CLI options
pkg/diffr/compare.go New core compare engine producing Result, Stats, and patch output
pkg/diffr/compare_test.go Extensive test suite covering compare behaviors and output helpers
pkg/diffr/color.go ANSI colorization for stdout patch output
pkg/diffr/cli.go JSON output and CLI writer for stdout/patch reporting
pkg/diffr/binary.go Binary hashing, size summaries, and binary-kind compare fallback
pkg/diffr/addr.go Listen/display address parsing utility for web UI
pkg/diffr/addr_test.go Unit tests for listen/display address parsing
pkg/cmd/root/root.go Updated Cobra root command to use new runner + new flags
go.sum Dependency updates for PDF + gitignore support (and test deps)
go.mod Go version + dependency additions for new features
.github/workflows/build-check.yml CI workflow updates (actions versions + Go version)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread go.mod
module github.com/imrajdas/diffr

go 1.20
go 1.26.6
Comment on lines 19 to +22
- name: Set up Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: '1.20'
go-version: '1.26.6'
Comment thread pkg/diffr/addr.go
Comment on lines +25 to +32
if u.Scheme != "" {
scheme = u.Scheme
}
if h := u.Hostname(); h != "" {
host = h
} else if u.Host != "" {
host = u.Host
}
Comment thread pkg/diffr/handler.go
Comment on lines 30 to 32
case "windows":
cmd = exec.Command("cmd", "/c", "start", url)
cmd = exec.Command("cmd", "/c", "start", rawURL)
default:
Comment thread pkg/diffr/text.go
Comment on lines +56 to +74
func normalizeText(s string, opts Options) string {
if !opts.IgnoreCase && !opts.IgnoreWhitespace {
return s
}
lines := splitLines(s)
var b strings.Builder
for _, line := range lines {
line = strings.TrimSuffix(line, "\n")
if opts.IgnoreWhitespace {
line = strings.Join(strings.Fields(line), "")
}
if opts.IgnoreCase {
line = strings.ToLower(line)
}
b.WriteString(line)
b.WriteByte('\n')
}
return b.String()
}
Comment thread pkg/diffr/compare.go
Comment on lines +85 to +89
func Compare(left, right string, opts Options) (*Result, error) {
start := time.Now()
if opts.Context <= 0 {
opts.Context = 3
}
Comment thread pkg/diffr/image.go
Comment on lines +38 to +39
lb, rb := left.Bounds(), right.Bounds()
if lb.Dx()*lb.Dy() > maxPixels || rb.Dx()*rb.Dy() > maxPixels {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants