Skip to content

Name the repository root apart from the Gradle root (#519) - #524

Merged
ramesh130 merged 3 commits into
mainfrom
issue-519-repository-root
Oct 14, 2026
Merged

ramesh130 merged 3 commits into
mainfrom
issue-519-repository-root

Conversation

@ramesh130

Copy link
Copy Markdown
Owner

Closes #519

The Gradle builds read and write the repository's own files: the Swift manifests, the iOS fixtures, docs/, config/, LICENSE, CHANGELOG.md, third-party/ and devicelab/. Every one of those paths assumed the Gradle root was the repository root. This PR names the repository root once and resolves each of those paths through it.

The two roots are the same directory today, so no file moves and no behaviour changes. In #521, moving the four builds under android/ changes one line on the Gradle side: superplayer.repositoryRoot=. becomes ...

Decisions

The mechanism: one Gradle property in the root gradle.properties

The property is superplayer.repositoryRoot. It is a path from the root build's directory to the repository root.

Four builds need the value, and they cannot share code:

  • Root settings script. It runs before build-logic is loaded.
  • demo/ and benchmark/. They are separate builds and never load build-logic.
  • build-logic's tests. They run outside any build.

All four can read one properties file, so the value is written once and each build derives its own copy from it:

  • Root build and modules: Project.repositoryRoot in the new build-logic/.../RepositoryRoot.kt. It reads the value through providers.gradleProperty, so the configuration cache tracks it. It refuses a missing value by name. It also refuses a value naming a directory that does not contain the build, because a typo would otherwise show up as "file missing" rather than "file misplaced".
  • Root settings: reads the value inline through providers.
  • demo/ and benchmark/ settings: load ../gradle.properties, the same way they already load ../gradle/libs.versions.toml. They hand the value to their build script through gradle.extra. The two blocks are marked as copies of each other.
  • build-logic's tests: call repositoryRootOf(File("..")), which is the same resolution the plugins use. I chose this over the suggested system property: a second channel could disagree with the first, and this way the tests exercise the plugins' own code path.
  • Module unit tests that read docs/ (TelemetrySchemaDocumentTest, DoctorDocumentTest, TransportDocumentTest): they get a module-relative superplayer.repository.dir system property from the convention plugin. This follows the existing superplayer.golden.dir pattern.

Paths deliberately left on the Gradle root

The catalog, settings.gradle.kts, superplayer-*, api/released and the Spotless targets stay where they are, since they are the Gradle build's own files.

CutRelease

  • git now runs at the repository root, the one directory that contains every path a release writes.
  • The git add paths are no longer a fixed list. releaseWrittenPaths computes them relative to the repository root, giving android/gradle/libs.versions.toml and CHANGELOG.md once the roots differ.
  • publishToMavenLocal still runs at the Gradle root, where gradlew is.

convertThroughputTrace

Relative --input and --output paths now resolve against the repository root, not the invoking directory. Three reasons:

  • Gradle does not expose the shell's working directory. The closest thing, StartParameter.currentDir, moves with -p.
  • The Gradle root stops being the top of the tree after Move the Android builds under android/ #521.
  • The repository root is the one directory that the command lines in docs/ are written from, and it stays the same however the wrapper is reached.

Tests

RepositoryRootTest has seven cases:

  • Gradle build one level below the repository root, declaring ..: the value is honoured.
  • Equal-roots control, declaring .: resolves to the build's own directory.
  • Missing value: refused by name.
  • Sibling, non-containing value: refused.
  • The real tree: resolves to the directory that holds the shared files.
  • Release written paths: one case with differing roots, plus an equal-roots control.

LicenseHeaderTest, ModulePhaseRuleTest and CompatibilityDocumentTest now read the documents and Swift files under the repository root, and read the modules and settings under the Gradle root.

Verification

  • ./gradlew assemble check --max-workers=1: green, run before and after the review fixes. The XML results show 1238 tests with 0 failures and 0 errors across the module unit tests and build-logic.
  • ./gradlew updateIosFixtures run on its own: git status --short ios/ is empty, so the fixtures are byte-identical.
  • publishToMavenLocal, then (cd demo && ./gradlew assembleDebug spotlessCheck) and (cd benchmark && ./gradlew assemble spotlessCheck): both green.
  • ios/check was not run, because nothing in Swift changed. No emulator run was needed either: this changes the build's paths, not playback.

Review

Standards

No hard findings. I fixed these soft ones:

  • The root settings now names the missing property instead of failing on a bare .get().
  • The demo and benchmark settings blocks are marked as copies of each other.
  • The comment on the superplayer.repository.dir system property now names the Gradle property it comes from.
  • The "one line" claim in RepositoryRoot.kt is scoped to the four builds moving together.
  • RepositoryRootTest's KDoc now says why the release-path cases live there.

Left as they are:

Spec

No gaps. Minor points:

  1. The settings copies of the resolution skip the containment check. It still runs as soon as the root build configures its first plugin, and the comment says so.
  2. A -P override would reach the root build but not demo/, benchmark/ or the build-logic tests, which read the file directly. That is an edge case, and nothing here passes -P.
  3. The benchmark's RunConditions.read(repoRoot, …) actually receives the Gradle root. It uses it for the catalog and for git, and both keep working after the move. Only the name and KDoc become inaccurate, so I left them for Move the Android builds under android/ #521 or Documents describe the android/ layout #522 rather than widening this PR.

Skipped and why

🤖 Generated with Claude Code

https://claude.ai/code/session_01MJAhQmFgdRRAKUaMHibQLe

ramesh130 and others added 3 commits October 14, 2026 12:43
…y shared or iOS path through it

The Gradle builds read and write the Swift manifests, the iOS fixtures, docs/, config/, LICENSE,
CHANGELOG.md, third-party/ and devicelab/, and each of those paths assumed the Gradle root was the
repository's. One Gradle property, superplayer.repositoryRoot in the root gradle.properties, now
names it; the root build and its modules read it through build-logic's repositoryRoot, the root
settings through providers, demo/ and benchmark/ from the root build's gradle.properties, and
build-logic's tests through repositoryRootOf. The two roots are one directory today, so nothing
moves; moving the Android builds under android/ (#521) is that one line becoming `..`.

Closes #519

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MJAhQmFgdRRAKUaMHibQLe
…rk the two settings copies as copies, and scope the one-line claim

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MJAhQmFgdRRAKUaMHibQLe
@ramesh130
ramesh130 merged commit fb365a7 into main Oct 14, 2026
3 checks passed
@ramesh130
ramesh130 deleted the issue-519-repository-root branch October 14, 2026 03:09
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.

Gradle build names the repository root separately from the Gradle root

1 participant