Skip to content

Give the build run feature an api module - #83

Merged
AhmadKharfan merged 1 commit into
developfrom
feat/buildrun-api-module
Jul 30, 2026
Merged

Give the build run feature an api module#83
AhmadKharfan merged 1 commit into
developfrom
feat/buildrun-api-module

Conversation

@AhmadKharfan

Copy link
Copy Markdown
Owner

Why

:feature:editor depended on :feature:buildrun's implementation for thirteen symbols. Only one of them, BuildRunApi, was an abstraction; the rest were concrete models the editor reads to render the build console.

What changed

New :feature:buildrun:api holding the contract and the types that cross it:

  • BuildRunApi, plus BuildExecutionSnapshot, BuildExecutionPhase, InstallExecutionState, StartBuildResult
  • The console models: BuildConsoleState, BuildStatus, BuildTaskGroup, BuildTaskLine, BuildLogLine, BuildProblem, BuildArtifact, and the reduce extension
  • BuildClientMeta
  • preflight: BuildPreflightResult, PreflightWarning, PreflightSeverity, ToolchainVersions, and the checkers
  • RunTargetResolver

:feature:editor now depends on the api module. BuildRunCoordinator, BuildInstallRunner, BuildNotifier, the installer and the keep-alive service stay in :feature:buildrun.

Editor's tests construct BuildRunCoordinator and BuildNotifier directly, so :feature:buildrun becomes testImplementation there — main depends on the contract, tests exercise the implementation.

Boundary baseline is down to a single entry.

Two things the type-closure audit turned up

BuildClientMeta was declared in BuildRunCoordinator.kt, not alongside the interface, even though it is a parameter of BuildRunApi.start(). Extracting only the obviously-contract files would have left the interface referencing a type still inside the implementation module.

RunTargetResolver is a stateless object over :domain types with no buildrun coupling, so it sits in the api module rather than behind the interface — the same treatment as gitErrorMessage. Moving it into :domain as a use case is arguably cleaner and remains open.

The api module takes a Compose dependency solely for @Immutable on the console models. That annotation is part of their contract: it tells Compose the state is stable so consumers skip recomposition correctly, and dropping it would silently change recomposition behaviour in the editor.

Behavior

No behavior change. Types moved between modules; no logic altered.

Tests

  • 714 tests passing, 0 failures.
  • The buildrun test suites moved with their subjects and still pass unchanged.

Verification

./gradlew test detekt verifyModuleBoundaries :app:assembleDebug — BUILD SUCCESSFUL. Boundary report: 127 dependencies checked, 1 baseline entry, 0 violations.

Verified on an emulator, because the previous api extraction shipped a crash that no JVM test could see:

  • Editor opens, build console renders
  • Pressing Run drives the full path through the contract — notification permission prompt, preflight, build start, console state reduction, and problem rendering. The build itself reports "You're offline or DNS failed", which is the remote build server being unreachable from the emulator, not a fault in this change. The pipeline around it executed correctly.
  • No AbstractMethodError, NoSuchMethodError or NoClassDefFoundError in logcat

Note: unlike GitPanelApi, BuildRunApi has no @Composable members, so the default-argument hazard that caused the earlier crash does not apply here.

@AhmadKharfan
AhmadKharfan merged commit 7df3a40 into develop Jul 30, 2026
3 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