@@ -186,6 +186,16 @@ minecraft {
186186 // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
187187 args ' --mod' , mod_id, ' --all' , ' --output' , file(' src/generated/resources/' ), ' --existing' , file(' src/main/resources/' )
188188 }
189+
190+ [' Fresh' , ' Reload' ]. each { String phase ->
191+ create(" surfaceIntegration${ phase} " ) {
192+ parent runs. server
193+ workingDirectory layout. buildDirectory. dir(' surface-integration-run' ). get(). asFile
194+ property ' forge.logging.console.level' , ' info'
195+ property ' surfaceprobe.integrationPhase' , phase. toLowerCase(Locale . ROOT )
196+ args ' --nogui'
197+ }
198+ }
189199 }
190200}
191201
@@ -291,6 +301,84 @@ tasks.named('test', Test).configure {
291301 useJUnitPlatform()
292302}
293303
304+ def surfaceIntegrationClasses = layout. buildDirectory. dir(' surface-integration-fixture/classes' )
305+ def compileSurfaceIntegrationTestMod = tasks. register(' compileSurfaceIntegrationTestMod' , JavaCompile ) {
306+ dependsOn tasks. named(' classes' )
307+ source fileTree(' src/biomeIntegrationTest/java' )
308+ classpath = files(sourceSets. main. output, sourceSets. main. compileClasspath)
309+ destinationDirectory. set(surfaceIntegrationClasses)
310+ javaCompiler. set(javaToolchains. compilerFor {
311+ languageVersion = JavaLanguageVersion . of(17 )
312+ })
313+ options. release = 17
314+ options. encoding = ' UTF-8'
315+ }
316+
317+ def surfaceIntegrationTestModJar = tasks. register(' surfaceIntegrationTestModJar' , Jar ) {
318+ dependsOn compileSurfaceIntegrationTestMod
319+ archiveFileName = ' surfaceprobe.jar'
320+ destinationDirectory = layout. buildDirectory. dir(' surface-integration-fixture' )
321+ from surfaceIntegrationClasses
322+ from ' src/biomeIntegrationTest/resources'
323+ }
324+
325+ def surfaceIntegrationRunDirectory = layout. buildDirectory. dir(' surface-integration-run' )
326+ def prepareSurfaceIntegrationTest = tasks. register(' prepareSurfaceIntegrationTest' ) {
327+ dependsOn surfaceIntegrationTestModJar
328+ doLast {
329+ File runDirectory = surfaceIntegrationRunDirectory. get(). asFile
330+ delete runDirectory
331+ runDirectory. mkdirs()
332+ copy {
333+ from surfaceIntegrationTestModJar. flatMap { it. archiveFile }
334+ into surfaceIntegrationRunDirectory. map { it. dir(' mods' ) }
335+ }
336+ new File (runDirectory, ' server.properties' ). setText(''' \
337+ level-name=surface-integration-world
338+ level-seed=0
339+ level-type=minecraft:normal
340+ online-mode=false
341+ allow-nether=true
342+ generate-structures=false
343+ spawn-protection=0
344+ max-tick-time=-1
345+ ''' , ' UTF-8' )
346+ new File (runDirectory, ' eula.txt' ). setText(' eula=true\n ' , ' UTF-8' )
347+ }
348+ }
349+
350+ tasks. configureEach {
351+ if (name == ' runSurfaceIntegrationFresh' ) {
352+ dependsOn prepareSurfaceIntegrationTest
353+ } else if (name == ' runSurfaceIntegrationReload' ) {
354+ dependsOn ' runSurfaceIntegrationFresh'
355+ }
356+ }
357+
358+ def surfaceIntegrationTest = tasks. register(' surfaceIntegrationTest' ) {
359+ group = ' verification'
360+ description = ' Verifies provider surfaces and dynamic-biome geology across fresh and reloaded normal terrain.'
361+ dependsOn ' runSurfaceIntegrationReload'
362+ doLast {
363+ File marker = surfaceIntegrationRunDirectory. get(). file(
364+ ' surface-integration-world/surfaceprobe-integration.properties' ). asFile
365+ if (! marker. isFile()) {
366+ throw new GradleException (" Surface integration completion marker is missing: ${ marker} " )
367+ }
368+ Properties result = new Properties ()
369+ marker. withInputStream { result. load(it) }
370+ if (result. getProperty(' reload_verified' ) != ' true' ) {
371+ throw new GradleException (" Surface integration reload was not verified: ${ marker} " )
372+ }
373+ logger. lifecycle(' Provider surfaces and dynamic-biome geology verified: {} dimensions, {} columns each, fresh + reload' ,
374+ result. getProperty(' dimensions' ), result. getProperty(' columns_per_dimension' ))
375+ }
376+ }
377+
378+ tasks. named(' check' ) {
379+ dependsOn surfaceIntegrationTest
380+ }
381+
294382// Keep every Eclipse launch input on one physical Gradle cache. Mixing Buildship's
295383// cache with a command-line cache duplicates named Java modules such as FML and Mixin.
296384def syncEclipseRunClasspaths = tasks. register(' syncEclipseRunClasspaths' ) {
@@ -463,6 +551,7 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
463551 }
464552
465553 int changedLaunches = 0
554+ int changedTestExclusions = 0
466555 if (eclipseLaunchDir. isDirectory()) {
467556 File eclipseClasses = file(' bin/main' ). canonicalFile
468557 String modClasses = " ${ mod_id} %%${ eclipseClasses.absolutePath} "
@@ -480,6 +569,27 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
480569 / < mapEntry key= " MOD_CLASSES" value= " [^" ]* " \/ >/) {
481570 " < mapEntry key= \" MOD_CLASSES\" value=\" ${ modClasses} \" />"
482571 }
572+ String excludeTestKey = ' org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE'
573+ String excludeTestAttribute =
574+ " <booleanAttribute key=\" ${ excludeTestKey} \" value=\" true\" />"
575+ String beforeTestExclusion = synced
576+ if (synced. contains(" key=\" ${ excludeTestKey} \" " )) {
577+ synced = synced. replaceFirst(
578+ / < booleanAttribute key= " org\. eclipse\. jdt\. launching\. ATTR_EXCLUDE_TEST_CODE" value= " [^" ]* " \/ >/,
579+ excludeTestAttribute)
580+ } else {
581+ int launchHeaderEnd = synced.indexOf('\n ', synced.indexOf('<launchConfiguration'))
582+ if (launchHeaderEnd < 0) {
583+ throw new GradleException(" Malformed Eclipse Java launch configuration : ${launchFile}" )
584+ }
585+ String lineSeparator = synced.contains('\r\n ') ? '\r\n ' : '\n '
586+ synced = " ${synced. substring(0 , launchHeaderEnd + 1 )}" +
587+ " ${excludeTestAttribute}${lineSeparator}" +
588+ synced.substring(launchHeaderEnd + 1)
589+ }
590+ if (beforeTestExclusion != synced) {
591+ changedTestExclusions++
592+ }
483593 if (original != synced) {
484594 launchFile.setText(synced, 'UTF-8')
485595 changedLaunches++
@@ -505,7 +615,7 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
505615 changedLaunchGroups++
506616 }
507617 }
508- logger. lifecycle(" Eclipse runtime paths aligned with ${ eclipseCache} (${ stableClasspaths.size()} Forge classpaths, ${ changedProjectClasspath} project classpath, ${ changedResourceExclusions} metadata exclusion, ${ changedPrepareLaunches} prepare launches, ${ changedLaunches} slim launches, ${ changedLaunchGroups} direct project launches updated)" )
618+ logger.lifecycle(" Eclipse runtime paths aligned with ${eclipseCache} (${stableClasspaths. size()} Forge classpaths, ${changedProjectClasspath} project classpath, ${changedResourceExclusions} metadata exclusion, ${changedPrepareLaunches} prepare launches, ${changedLaunches} slim launches, ${changedTestExclusions} test exclusions, ${ changedLaunchGroups} direct project launches updated)" )
509619 }
510620}
511621
0 commit comments