Skip to content

refactor: inline werk365/etagconditionals to unblock laravel 13#737

Merged
brycehans merged 1 commit into
4.xfrom
refactor/etagconditionals-inline
Jun 1, 2026
Merged

refactor: inline werk365/etagconditionals to unblock laravel 13#737
brycehans merged 1 commit into
4.xfrom
refactor/etagconditionals-inline

Conversation

@brycehans

Copy link
Copy Markdown
Owner

Summary

  • Replaces the werk365/etagconditionals dependency with three in-tree middlewares (SetEtag, IfNoneMatch, IfMatch) plus the static EtagConditionals helper, all under app/Http/Middleware/Etag/. The three route-middleware aliases (setEtag, ifNoneMatch, ifMatch) shift from the package's auto-discovered service provider into app/Http/Kernel.php's $routeMiddleware array.
  • Removes the lone remaining dependency blocker for the Laravel 12 → 13 upgrade. After this PR, composer why-not laravel/framework "^13.0" reports only the standard list of packages that have published L13-compatible newer releases (debugbar ^4, tinker ^3, cloudflare ^4, google2fa-laravel ^3, hashids ^14) — no irreplaceable blocker remains.
  • Documents the decision in docs/design-decisions.md (new "ETag conditional middleware: replaced inline" section), including the two deliberate simplifications: the if_match_weak / if_none_match_weak config knobs are dropped (Monica never overrode them), and the unused etag middleware group / facade / Middleware base class are removed.

Why

Upstream werk365/etagconditionals is dormant. PR #28 ("Support Laravel 13.x") has sat open since 2026-04, the previous L11/L12 PR sat open for 13 months, and the repo's last push was nine months ago — Monica was already pinned to dev-master to get L11/L12 support. The middleware surface is ~120 lines and the upstream tests fully specify the behaviour, so inlining costs less than maintaining a soft-fork or VCS-pinning a PR branch.

What this looks like for StorageController

Zero call-site change. The controller's __construct still does $this->middleware(['setEtag', 'ifMatch', 'ifNoneMatch']). The aliases now resolve through Kernel.php instead of the package's service provider.

The EtagConditionals::etagGenerateUsing(...) closure registration in AppServiceProvider::boot() continues to work via a one-line import swap. The closure (sha1-of-URL, cached forever) is unchanged.

Test plan

  • New: tests/Feature/Http/Middleware/Etag/SetEtagTest.php (3 cases — default md5 path, registered-callback path, HEAD response path)
  • New: tests/Feature/Http/Middleware/Etag/IfNoneMatchTest.php (4 cases — match, no-match, weak-tag, HEAD-match-304)
  • New: tests/Feature/Http/Middleware/Etag/IfMatchTest.php (8 cases — match, list-match, wildcard, mismatch, list-mismatch, weak-tag, non-PATCH passthrough, Kernel-alias resolution)
  • Existing tests/Feature/StorageControllerTest.php continues to exercise the live /store/{file} integration with the new alias resolution (all 15 cases green)
  • Full PHPUnit suite green: 1745 tests, 13391 assertions
  • PHPStan clean

three middlewares (SetEtag, IfNoneMatch, IfMatch) plus the static
EtagConditionals helper move into app/Http/Middleware/Etag/. route
aliases (setEtag, ifNoneMatch, ifMatch) shift from the package's
service provider into Kernel.php's $routeMiddleware.

trigger: the L13 readiness audit (composer why-not laravel/framework
"^13.0") flagged werk365/etagconditionals as the lone dep blocker.
upstream PR #28 ("Support Laravel 13.x") has sat open since April
2026, last push was nine months ago, and we were already pinned to
dev-master to get L11/L12 support — no tagged path forward.

behaviour parity with two deliberate simplifications, both called
out in docs/design-decisions.md:

- if_match_weak / if_none_match_weak config knobs dropped; both
  hardcoded to true. monica never overrode the env vars.
- the 'etag' middleware group, the facade, and the Middleware base
  class with name() are removed. monica only ever used the three
  aliases individually.

coverage: 15 new cases in tests/Feature/Http/Middleware/Etag/
(unit-port + HEAD + kernel-alias resolution). the existing
StorageControllerTest still exercises the live integration on
/store/{file}. full PHPUnit (1745 tests) green, PHPStan clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Claude-Session: c609e463-b87a-4011-a563-2f7d6a694177
@brycehans brycehans merged commit d44215c into 4.x Jun 1, 2026
11 checks passed
@brycehans brycehans deleted the refactor/etagconditionals-inline branch June 1, 2026 23:29
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.

1 participant