Skip to content

Ruby 4.0.5 / Rack 3 support#1

Draft
lleirborras wants to merge 2 commits into
masterfrom
upgrade/rails-8.1-ruby-4
Draft

Ruby 4.0.5 / Rack 3 support#1
lleirborras wants to merge 2 commits into
masterfrom
upgrade/rails-8.1-ruby-4

Conversation

@lleirborras

Copy link
Copy Markdown
Member

Summary

Brings rack_dav up to Ruby 4.0.5 / Rack 3 for the fleet upgrade. Draft — opened for review/CI while the consuming app (scriptoria) is still on its own staircase.

What changed

  • Rack 3: status coerced with to_i before finish, response headers reassigned (not <<), request.body&.read.to_s nil-guard.
  • Ruby 3.0+ stdlib: declare rexml + webrick (left the default gems).
  • URI.escapeURI::DEFAULT_PARSER.escape (removed in Ruby 3.0).
  • CI runs the smoke (test/smoke.rb) across Ruby 2.7 / 3.0 / 3.4 / 4.0.5 via each Ruby's official Docker image. required_ruby_version >= 2.7.

Ruby floor

0.4.0 is a modern release: it targets Rack 3 (Ruby ≥ 2.4) and uses safe-navigation &. (Ruby ≥ 2.3), so it does not run on the very old Rubies (verified: Ruby 2.1/2.2 fail to parse). The only consumer, scriptoria (Ruby 2.1), keeps the old release pinned until its own upgrade staircase crosses Ruby 2.7 — at which point it adopts this version.

How to test

docker run --rm -v "$PWD":/gem -w /gem -e BUNDLE_GEMFILE=test/Gemfile.ci \
  -e BUNDLE_FORCE_RUBY_PLATFORM=true ruby:2.7 \
  bash -c 'rm -f test/*.lock && bundle install --quiet && bundle exec ruby test/smoke.rb'

Verified green on 2.7 and 4.0.5.

lleirborras and others added 2 commits June 19, 2026 13:55
- Declare `rexml` + `webrick` runtime deps — both are required in lib/rack_dav.rb
  and left Ruby's default gems in 3.0, so the gem failed to load on Ruby 4.
- `URI.escape` / `URI.unescape` (removed in Ruby 3.0) → `URI::DEFAULT_PARSER`;
  `Rack::Utils.bytesize` (removed) → `String#bytesize`.
- Rack 3 no longer coerces the response status via `#to_i`, so setting
  `response.status = NoContent` (an HTTPStatus class) left a non-Integer status.
  Coerce in the handler before `finish`.
- Rack 3 leaves `request.body` nil for an empty body (Rack 2 gave an empty
  StringIO) — guard it in `request_document`. Reassign rather than mutate the
  OPTIONS Allow/Dav header strings in place.

All changes are backward-compatible with Rack 2. Add a self-contained smoke
harness (test/smoke.rb) driving OPTIONS/PUT/GET/PROPFIND/DELETE over a temp dir,
plus a CI matrix over Ruby 4.0.5/3.4/2.7 × Rack 3/2.2. Verified green on Ruby
4.0.5/Rack 3 and Ruby 3.4/Rack 2.2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0.4.0 targets Rack 3 (Ruby >= 2.4) and uses safe-navigation `&.` (Ruby >= 2.3),
so it can't run on the oldest Rubies — verified: Ruby 2.1/2.2 fail to parse
controller.rb. Modern floor is 2.7 (Rack 3 + 2.7 smoke green). Run the smoke in
each Ruby's official Docker image (GitHub-hosted runners can't install <= 2.6),
with BUNDLE_FORCE_RUBY_PLATFORM so old rows resolve native gems from source.
required_ruby_version >= 2.7. Consumer (scriptoria, Ruby 2.1) keeps the old
release pinned until its staircase crosses 2.7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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