Skip to content

refactor(core): hoist redirect following out of getInputStream - #6

Merged
w0rxbend merged 1 commit into
mainfrom
refactor/core-complexity
Sep 6, 2026
Merged

w0rxbend merged 1 commit into
mainfrom
refactor/core-complexity

Conversation

@w0rxbend

@w0rxbend w0rxbend commented Sep 6, 2026

Copy link
Copy Markdown
Member

Clears three maintainability findings — scala:S3776 ×2 on RuntimeHttp.scala and scala:S107 on StatefulApplyRunner.scala. These are the only open Sonar findings in production Scala; the other 79 are test code.

Tests first, because the branches being refactored were uncovered

follow's redirect-failure exits were 1-of-4 covered — only "unsafe redirect target" was asserted. Refactoring uncovered branches is how they change behaviour quietly, so this PR adds the three missing cases before touching production code:

  • redirect budget exhausted
  • missing or blank Location
  • malformed Location

Each asserts the error message and that the response body was closed. All three pass before the refactor and after.

The two S3776 findings were the same code counted twice

Sonar reports complexity 22 at getInputStream:38 and 17 at follow:46. follow was a nested @tailrec def, so its branching aggregated into the enclosing method on top of a nesting surcharge — one method scored twice, once through its child.

Hoisting follow to object level clears both. Extracting helpers while leaving it nested would have left the outer method around 14–15 and flickering across the threshold on the next edit.

redirectTarget and provenanceFor come out as siblings.

Three things that are load-bearing, not incidental

  • The redirect target stays a match, not a for-comprehension. Moving the recursive call inside a flatMap lambda takes it out of tail position and @tailrec fails compilation.
  • redirectTarget leaves the response open on every path, success and failure alike. The body belongs to the caller, which releases it through failClosing; closing it here would double-close.
  • provenanceFor's two arms draw on different sources on purpose. A chain this loop followed itself is recorded in redirects; a response that never redirected here may still have been redirected by the transport, and only the response carries that history. They are not collapsible.

getInputStream's public signature is unchanged, so its three callers are untouched.

StatefulApplyRunner

runWithState drops its fileSystem parameter, which duplicated installer.fileSystem, taking it from 8 parameters to 7. The single caller in ResolvingBinaryInstallerService is updated.

This is redundant state, not a latent bug. The object is private[core], the method is private, and the caller passed installer.fileSystem literally — the divergence was not constructible. Removing it for tidiness, not for safety.

Verification

scalafmt/checkFormatAll, __.compile under -Werror -Wunused:all -Wvalue-discard -Wnonunit-statement, and __.test all pass — 514 tests, 0 failures. The new HttpClientTest cases were also run against the pre-refactor code to confirm they pass on both sides of the change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AaPvsFt1xYoXErXaZ4Kk8A

Clears three maintainability findings, but the tests come first: follow's
redirect-failure exits were 1-of-4 covered, with only "unsafe redirect
target" asserted. Refactoring uncovered branches is how they change
behaviour quietly.

Adds the three missing cases — redirect budget exhausted, missing or blank
Location, malformed Location — each asserting the message and that the
response body was closed. They pass before the refactor and after.

The two cognitive-complexity findings on RuntimeHttp (22 at getInputStream,
17 at follow) were the same code counted twice: follow was a nested @tailrec
def, so its branching aggregated into the enclosing method on top of a
nesting surcharge. Hoisting it to object level clears both. Extracting
helpers while leaving it nested would have left the outer method flickering
around the threshold.

redirectTarget and provenanceFor come out as siblings. redirectTarget
deliberately leaves the response open on every path, success and failure
alike — the body belongs to the caller, which releases it through
failClosing, and closing it here would double-close. provenanceFor's two
arms draw on different sources on purpose: a chain this loop followed is
recorded in `redirects`, while a response redirected by the transport
carries its history only on the response.

The redirect target stays a match rather than a for-comprehension: moving
the recursive call inside a flatMap lambda takes it out of tail position
and fails compilation.

getInputStream's public signature is unchanged, so its three callers are
untouched.

Separately, StatefulApplyRunner.runWithState drops its fileSystem
parameter, which duplicated installer.fileSystem, taking it from 8
parameters to 7. This is redundant state, not a latent bug — the object is
private[core], the method is private, and the single caller passed
installer.fileSystem literally, so the divergence was not constructible.

scalafmt, compile under -Werror, and the full suite pass: 514 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaPvsFt1xYoXErXaZ4Kk8A
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 22ef340c-f0a0-43be-8d8c-b495a9f9f051


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.

@sonarqubecloud

sonarqubecloud Bot commented Sep 6, 2026

Copy link
Copy Markdown

@w0rxbend
w0rxbend merged commit e79680d into main Sep 6, 2026
5 checks passed
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