Skip to content
CAI
Software that uses CAICheck a score

sebastianbergmann/diff

75.2

Strong · 26 September 2026

1.6k

lines of production code

PHP

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a PHP library that computes differences between text files using Myers' algorithm and formats the results as unified diffs. It provides a structured API with value objects for lines and chunks, allowing users to generate either strict standard-compliant diffs or simplified outputs. The library includes a parser to reconstruct diff objects from strings and is built with modern PHP standards, strict static analysis, and comprehensive test coverage.

How it got here

2013 — Core diff engine rewrite and modernization

4 changes.

The project overhauled its core diffing logic by implementing the Myers algorithm and introducing new value objects like Chunk and Line, significantly improving performance and API structure. This major refactoring was accompanied by a comprehensive modernization of the development environment, including upgrading to PHP 8.4, switching static analysis to PHPStan, and updating build tooling.

2014–2017 — Unified diff output and exception handling

4 changes.

This period focused on enhancing the library's diff output capabilities by introducing strict and loose unified diff builders, allowing users to choose between standard-compliant and simplified formats. It also established a robust exception handling framework with custom interfaces and specific exception classes for configuration and calculation errors. Comprehensive test coverage was added to validate the new output builders and parsing logic for multi-chunk diffs.

2018–2025 — test coverage and tooling updates

6 changes.

This period focused on expanding test coverage for exception handling and unified diff output generation, including new integration tests and validation utilities. It also involved updating static analysis tooling to newer versions and introducing a script to automate release note extraction from the changelog.

Features

New script to extract release notes from changelog

A new PHP script, extract-release-notes.php, has been added to the build/scripts directory. This tool allows users to programmatically extract the release notes for a specific version tag from the project's ChangeLog.md file, facilitating automated release processes.

build/scripts · high confidence

New strict unified diff output builder and interface

The library now includes a new \DiffOutputBuilderInterface\ and a \StrictUnifiedDiffOutputBuilder\ implementation that generates strict Unified diff output with configurable hunks, context lines, and file headers. A new \DiffOnlyOutputBuilder\ is also added for producing loose unified diff output that lists only changed lines without line numbers. These changes allow users to choose between strict standard-compliant diffs and simplified diff formats.

src/Output · high confidence

Behavioural changes

140 commits (1 fix) modifying tools

A change to existing behaviour in tools — 140 commits (1 fix), 4 files.

tools · medium confidence · unverified

Introduction of a custom Exception interface and new exception classes

The library now defines a custom \Exception\ interface that extends \Throwable\, allowing for more specific exception handling. Two new exception classes have been added: \ConfigurationException\, which extends \InvalidArgumentException\ to provide detailed error messages for invalid options, and \NoMiddleSnakeFoundException\, which extends \LogicException\ to signal invariant violations during diff calculations.

src/Exception · high confidence

Major refactoring of diff engine with new data structures and Myers algorithm

The core diffing logic has been rewritten to use Eugene W. Myers' linear-space algorithm, significantly improving performance for large inputs. The public API now relies on new value objects: \Chunk\ represents a range of lines, \Line\ represents an individual line with added/removed/unchanged status, and \Diff\ holds the file metadata and chunks. The \Differ\ class now accepts a \DiffOutputBuilderInterface\ to allow flexible output formatting, and a new \Parser\ class has been added to parse unified diff strings back into \Diff\ objects. The old \Diff\ class structure and the custom \autoload.php\ have been removed in favor of modern PHP standards (strict types, final classes, and standard autoloading).

src · high confidence

Modernized build automation and development tooling

The project has overhauled its build and development environment to use modern standards. Composer is now managed via Phive in the \tools/\ directory, and static analysis has switched from Psalm to PHPStan (configured at level 10 with strict rules). The PHPUnit configuration has been updated to the current schema, and the legacy PEAR installation method has been removed from the documentation. Additionally, Renovate is configured for automated dependency updates, and the license has been standardized to the BSD 3-Clause format.

(repo-wide) · high confidence

Test coverage

Added integration tests for StrictUnifiedDiffOutputBuilder; Added test fixtures for unified diff assertion and multi-chunk parsing; Added test utilities for validating unified diff formats; Added tests for ConfigurationException; Added tests for DiffOnly and StrictUnifiedDiff output builders; Added unit tests for Diff components.

Dependencies

PHP 8.4 requirement and PHPStan 2 tooling isolation

The project now requires PHP 8.4 or higher, dropping support for all previous versions, and updates its development dependencies to PHPUnit ^13.3.5 and Symfony Process ^7.4.19. Additionally, a new isolated PHPStan 2 tooling environment has been introduced under \tools/.phpstan/\, bundling PHPStan ^2.2.16 with strict rules and extension installer, while the main \composer.json\ has been updated to reflect the new PHP version constraint, updated homepage URL, and a branch alias for version 9.0.

(dependencies) · high confidence

PHPStan static analysis tooling updated to version 2.2.16

The PHPStan static analysis tool and its associated extensions in the \tools/.phpstan\ directory have been updated. The core \phpstan/phpstan\ package is now at version 2.2.16, and \phpstan/phpstan-strict-rules\ is at 2.0.12. Additionally, \ergebnis/phpstan-rules\ has been updated to version 2.14.0, which includes new rules such as \NoPhpstanIgnoreRule\ and support for PHP 8.6, while \phpstan/extension-installer\ remains at 1.4.3 to manage these extensions.

tools/.phpstan · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 54 → 75 (+21.4)
  • Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 95 → 89 (-6.0)
  • Architecture 94 → 100 (+5.9)
  • Maturity 59 → 66 (+6.5)
  • Readiness 32 → 77 (+45.3)
  • Security 81 → 88 (+6.3)

Resolved (6)

  • Coverage not measured — test suite did not build
  • Dimension evaluation failed
  • Duplicated block (12 lines × 2) (src/MyersDiff.php)
  • No exposed public API
  • No tests found
  • Test reliability not included

New (14)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (13 lines × 2) (src/MyersDiff.php)
  • Hotspot: src/Parser.php (src/Parser.php)
  • MyersDiff.findMiddleSnake (cognitive 45) (src/MyersDiff.php)
  • MyersDiff.findMiddleSnake (cyclomatic 24) (src/MyersDiff.php)
  • No assertions: testIntegrationOfUnitTestCasesGitApply (tests/Output/Integration/StrictUnifiedDiffOutputBuilderIntegrationTest.php)
  • No assertions: testIntegrationOfUnitTestCasesPatch (tests/Output/Integration/StrictUnifiedDiffOutputBuilderIntegrationTest.php)
  • No assertions: testIntegrationUsingPHPFileInVendorGitApply (tests/Output/Integration/StrictUnifiedDiffOutputBuilderIntegrationTest.php)
  • No assertions: testIntegrationUsingPHPFileInVendorPatch (tests/Output/Integration/StrictUnifiedDiffOutputBuilderIntegrationTest.php)
  • Parser.parse (cognitive 47) (src/Parser.php)
  • Parser.parse (cyclomatic 27) (src/Parser.php)
  • StrictUnifiedDiffOutputBuilder.writeDiffHunks (cognitive 41) (src/Output/StrictUnifiedDiffOutputBuilder.php)
  • StrictUnifiedDiffOutputBuilder.writeDiffHunks (cyclomatic 19) (src/Output/StrictUnifiedDiffOutputBuilder.php)

Changes since last survey

  • 30 commits — 30 feature/other, 0 fixes

By area

  • (root) — 14 commits
  • tools/.phpstan — 10 commits
  • (repo) — 3 commits
  • .github/workflows — 2 commits
  • src/Parser.php — 1 commit

Notable commits

  • change: Do not depend on tomasvotruba/type-coverage
  • change: Do not drop lines that look like file headers
  • change: Do not perform lock-file maintenance
  • change: Extract regular expressions in Parser into constants
  • change: Merge branch '7.0'
  • change: Merge branch '7.0'
  • change: Merge branch '7.0'
  • change: Prepare release
  • change: Prepare release
  • change: Update PHPStan packages
  • change: Update codecov/codecov-action action to v7.1.0
  • change: Update codecov/codecov-action action to v7.1.1
  • change: Update dependency phpstan/phpstan to ^2.2.10
  • change: Update dependency phpstan/phpstan to ^2.2.11
  • change: Update dependency phpstan/phpstan to ^2.2.12
  • change: Update dependency phpstan/phpstan to ^2.2.13
  • change: Update dependency phpstan/phpstan to ^2.2.14
  • change: Update dependency phpstan/phpstan to ^2.2.9
  • change: Update dependency phpstan/phpstan to ^2.2.9
  • change: Update dependency phpunit/phpunit to ^13.3.0
  • …and 10 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

sebastianbergmann/diff was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 86555df6dc6daf368c700abeac8945f83e47c521 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-a15879f6f801.