This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This repository contains custom Rector rules for for automating Carbon 2 → Carbon 3 migration for PHP 8.4 and 8.5 codebases,
with special emphasis on support for codebases that do not use UTC as the default time zone. Each rule in src/ extends
Rector\Rector\AbstractRector and transforms PHP AST nodes using nikic/php-parser. The rules target Carbon,
CarbonImmutable, and Illuminate\Support\Carbon classes.
Background:
- Migration Info: https://carbon.nesbot.com/guide/getting-started/migration.html
- Creating Rector Tests: https://getrector.com/documentation/writing-tests-for-custom-rule
IMPORTANT: Do not assume that PHP or Composer is installed locally. Always run commands through the appropriate Docker container.
# PHP/Tooling Commands (use `php:8.4-cli` Docker image)
# Run tests
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) php:8.4-cli php vendor/bin/phpunit
# Run a single test
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) php:8.4-cli php vendor/bin/phpunit --filter testMethodName
# Static analysis (level max, bleeding edge)
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) php:8.4-cli php vendor/bin/phpstan analyse
# Code style (PER-CS via PHP-CS-Fixer)
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) php:8.4-cli php vendor/bin/php-cs-fixer fix --dry-run --diff # check
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) php:8.4-cli php vendor/bin/php-cs-fixer fix # fix
# Apply Rector rules to this repo's own source
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) php:8.4-cli php vendor/bin/rector process
# Composer commands (use `composer:latest` Docker image)
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) composer:latest install
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) composer:latest update
docker run --rm -it -w /app -v ./:/app -u $(id -u):$(id -g) composer:latest require ...Namespace: PhoneBurner\CarbonMigrationRectorRules
Every Rector rule follows the same structure:
getRuleDefinition()— returns docs with before/after code samplesgetNodeTypes()— declares which AST node types to visit (StaticCall,MethodCall,Expression)refactor(Node $node)— performs the transformation, returns modified node ornullto skip
There are two patterns for matching Carbon calls:
- Static calls (e.g.,
Carbon::createFromTimestamp) — useisObjectType()with fully-qualified class names +isName()fallback for short class names - Method calls (e.g.,
$date->diffInSeconds()) — match on method name only (no type checking on the receiver)
CarbonMigrationRules::ALL is the canonical ordered list of all rule classes, grouped by severity (behavioral changes →
API changes → removed methods).
Rules that can't fully automate a migration insert TODO: [Carbon 3 migration] comments for manual review.
- PHP 8.4 with
declare(strict_types=1)in every file - PER Coding Style enforced by PHP-CS-Fixer (
@auto+@auto:riskyrules) - PHPStan at max level with bleeding edge enabled
- PHPUnit 13 with
#[Test]attributes (not@testannotations)
- Variables, Parameters, Properties: snake_case
- Class Methods (including test methods): camelCase
- Constants: SCREAMING_SNAKE_CASE
- Class/Interface/Trait: PascalCase
- Enum Case: PascalCase
- Functions: snake_case