Feature/stonecutter migration - #21
Merged
Merged
Conversation
Prerequisite for adding Stonecutter, which refuses to apply below
Gradle 9 (checked directly: 0.8.4, 0.9.1, and 0.9.7 all reject 8.x).
Verified clean on 9.7.1 first - full compile, unit tests, and the
whole task graph (Loom, Architectury, Dokka, ModFusioner, ModPublisher,
Shadow, the actualizer/archie plugins) all configure and run across
every module with no changes beyond the two below.
- Gradle 9 stopped bundling its own JUnit Platform launcher for
useJUnitPlatform() - added junit-platform-launcher to the catalog
and wired it once as testRuntimeOnly in the shared subprojects{}
dependencies block.
- core/common's verifyGuiSpriteAssets task used the `by registering {}`
delegate, deprecated in 9.6 and removed in 10 - switched to
`register("...")`.
architectury-loom's pinned version also now reads 1.17.491 instead of
1.13.469 in gradle/libs.versions.toml. This wasn't a deliberate edit -
noticed the file already showed 1.17.491 when checked, with no edit
made by this work to explain it. Left as-is since it's what actually
resolved and ran successfully throughout verification, but flagging it
since its cause is unexplained.
Converts core/{common,fabric,neoforge} to a Stonecutter-managed tree/branch
structure (settings.gradle.kts: stonecutter { create("core") { branch(...) } }),
keeping datagen/gametest/test on the old includeModule() scheme until this
slice is proven out.
Root build.gradle.kts guards subprojects{}/allprojects{} plugin application
against Stonecutter's synthetic tree/branch container projects (:core,
:core:common, etc. - real leaf projects nest under them and must not get
build plugins applied directly).
Sibling-project references (fabric/neoforge -> common) go through Stonecutter's
node.sibling("common").project API rather than a hardcoded project path -
ProjectNode.project resolves straight to the sibling's Gradle Project.
The old namedElements/transformProductionX cross-project dependency (Loom's
own common() mechanism) produces a circular task dependency under Stonecutter's
nested per-version project paths, so fabric/neoforge instead depend directly
on common's own "jar" task output as a FileCollection. (A plain SourceSetOutput
FileCollection almost works the same way, but breaks shadowJar - Shadow's copy
action expects zip-safe entries, not raw class/resource directories.)
Also bumps the Shadow plugin from com.github.johnrengelman.shadow 8.1.1 to the
maintained com.gradleup.shadow 9.6.1 fork - the old one is incompatible with
Gradle 9.7.1 (MissingPropertyException: mode in ShadowCopyAction), independent
of the Stonecutter migration itself.
Disables the background-session worktree-isolation guard for this repo
(.claude/settings.json) at the user's request.
Verified: :core:{common,fabric,neoforge}:1.21.1:assemble all succeed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016XkTGULzd3V7X4ZGP3iw7P
Extends the core-only Stonecutter validation slice to datagen, gametest, and
test - all four module trees are now Stonecutter-managed. settings.gradle.kts
registers all four trees identically (branch("common")/branch("fabric")/
branch("neoforge"), single version "1.21.1" each); each tree gets its own
stonecutter.gradle.kts (mirroring core's).
Sibling-project references follow the pattern established for core:
- Same-tree (X:common <-> X:fabric/neoforge): node.sibling("common").project.
- Cross-tree (e.g. datagen -> core, test -> core/datagen/gametest): Stonecutter
has no public cross-tree lookup API (node.sibling() only searches its own
tree), so these resolve via rootProject.project(":tree:branch:$version").
- Every cross-project compiled-output dependency goes through the sibling's
plain "jar" task output as a FileCollection, not project(path, configuration)
or a bare project(path) - both trigger a circular compileJava<->compileKotlin
task dependency under Stonecutter's nested per-version project paths,
confirmed live across multiple project-pairings (common<->common,
loader<->loader, common-mode<->loader). Deliberately not remapJar's output:
that transforms named->intermediary for shipping and reintroduces the same
class duplication one layer down (confirmed live: a Font/class_327
duplicate-overload regression in already-working core code, traced to a
poisoned shared .gradle/loom-cache/remapped_mods/ entry - cleared as part of
this work).
files() dependencies carry no transitive module metadata, unlike the
project(path, "namedElements") dependencies they replace, so every affected
common-mode project (datagen/gametest/test's common modules) repeats
whatever api/modApi surface its own code actually needs from its sibling
(Compose, kotlinx.serialization, storage lib) - verified by removing each
speculatively-added line and confirming the build still needs it before
keeping it (e.g. libs.rei.common was not actually needed by datagen-common).
The actualizer merges each common module's own source directly into its
fabric/neoforge siblings' compilation (not just their compiled output), so
those loader projects need common's compile-time deps directly too - same
reasoning, same fix.
gametest-neoforge needed the loader-specific libs.storage.neoforge instead of
libs.storage.common - NeoForge's remap pipeline doesn't handle
earth.terrarium.common_storage_lib's common artifact correctly (same family
of gap as the documented Cloche NeoForge remapCommon limitation for this
library); using the common variant surfaced as an ambiguous ItemResource.of
overload resolving against raw Fabric intermediary-mapped parameter types.
Verified: `./gradlew assemble` succeeds for the whole repo (all 12
common/fabric/neoforge modules across core/datagen/gametest/test).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016XkTGULzd3V7X4ZGP3iw7P
…est/test loader modules
The files()-based cross-tree dependency on each core-{fabric,neoforge}
sibling (used to dodge the circular compileJava<->compileKotlin task
dependency documented in the previous commit) carries no runtime GAMELIBRARY
discovery either, same as it carries no compile-time transitive metadata.
core-fabric/core-neoforge each bundle the kotlinx.serialization format
add-ons (nbt/toml/json5) via bundleRuntimeLibrary - Archie's own Config
system needs all three at init - but that never propagated to any of
datagen/gametest/test's loader modules, which only had Compose repeated so
far.
Confirmed live via `./gradlew :test:fabric:1.21.1:runClient`:
Caused by: java.lang.NoClassDefFoundError: io/github/xn32/json5k/ConfigBuilder
at ...Json5ConfigSerializer.<clinit>
at ...ConfigSpec.<init>
at ...Archie.init
Same gap existed on datagen-fabric, datagen-neoforge, gametest-fabric,
gametest-neoforge, and test-neoforge (verified via each module's own
runtimeClasspath resolution, not just test-fabric where it was reported) -
fixed all six with the same runtimeLibrary(...) additions.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016XkTGULzd3V7X4ZGP3iw7P
…tonecutter
Stonecutter's nested per-version project layout broke several things that
keyed off the pre-migration flat project names:
- Maven publish's artifactId was "1.21.1" for every module (not just the
intended -fabric/-datagen-common/etc. suffix missing) - the artifactId
assignment ran before base.archivesName reached its final value. Moved it
into afterEvaluate{}. Also fixed the archie-test exclusion, which checked
project.name (now always "1.21.1") instead of project.path.
- modfusioner's fusejars task silently no-op'd ("No projects were found")
since it resolves projects by bare Project.name, and every Stonecutter tree
now has a leaf literally named "fabric"/"neoforge". Anchored it on the
unique ":core" container project and override inputFile via
gradle.projectsEvaluated once the real remapJar output paths are known.
- Dokka's per-module aggregation dependency block had been commented out
during the migration (stale flat project paths) - rebuilt against
Stonecutter's real :tree:branch:version paths.
- gameVersions in the publisher{} block now derives from
libs.versions.minecraft instead of a separately hardcoded "1.21.1" literal.
Verified: generatePomFileForMavenPublication produces correct artifactIds,
test tree is excluded, fusejars produces a real merged jar (both
fabric.mod.json and neoforge.mods.toml present), dokka configuration
resolves all 9 module paths, and publishCurseforge/publishModrinth dry-run
(debug=true) cleanly against live CurseForge/Modrinth data.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WW8YqJDBH8AFaTFirpCQGZ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.