VolmLib pin removal

- The build resolves VolmLib master-SNAPSHOT when no sibling checkout is substituted
- The native runtime manifest, roots and keep rules come from the embedded natives
- The packed jar natives are verified against the embedded provider shas
- Every jar carries META-INF/volmit/volmlib.properties
- The build logs the resolved VolmLib once
- publishedNativeRuntime, the loader coordinate flags, mavenLocal and publish-volmlib are gone
This commit is contained in:
Brian Neumann-Fopiano
2026-09-29 09:33:26 -04:00
parent f60538343e
commit bf11d44370
20 changed files with 386 additions and 426 deletions
+6
View File
@@ -271,6 +271,12 @@ when it exists, otherwise `build/consumers/` inside the repo. `-Plocation=/path/
changes only the consumer directory. Both tasks copy all four verified platform jars into changes only the consumer directory. Both tasks copy all four verified platform jars into
`../PluginOuts/`. `../PluginOuts/`.
VolmLib is built from source when a `VolmLib` checkout sits beside the repo or in a parent directory
(`VOLMLIB_DIR` or `-PlocalVolmLibDirectory=<path>` pick another one). Without one, or with
`-PuseLocalVolmLib=false`, the build uses VolmLib `master-SNAPSHOT` from JitPack. There is no VolmLib
version to bump. The build logs which VolmLib it used, and every jar records it in
`META-INF/volmit/volmlib.properties`.
If you need help compiling as a developer or contributor, ask in the Discord. If you need help compiling as a developer or contributor, ask in the Discord.
## Adapters / modded development ## Adapters / modded development
+2 -6
View File
@@ -2,15 +2,11 @@ String apiVersion = providers.gradleProperty('apiVersion').get()
def mainClass = 'art.arcane.iris.Iris' def mainClass = 'art.arcane.iris.Iris'
def bootstrapperClass = 'art.arcane.iris.IrisBootstrap' def bootstrapperClass = 'art.arcane.iris.IrisBootstrap'
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
.get()
dependencies { dependencies {
compileOnly(project(':core')) compileOnly(project(':core'))
compileOnly(libs.lombok) compileOnly(libs.lombok)
annotationProcessor(libs.lombok) annotationProcessor(libs.lombok)
compileOnly(volmLibCoordinate) { compileOnly('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
compileOnly(libs.paper.api) compileOnly(libs.paper.api)
@@ -23,7 +19,7 @@ dependencies {
testImplementation(libs.bstats) testImplementation(libs.bstats)
testImplementation(project(':core')) testImplementation(project(':core'))
testImplementation(testFixtures(project(':core'))) testImplementation(testFixtures(project(':core')))
testImplementation(volmLibCoordinate) { testImplementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
compileOnly(libs.placeholderApi) compileOnly(libs.placeholderApi)
+7 -8
View File
@@ -32,11 +32,7 @@ buildscript {
maven { url = uri('https://jitpack.io') } maven { url = uri('https://jitpack.io') }
} }
dependencies { dependencies {
Properties libraryProperties = new Properties() classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
file('../../gradle.properties').withInputStream { InputStream stream -> libraryProperties.load(stream) }
String libraryCoordinate = providers.gradleProperty('volmLibCoordinate')
.getOrElse(libraryProperties.getProperty('volmLibCoordinate'))
classpath("com.github.VolmitSoftware.VolmLib:packaging:${libraryCoordinate.tokenize(':').last()}")
} }
} }
@@ -56,13 +52,13 @@ interface IrisFileOperations {
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations) IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
apply from: file('../../gradle/modded-generation-build-revision.gradle') apply from: file('../../gradle/modded-generation-build-revision.gradle')
apply from: file('../../gradle/volmlib-stamp.gradle')
Properties rootProperties = new Properties() Properties rootProperties = new Properties()
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) } file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2')) String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3')) String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse(rootProperties.getProperty('fabricLoaderVersion', '0.19.5')) String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse(rootProperties.getProperty('fabricLoaderVersion', '0.19.5'))
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
Closure<String> irisArtifactName = { String platform, String targetVersion -> Closure<String> irisArtifactName = { String platform, String targetVersion ->
return "Iris v${project.version} [${platform}] ${targetVersion}.jar" return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
} }
@@ -180,10 +176,10 @@ dependencies {
compileOnly(libs.spigot) { compileOnly(libs.spigot) {
transitive = false transitive = false
} }
add('bundle', volmLibCoordinate) { add('bundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('devBundle', volmLibCoordinate) { add('devBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('bundle', libs.zip) { add('bundle', libs.zip) {
@@ -286,6 +282,9 @@ tasks.named('shadowJar', ShadowJar).configure {
spec.delete(staleLoaderJars, legacyLoaderJar) spec.delete(staleLoaderJars, legacyLoaderJar)
} }
} }
from(tasks.named('generateVolmLibStamp')) {
into('META-INF/volmit')
}
archiveFileName.set(irisArtifactName('Fabric', "${minecraftVersion}+${fabricLoaderVersion}")) archiveFileName.set(irisArtifactName('Fabric', "${minecraftVersion}+${fabricLoaderVersion}"))
configurations = [project.configurations.named('bundle').get()] configurations = [project.configurations.named('bundle').get()]
mergeServiceFiles() mergeServiceFiles()
+8 -9
View File
@@ -32,11 +32,7 @@ buildscript {
maven { url = uri('https://jitpack.io') } maven { url = uri('https://jitpack.io') }
} }
dependencies { dependencies {
Properties libraryProperties = new Properties() classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
file('../../gradle.properties').withInputStream { InputStream stream -> libraryProperties.load(stream) }
String libraryCoordinate = providers.gradleProperty('volmLibCoordinate')
.getOrElse(libraryProperties.getProperty('volmLibCoordinate'))
classpath("com.github.VolmitSoftware.VolmLib:packaging:${libraryCoordinate.tokenize(':').last()}")
} }
} }
@@ -56,13 +52,13 @@ interface IrisFileOperations {
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations) IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
apply from: file('../../gradle/modded-generation-build-revision.gradle') apply from: file('../../gradle/modded-generation-build-revision.gradle')
apply from: file('../../gradle/volmlib-stamp.gradle')
Properties rootProperties = new Properties() Properties rootProperties = new Properties()
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) } file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2')) String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3')) String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse(rootProperties.getProperty('forgeVersion', '26.3-66.0.8')) String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse(rootProperties.getProperty('forgeVersion', '26.3-66.0.8'))
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
Closure<String> loaderDisplayVersion = { String loaderVersion -> Closure<String> loaderDisplayVersion = { String loaderVersion ->
String coordinatePrefix = "${minecraftVersion}-" String coordinatePrefix = "${minecraftVersion}-"
if (loaderVersion.startsWith(coordinatePrefix)) { if (loaderVersion.startsWith(coordinatePrefix)) {
@@ -173,13 +169,13 @@ dependencies {
compileOnly(libs.spigot) { compileOnly(libs.spigot) {
transitive = false transitive = false
} }
add('bundle', volmLibCoordinate) { add('bundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('devBundle', volmLibCoordinate) { add('devBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('runBundle', volmLibCoordinate) { add('runBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('bundle', libs.zip) { add('bundle', libs.zip) {
@@ -271,6 +267,9 @@ tasks.named('shadowJar', ShadowJar).configure {
spec.delete(staleLoaderJars, legacyLoaderJar) spec.delete(staleLoaderJars, legacyLoaderJar)
} }
} }
from(tasks.named('generateVolmLibStamp')) {
into('META-INF/volmit')
}
manifest { manifest {
// FML 26.3 has no TOML mixin handling at all (ModFileParser reads neither [[mixins]] nor // FML 26.3 has no TOML mixin handling at all (ModFileParser reads neither [[mixins]] nor
// accessTransformers on Forge). This manifest attribute is the only registration mechanism; // accessTransformers on Forge). This manifest attribute is the only registration mechanism;
+7 -8
View File
@@ -32,11 +32,7 @@ buildscript {
maven { url = uri('https://jitpack.io') } maven { url = uri('https://jitpack.io') }
} }
dependencies { dependencies {
Properties libraryProperties = new Properties() classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
file('../../gradle.properties').withInputStream { InputStream stream -> libraryProperties.load(stream) }
String libraryCoordinate = providers.gradleProperty('volmLibCoordinate')
.getOrElse(libraryProperties.getProperty('volmLibCoordinate'))
classpath("com.github.VolmitSoftware.VolmLib:packaging:${libraryCoordinate.tokenize(':').last()}")
} }
} }
@@ -56,13 +52,13 @@ interface IrisFileOperations {
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations) IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
apply from: file('../../gradle/modded-generation-build-revision.gradle') apply from: file('../../gradle/modded-generation-build-revision.gradle')
apply from: file('../../gradle/volmlib-stamp.gradle')
Properties rootProperties = new Properties() Properties rootProperties = new Properties()
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) } file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2')) String irisVersion = providers.gradleProperty('irisVersion').getOrElse(rootProperties.getProperty('irisVersion', '4.1.2-26.2'))
String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3')) String minecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse(rootProperties.getProperty('minecraftVersion', '26.3'))
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse(rootProperties.getProperty('neoForgeVersion', '26.3.0.33-beta')) String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse(rootProperties.getProperty('neoForgeVersion', '26.3.0.33-beta'))
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate').getOrElse(rootProperties.getProperty('volmLibCoordinate', 'com.github.VolmitSoftware:VolmLib:master-SNAPSHOT'))
Closure<String> irisArtifactName = { String platform, String targetVersion -> Closure<String> irisArtifactName = { String platform, String targetVersion ->
return "Iris v${project.version} [${platform}] ${targetVersion}.jar" return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
} }
@@ -152,10 +148,10 @@ dependencies {
compileOnly(libs.spigot) { compileOnly(libs.spigot) {
transitive = false transitive = false
} }
add('bundle', volmLibCoordinate) { add('bundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('devBundle', volmLibCoordinate) { add('devBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
add('bundle', libs.zip) { add('bundle', libs.zip) {
@@ -274,6 +270,9 @@ tasks.named('shadowJar', ShadowJar).configure {
spec.delete(staleLoaderJars, legacyLoaderJar) spec.delete(staleLoaderJars, legacyLoaderJar)
} }
} }
from(tasks.named('generateVolmLibStamp')) {
into('META-INF/volmit')
}
archiveFileName.set(irisArtifactName('NeoForge', "${minecraftVersion}+${neoForgeVersion}")) archiveFileName.set(irisArtifactName('NeoForge', "${minecraftVersion}+${neoForgeVersion}"))
configurations = [project.configurations.named('bundle').get()] configurations = [project.configurations.named('bundle').get()]
from(sourceSets.main.output) from(sourceSets.main.output)
+45 -104
View File
@@ -43,8 +43,7 @@ buildscript {
maven { url = uri('https://jitpack.io') } maven { url = uri('https://jitpack.io') }
} }
dependencies { dependencies {
String volmLibRevision = providers.gradleProperty('volmLibCoordinate').get().tokenize(':').last() classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
classpath("com.github.VolmitSoftware.VolmLib:packaging:${volmLibRevision}")
} }
} }
@@ -55,6 +54,7 @@ plugins {
apply plugin: 'art.arcane.volmit-packaging' apply plugin: 'art.arcane.volmit-packaging'
apply from: file('gradle/runtime-relocations.gradle') apply from: file('gradle/runtime-relocations.gradle')
apply from: file('gradle/volmlib-stamp.gradle')
interface IrisFileOperations { interface IrisFileOperations {
@Inject @Inject
@@ -76,15 +76,9 @@ String bukkitMinecraftRange = providers.gradleProperty('bukkitMinecraftRange').g
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse('0.19.5') String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse('0.19.5')
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse('26.3-66.0.8') String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse('26.3-66.0.8')
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse('26.3.0.33-beta') String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse('26.3.0.33-beta')
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate') String volmLibShared = 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT'
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT') File localVolmLibCheckout = (File) gradle.extensions.extraProperties.get('volmLibDirectory')
.get() Map<String, String> volmLibStamp = (Map<String, String>) gradle.extensions.extraProperties.get('volmLibStamp')
String useLocalVolmLib = providers.gradleProperty('useLocalVolmLib').getOrElse('true')
String localVolmLibDirectory = providers.gradleProperty('localVolmLibDirectory').getOrNull()
boolean useMavenLocal = providers.gradleProperty('useMavenLocal')
.orElse(useLocalVolmLib.equalsIgnoreCase('true') ? 'false' : 'true')
.map { String value -> value.equalsIgnoreCase('true') }
.get()
Closure<String> loaderDisplayVersion = { String loaderVersion -> Closure<String> loaderDisplayVersion = { String loaderVersion ->
String coordinatePrefix = "${minecraftVersion}-" String coordinatePrefix = "${minecraftVersion}-"
if (loaderVersion.startsWith(coordinatePrefix)) { if (loaderVersion.startsWith(coordinatePrefix)) {
@@ -153,11 +147,11 @@ nmsBindings.each { String key ->
} }
dependencies { dependencies {
implementation("com.github.VolmitSoftware.VolmLib:native-${key}:${volmLibCoordinate.tokenize(':').last()}") { implementation("com.github.VolmitSoftware.VolmLib:native-${key}:master-SNAPSHOT") {
transitive = false transitive = false
} }
compileOnly(project(':core')) compileOnly(project(':core'))
compileOnly(volmLibCoordinate) { compileOnly(volmLibShared) {
transitive = false transitive = false
} }
compileOnly(rootProject.libs.annotations) compileOnly(rootProject.libs.annotations)
@@ -169,10 +163,10 @@ nmsBindings.each { String key ->
} }
testImplementation(project(':core')) testImplementation(project(':core'))
testImplementation(testFixtures(project(':core'))) testImplementation(testFixtures(project(':core')))
testImplementation("com.github.VolmitSoftware.VolmLib:native-common:${volmLibCoordinate.tokenize(':').last()}") { testImplementation('com.github.VolmitSoftware.VolmLib:native-common:master-SNAPSHOT') {
transitive = false transitive = false
} }
testCompileOnly(volmLibCoordinate) { testCompileOnly(volmLibShared) {
transitive = false transitive = false
} }
testRuntimeOnly(project(':core')) testRuntimeOnly(project(':core'))
@@ -183,49 +177,32 @@ nmsBindings.each { String key ->
def included = configurations.create('included') def included = configurations.create('included')
def nativeRuntime = configurations.create('nativeRuntime') def nativeRuntime = configurations.create('nativeRuntime')
def publishedNativeRuntime = configurations.create('publishedNativeRuntime') {
canBeConsumed = false
transitive = false
resolutionStrategy.useGlobalDependencySubstitutionRules = false
}
repositories.configureEach { repository ->
if (repository.name != 'publishedNativeProviders') {
repository.content { notForConfigurations('publishedNativeRuntime') }
}
}
repositories.maven {
name = 'publishedNativeProviders'
url = uri('https://jitpack.io/')
content {
onlyForConfigurations('publishedNativeRuntime')
includeGroup('com.github.VolmitSoftware.VolmLib')
}
}
def nativeRuntimeOutput = layout.buildDirectory.dir('generated/native-runtime') def nativeRuntimeOutput = layout.buildDirectory.dir('generated/native-runtime')
def nativeRuntimeRules = layout.buildDirectory.file('generated/native-runtime-keep.pro') def nativeRuntimeRules = layout.buildDirectory.file('generated/native-runtime-keep.pro')
List<String> nativeRuntimeModules = ['native-common'] + nmsBindings.collect { String adapter -> 'native-' + adapter } List<String> nativeRuntimeModules = ['native-common'] + nmsBindings.collect { String adapter -> 'native-' + adapter }
dependencies { dependencies {
nativeRuntimeModules.each { String module -> nativeRuntimeModules.each { String module ->
add('nativeRuntime', "com.github.VolmitSoftware.VolmLib:${module}:${volmLibCoordinate.tokenize(':').last()}") { add('nativeRuntime', "com.github.VolmitSoftware.VolmLib:${module}:master-SNAPSHOT") {
transitive = false transitive = false
} }
add('publishedNativeRuntime', "com.github.VolmitSoftware.VolmLib:${module}:${volmLibCoordinate.tokenize(':').last()}")
} }
} }
// The natives PackedJar embeds are the single source for the runtime manifest, the reachability roots and
// the ProGuard keep rules, so the shrinker can never prune against a different provider build.
Closure<Map<String, File>> embeddedNatives = { ->
Map<ComponentIdentifier, File> resolved = new LinkedHashMap<>()
nativeRuntime.incoming.artifacts.artifacts.each { artifact ->
resolved.put(artifact.id.componentIdentifier, artifact.file)
}
return PackedJar.resolveNativeArtifacts(resolved)
}
def generateNativeRuntime = tasks.register('generateNativeRuntime') { def generateNativeRuntime = tasks.register('generateNativeRuntime') {
inputs.files(publishedNativeRuntime) inputs.files(nativeRuntime)
inputs.property('version', volmLibCoordinate.tokenize(':').last()) inputs.property('modules', nativeRuntimeModules)
inputs.property('adapters', nmsBindings)
outputs.dir(nativeRuntimeOutput) outputs.dir(nativeRuntimeOutput)
outputs.file(nativeRuntimeRules) outputs.file(nativeRuntimeRules)
doLast { doLast {
Map<ComponentIdentifier, File> resolved = new LinkedHashMap<>() NativeRuntimeArtifacts.generate(embeddedNatives(), nativeRuntimeModules,
publishedNativeRuntime.incoming.artifacts.artifacts.each { artifact ->
resolved.put(artifact.id.componentIdentifier, artifact.file)
}
Map<String, File> artifacts = NativeRuntimeArtifacts.publishedArtifacts(resolved,
nativeRuntimeModules, volmLibCoordinate.tokenize(':').last())
NativeRuntimeArtifacts.generate(artifacts, volmLibCoordinate.tokenize(':').last(),
nativeRuntimeOutput.get().asFile, nativeRuntimeRules.get().asFile) nativeRuntimeOutput.get().asFile, nativeRuntimeRules.get().asFile)
} }
} }
@@ -240,6 +217,9 @@ tasks.named('jar', Jar).configure {
inputs.files(included) inputs.files(included)
dependsOn(generateNativeRuntime) dependsOn(generateNativeRuntime)
from(nativeRuntimeOutput) from(nativeRuntimeOutput)
from(tasks.named('generateVolmLibStamp')) {
into('META-INF/volmit')
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
includeEmptyDirs = false includeEmptyDirs = false
from(jarJar) from(jarJar)
@@ -312,31 +292,6 @@ tasks.register('buildBukkit', Copy) {
// task therefore has to carry the full inventory of what those builds read: every shared source tree, // task therefore has to carry the full inventory of what those builds read: every shared source tree,
// every build script and version file they load, and the local VolmLib checkout when the composite // every build script and version file they load, and the local VolmLib checkout when the composite
// resolves one. Anything missing from that list publishes a stale jar. // resolves one. Anything missing from that list publishes a stale jar.
Closure<File> resolveLocalVolmLibDirectory = { ->
String configured = localVolmLibDirectory != null && !localVolmLibDirectory.isBlank()
? localVolmLibDirectory
: System.getenv('VOLMLIB_DIR')
if (configured != null && !configured.isBlank()) {
File configuredDirectory = new File(configured)
if (!configuredDirectory.isAbsolute()) {
configuredDirectory = new File(rootDir, configured)
}
return configuredDirectory.isDirectory() ? configuredDirectory : null
}
File current = rootDir
while (current != null) {
File candidate = new File(current, 'VolmLib')
if (new File(candidate, 'settings.gradle').isFile() || new File(candidate, 'settings.gradle.kts').isFile()) {
return candidate
}
current = current.parentFile
}
return null
}
List<Object> moddedSharedInputs = [] List<Object> moddedSharedInputs = []
[ [
'adapters/modded-common/src', 'adapters/modded-common/src',
@@ -353,11 +308,11 @@ List<Object> moddedSharedInputs = []
'lombok.config', 'lombok.config',
'gradle/libs.versions.toml', 'gradle/libs.versions.toml',
'gradle/volmlib-resolution.settings.gradle', 'gradle/volmlib-resolution.settings.gradle',
'gradle/volmlib-stamp.gradle',
'gradle/generation-build-revision.gradle', 'gradle/generation-build-revision.gradle',
'gradle/modded-generation-build-revision.gradle', 'gradle/modded-generation-build-revision.gradle',
'gradle/native-minecraft-sources.gradle' 'gradle/native-minecraft-sources.gradle'
].each { String path -> moddedSharedInputs.add(layout.projectDirectory.file(path).asFile) } ].each { String path -> moddedSharedInputs.add(layout.projectDirectory.file(path).asFile) }
File localVolmLibCheckout = useLocalVolmLib.equalsIgnoreCase('true') ? resolveLocalVolmLibDirectory() : null
if (localVolmLibCheckout != null) { if (localVolmLibCheckout != null) {
moddedSharedInputs.add(fileTree(localVolmLibCheckout) { moddedSharedInputs.add(fileTree(localVolmLibCheckout) {
include('shared/src/main/**', 'native-api/src/main/**', 'native-terrain-api/src/main/**', include('shared/src/main/**', 'native-api/src/main/**', 'native-terrain-api/src/main/**',
@@ -377,8 +332,7 @@ Closure<Void> declareModdedJarIo = { Exec task, String adapter, String artifactN
layout.projectDirectory.file("adapters/${adapter}/settings.gradle").asFile layout.projectDirectory.file("adapters/${adapter}/settings.gradle").asFile
).withPropertyName('adapterSources') ).withPropertyName('adapterSources')
versions.each { String key, String value -> task.inputs.property(key, value) } versions.each { String key, String value -> task.inputs.property(key, value) }
task.inputs.property('useLocalVolmLib', useLocalVolmLib) task.inputs.property('volmLibStamp', volmLibStamp)
task.inputs.property('volmLibCoordinate', volmLibCoordinate)
task.outputs.file(layout.projectDirectory.file("adapters/${adapter}/build/libs/${artifactName}")) task.outputs.file(layout.projectDirectory.file("adapters/${adapter}/build/libs/${artifactName}"))
return null return null
} }
@@ -394,8 +348,7 @@ tasks.register('fabricJar', Exec) {
"-PirisVersion=${project.version}", "-PirisVersion=${project.version}",
"-PminecraftVersion=${minecraftVersion}", "-PminecraftVersion=${minecraftVersion}",
"-PfabricLoaderVersion=${fabricLoaderVersion}", "-PfabricLoaderVersion=${fabricLoaderVersion}",
"-PuseLocalVolmLib=${useLocalVolmLib}", "-PuseLocalVolmLib=${localVolmLibCheckout != null}"
"-PvolmLibCoordinate=${volmLibCoordinate}"
] ]
if (localVolmLibCheckout != null) { if (localVolmLibCheckout != null) {
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath) environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
@@ -432,8 +385,7 @@ tasks.register('forgeJar', Exec) {
"-PirisVersion=${project.version}", "-PirisVersion=${project.version}",
"-PminecraftVersion=${minecraftVersion}", "-PminecraftVersion=${minecraftVersion}",
"-PforgeVersion=${forgeVersion}", "-PforgeVersion=${forgeVersion}",
"-PuseLocalVolmLib=${useLocalVolmLib}", "-PuseLocalVolmLib=${localVolmLibCheckout != null}"
"-PvolmLibCoordinate=${volmLibCoordinate}"
] ]
if (localVolmLibCheckout != null) { if (localVolmLibCheckout != null) {
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath) environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
@@ -470,8 +422,7 @@ tasks.register('neoforgeJar', Exec) {
"-PirisVersion=${project.version}", "-PirisVersion=${project.version}",
"-PminecraftVersion=${minecraftVersion}", "-PminecraftVersion=${minecraftVersion}",
"-PneoForgeVersion=${neoForgeVersion}", "-PneoForgeVersion=${neoForgeVersion}",
"-PuseLocalVolmLib=${useLocalVolmLib}", "-PuseLocalVolmLib=${localVolmLibCheckout != null}"
"-PvolmLibCoordinate=${volmLibCoordinate}"
] ]
if (localVolmLibCheckout != null) { if (localVolmLibCheckout != null) {
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath) environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
@@ -528,8 +479,7 @@ tasks.register('moddedTest', Exec) {
"-PirisVersion=${project.version}", "-PirisVersion=${project.version}",
"-PminecraftVersion=${minecraftVersion}", "-PminecraftVersion=${minecraftVersion}",
"-PfabricLoaderVersion=${fabricLoaderVersion}", "-PfabricLoaderVersion=${fabricLoaderVersion}",
"-PuseLocalVolmLib=${useLocalVolmLib}", "-PuseLocalVolmLib=${localVolmLibCheckout != null}"
"-PvolmLibCoordinate=${volmLibCoordinate}"
] ]
if (localVolmLibCheckout != null) { if (localVolmLibCheckout != null) {
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath) environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
@@ -545,8 +495,7 @@ tasks.register('moddedTest', Exec) {
inputs.property('irisVersion', project.version.toString()) inputs.property('irisVersion', project.version.toString())
inputs.property('minecraftVersion', minecraftVersion) inputs.property('minecraftVersion', minecraftVersion)
inputs.property('fabricLoaderVersion', fabricLoaderVersion) inputs.property('fabricLoaderVersion', fabricLoaderVersion)
inputs.property('useLocalVolmLib', useLocalVolmLib) inputs.property('volmLibStamp', volmLibStamp)
inputs.property('volmLibCoordinate', volmLibCoordinate)
outputs.dir(layout.projectDirectory.dir('adapters/fabric/build/test-results/test')) outputs.dir(layout.projectDirectory.dir('adapters/fabric/build/test-results/test'))
mustRunAfter(tasks.named('jar')) mustRunAfter(tasks.named('jar'))
mustRunAfter(project(':core').tasks.named('check')) mustRunAfter(project(':core').tasks.named('check'))
@@ -585,6 +534,7 @@ List<String> commonModdedArtifactEntries = [
'native/windows-x86_64/jlibdeflate.dll', 'native/windows-x86_64/jlibdeflate.dll',
'META-INF/iris/generation-kernels/catalog.tsv', 'META-INF/iris/generation-kernels/catalog.tsv',
'META-INF/iris/generation-kernels/abi-1.revision', 'META-INF/iris/generation-kernels/abi-1.revision',
'META-INF/volmit/volmlib.properties',
'META-INF/services/art.arcane.iris.localization.IrisMessageContributor', 'META-INF/services/art.arcane.iris.localization.IrisMessageContributor',
'art/arcane/iris/generation/runtime/IrisEngine.class', 'art/arcane/iris/generation/runtime/IrisEngine.class',
'art/arcane/iris/pack/datapack/DataVersion.class', 'art/arcane/iris/pack/datapack/DataVersion.class',
@@ -700,6 +650,7 @@ List<String> requiredBukkitArtifactEntries = [
'slimjar.dat', 'slimjar.dat',
'slimjar-resolutions.dat', 'slimjar-resolutions.dat',
'META-INF/iris/native-runtime.properties', 'META-INF/iris/native-runtime.properties',
'META-INF/volmit/volmlib.properties',
'iris-language-source.properties', 'iris-language-source.properties',
'agent.jar', 'agent.jar',
'art/arcane/iris/Iris.class', 'art/arcane/iris/Iris.class',
@@ -725,6 +676,7 @@ tasks.register('verifyBukkitArtifact') {
dependsOn('jar') dependsOn('jar')
File artifact = bukkitArtifact File artifact = bukkitArtifact
inputs.file(artifact) inputs.file(artifact)
inputs.files(nativeRuntime)
inputs.files(commandHandlerSources) inputs.files(commandHandlerSources)
inputs.files(mantleComponentSources) inputs.files(mantleComponentSources)
doLast { doLast {
@@ -733,7 +685,7 @@ tasks.register('verifyBukkitArtifact') {
requiredBukkitArtifactEntries, requiredBukkitArtifactEntries,
16, 16,
runtimeDownloadedPrefixes) runtimeDownloadedPrefixes)
NativeRuntimeArtifacts.verify(artifact, nmsBindings, volmLibCoordinate.tokenize(':').last()) NativeRuntimeArtifacts.verify(artifact, nativeRuntimeModules, embeddedNatives())
logger.lifecycle("Verified ${artifact.name} packaging and class reference graph") logger.lifecycle("Verified ${artifact.name} packaging and class reference graph")
} }
} }
@@ -819,11 +771,6 @@ tasks.register('irisDev', Copy) {
dependsOn(':core:javadocJar') dependsOn(':core:javadocJar')
} }
configurations.configureEach {
resolutionStrategy.cacheChangingModulesFor(0, 'seconds')
resolutionStrategy.cacheDynamicVersionsFor(0, 'seconds')
}
allprojects { allprojects {
apply plugin: 'java' apply plugin: 'java'
@@ -834,9 +781,6 @@ allprojects {
} }
repositories { repositories {
if (useMavenLocal) {
mavenLocal()
}
mavenCentral() mavenCentral()
maven { url = uri('https://repo.papermc.io/repository/maven-public/') } maven { url = uri('https://repo.papermc.io/repository/maven-public/') }
maven { url = uri('https://repo.codemc.org/repository/maven-public/') } maven { url = uri('https://repo.codemc.org/repository/maven-public/') }
@@ -990,7 +934,7 @@ project(':adapters:bukkit:nms:v26_3_R1') {
canBeResolved = true canBeResolved = true
} }
dependencies.add(headlessNativeSources.name, dependencies.add(headlessNativeSources.name,
"com.github.VolmitSoftware.VolmLib:native-minecraft26_2-sources:${volmLibCoordinate.tokenize(':').last()}") 'com.github.VolmitSoftware.VolmLib:native-minecraft26_2-sources:master-SNAPSHOT')
List<String> headlessNativeTypes = ['ModdedBlockState', 'ModdedBiome', 'NativeBlockProperties', 'NativeBlockResolver', List<String> headlessNativeTypes = ['ModdedBlockState', 'ModdedBiome', 'NativeBlockProperties', 'NativeBlockResolver',
'NativeBlockFaces', 'NativeStateRotator', 'NativeStateMerger', 'NativeBlockFaces', 'NativeStateRotator', 'NativeStateMerger',
'NativeRegistryAccess', 'ModdedItem', 'ModdedEntityType', 'NativeTileReader', 'NativeTileData'] 'NativeRegistryAccess', 'ModdedItem', 'ModdedEntityType', 'NativeTileReader', 'NativeTileData']
@@ -1016,10 +960,10 @@ project(':adapters:bukkit:nms:v26_3_R1') {
dependencies { dependencies {
offlineImplementation(project(':probe')) offlineImplementation(project(':probe'))
offlineImplementation(project(':core')) offlineImplementation(project(':core'))
offlineImplementation("com.github.VolmitSoftware.VolmLib:native-common:${volmLibCoordinate.tokenize(':').last()}") { offlineImplementation('com.github.VolmitSoftware.VolmLib:native-common:master-SNAPSHOT') {
transitive = false transitive = false
} }
offlineImplementation(volmLibCoordinate) { offlineImplementation(volmLibShared) {
transitive = false transitive = false
} }
} }
@@ -1132,14 +1076,11 @@ commands:
} }
tasks.withType(PackedJar).configureEach { tasks.withType(PackedJar).configureEach {
nativeManifestPath.set('META-INF/iris/native-runtime.properties') nativeManifestPath.set(NativeRuntimeArtifacts.MANIFEST)
nativeResourceDirectory.set('META-INF/iris/native/') nativeResourceDirectory.set(NativeRuntimeArtifacts.RESOURCES)
dependsOn(tasks.named('verifyBukkitArtifact'), configurations.nativeRuntime) dependsOn(tasks.named('verifyBukkitArtifact'), nativeRuntime)
nativeArtifacts.set(providers.provider { nativeArtifacts.set(providers.provider { embeddedNatives() })
Map<ComponentIdentifier, File> resolved = new LinkedHashMap<>() doLast { PackedJar task ->
configurations.nativeRuntime.incoming.artifacts.artifacts.each { artifact -> NativeRuntimeArtifacts.verifyPacked(task.outputJar.get().asFile, nativeRuntimeModules, embeddedNatives())
resolved.put(artifact.id.componentIdentifier, artifact.file)
} }
PackedJar.resolveNativeArtifacts(resolved)
})
} }
+1
View File
@@ -32,6 +32,7 @@ dependencies {
implementation(gradleApi()) implementation(gradleApi())
implementation('org.ow2.asm:asm:9.10.1') implementation('org.ow2.asm:asm:9.10.1')
implementation('org.apache.commons:commons-compress:1.28.0') implementation('org.apache.commons:commons-compress:1.28.0')
implementation('org.tukaani:xz:1.10')
implementation('io.papermc.paperweight:paperweight-userdev:2.0.0-beta.21') implementation('io.papermc.paperweight:paperweight-userdev:2.0.0-beta.21')
testImplementation('junit:junit:4.13.2') testImplementation('junit:junit:4.13.2')
} }
@@ -1,7 +1,7 @@
import org.gradle.api.GradleException; import org.gradle.api.GradleException;
import org.gradle.api.artifacts.component.ComponentIdentifier; import org.tukaani.xz.XZInputStream;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -11,6 +11,7 @@ import java.nio.file.Path;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HexFormat; import java.util.HexFormat;
import java.util.List; import java.util.List;
@@ -21,46 +22,32 @@ import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public final class NativeRuntimeArtifacts { public final class NativeRuntimeArtifacts {
public static final String MANIFEST = "META-INF/iris/native-runtime.properties"; public static final String MANIFEST = "META-INF/iris/native-runtime.properties";
public static final String RESOURCES = "META-INF/iris/native/";
private static final String PAYLOAD = "META-INF/volmit/runtime.jar.xz";
private static final String GROUP = "com.github.VolmitSoftware.VolmLib"; private static final String GROUP = "com.github.VolmitSoftware.VolmLib";
private static final String NATIVE = "art/arcane/volmlib/nativelib/"; private static final String NATIVE = "art/arcane/volmlib/nativelib/";
private NativeRuntimeArtifacts() { private NativeRuntimeArtifacts() {
} }
public static Map<String, File> publishedArtifacts(Map<ComponentIdentifier, File> resolved, public static void generate(Map<String, File> natives, List<String> modules, File output, File rules) throws IOException {
List<String> modules, String version) { requireModules(natives, modules);
Map<String, File> artifacts = new TreeMap<>(); Map<String, File> providers = new TreeMap<>(natives);
for (Map.Entry<ComponentIdentifier, File> entry : resolved.entrySet()) {
if (!(entry.getKey() instanceof ModuleComponentIdentifier component)
|| !GROUP.equals(component.getGroup()) || !version.equals(component.getVersion())
|| !modules.contains(component.getModule())) {
throw new GradleException("Native runtime providers must resolve to published coordinates at "
+ version + ": " + entry.getKey().getDisplayName());
}
if (artifacts.put(component.getModule(), entry.getValue()) != null) {
throw new GradleException("Duplicate native runtime provider: " + component.getModule());
}
}
if (!artifacts.keySet().equals(new TreeSet<>(modules))) {
throw new GradleException("Published native runtime providers differ: " + artifacts.keySet()
+ "; expected " + modules);
}
return artifacts;
}
public static void generate(Map<String, File> artifacts, String version, File output, File rules) throws IOException {
List<String> manifest = new ArrayList<>(); List<String> manifest = new ArrayList<>();
manifest.add("modules=" + String.join(",", artifacts.keySet())); manifest.add("modules=" + String.join(",", providers.keySet()));
manifest.add("repository=https://jitpack.io/"); manifest.add("storage=embedded");
Set<String> retained = new TreeSet<>(); Set<String> retained = new TreeSet<>();
for (Map.Entry<String, File> artifact : artifacts.entrySet()) { for (Map.Entry<String, File> provider : providers.entrySet()) {
String module = artifact.getKey(); String module = provider.getKey();
manifest.add(module + ".coordinate=" + GROUP + ":" + module + ":" + version); String digest = digest(Files.readAllBytes(provider.getValue().toPath()));
manifest.add(module + ".sha256=" + digest(artifact.getValue())); manifest.add(module + ".coordinate=" + GROUP + ":" + module + ":embedded-" + digest);
try (JarFile jar = new JarFile(artifact.getValue())) { manifest.add(module + ".sha256=" + digest);
try (JarFile jar = new JarFile(provider.getValue())) {
Enumeration<JarEntry> entries = jar.entries(); Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement(); JarEntry entry = entries.nextElement();
@@ -92,31 +79,15 @@ public final class NativeRuntimeArtifacts {
Files.write(rules.toPath(), keep, StandardCharsets.UTF_8); Files.write(rules.toPath(), keep, StandardCharsets.UTF_8);
} }
public static void verify(File artifact, List<String> adapters, String version) throws IOException { public static void verify(File artifact, List<String> modules, Map<String, File> natives) throws IOException {
requireModules(natives, modules);
try (JarFile jar = new JarFile(artifact)) { try (JarFile jar = new JarFile(artifact)) {
JarEntry entry = jar.getJarEntry(MANIFEST); JarEntry entry = jar.getJarEntry(MANIFEST);
if (entry == null) { if (entry == null) {
throw new GradleException("Missing native runtime dependency manifest"); throw new GradleException("Missing native runtime dependency manifest");
} }
Properties manifest = new Properties();
try (InputStream input = jar.getInputStream(entry)) { try (InputStream input = jar.getInputStream(entry)) {
manifest.load(input); verifyManifest(input.readAllBytes(), natives);
}
Set<String> expected = new TreeSet<>();
expected.add("native-common");
for (String adapter : adapters) {
expected.add("native-" + adapter);
}
Set<String> actual = new TreeSet<>(List.of(manifest.getProperty("modules", "").split(",")));
if (!expected.equals(actual)) {
throw new GradleException("Native dependency modules differ: " + actual + "; expected " + expected);
}
for (String module : expected) {
String coordinate = GROUP + ":" + module + ":" + version;
if (!coordinate.equals(manifest.getProperty(module + ".coordinate"))
|| !manifest.getProperty(module + ".sha256", "").matches("[0-9a-f]{64}")) {
throw new GradleException("Invalid native runtime dependency: " + module);
}
} }
Enumeration<JarEntry> entries = jar.entries(); Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
@@ -128,6 +99,82 @@ public final class NativeRuntimeArtifacts {
} }
} }
public static void verifyPacked(File artifact, List<String> modules, Map<String, File> natives) throws IOException {
requireModules(natives, modules);
Map<String, byte[]> contents;
try (JarFile jar = new JarFile(artifact)) {
JarEntry payload = jar.getJarEntry(PAYLOAD);
if (payload == null) {
contents = read(Files.newInputStream(artifact.toPath()));
} else {
try (InputStream input = new XZInputStream(jar.getInputStream(payload))) {
contents = read(new ByteArrayInputStream(input.readAllBytes()));
}
JarEntry outer = jar.getJarEntry(MANIFEST);
byte[] embedded = contents.get(MANIFEST);
if (outer != null && embedded != null) {
try (InputStream input = jar.getInputStream(outer)) {
if (!Arrays.equals(input.readAllBytes(), embedded)) {
throw new GradleException("Packed native runtime manifests differ");
}
}
}
}
}
byte[] manifest = contents.get(MANIFEST);
if (manifest == null) {
throw new GradleException("Missing native runtime dependency manifest");
}
verifyManifest(manifest, natives);
for (String module : natives.keySet()) {
byte[] provider = contents.get(RESOURCES + module + ".jar");
if (provider == null) {
throw new GradleException("Missing embedded native provider: " + module);
}
if (!digest(provider).equals(digest(Files.readAllBytes(natives.get(module).toPath())))) {
throw new GradleException("Embedded native provider differs from the resolved build: " + module);
}
}
}
private static void verifyManifest(byte[] bytes, Map<String, File> natives) throws IOException {
Properties manifest = new Properties();
manifest.load(new ByteArrayInputStream(bytes));
Set<String> actual = new TreeSet<>(List.of(manifest.getProperty("modules", "").split(",")));
if (!natives.keySet().equals(actual)) {
throw new GradleException("Native dependency modules differ: " + actual + "; expected " + natives.keySet());
}
if (!"embedded".equals(manifest.getProperty("storage"))) {
throw new GradleException("Native runtime providers must be embedded: " + manifest.getProperty("storage"));
}
for (Map.Entry<String, File> provider : natives.entrySet()) {
String module = provider.getKey();
String digest = digest(Files.readAllBytes(provider.getValue().toPath()));
if (!digest.equals(manifest.getProperty(module + ".sha256"))
|| !(GROUP + ":" + module + ":embedded-" + digest).equals(manifest.getProperty(module + ".coordinate"))) {
throw new GradleException("Native runtime manifest does not describe the embedded provider: " + module);
}
}
}
private static void requireModules(Map<String, File> natives, List<String> modules) {
if (!natives.keySet().equals(new TreeSet<>(modules))) {
throw new GradleException("Embedded native providers differ: " + natives.keySet() + "; expected " + modules);
}
}
private static Map<String, byte[]> read(InputStream source) throws IOException {
Map<String, byte[]> contents = new TreeMap<>();
try (ZipInputStream archive = new ZipInputStream(source)) {
for (ZipEntry entry = archive.getNextEntry(); entry != null; entry = archive.getNextEntry()) {
if (!entry.isDirectory()) {
contents.put(entry.getName(), archive.readAllBytes());
}
}
}
return contents;
}
private static boolean implementation(String name) { private static boolean implementation(String name) {
if (!name.startsWith(NATIVE)) { if (!name.startsWith(NATIVE)) {
return false; return false;
@@ -137,9 +184,9 @@ public final class NativeRuntimeArtifacts {
|| relative.matches("v[0-9_]+R[0-9]+/.*"); || relative.matches("v[0-9_]+R[0-9]+/.*");
} }
private static String digest(File file) throws IOException { private static String digest(byte[] bytes) {
try { try {
return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(file.toPath()))); return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(bytes));
} catch (NoSuchAlgorithmException exception) { } catch (NoSuchAlgorithmException exception) {
throw new IllegalStateException(exception); throw new IllegalStateException(exception);
} }
@@ -1,12 +1,15 @@
import org.gradle.api.GradleException; import org.gradle.api.GradleException;
import org.gradle.api.artifacts.ModuleIdentifier; import org.junit.Rule;
import org.gradle.api.artifacts.component.ComponentIdentifier;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.XZOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -15,122 +18,149 @@ import java.util.HexFormat;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.TreeMap;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class NativeRuntimeArtifactsTest { public class NativeRuntimeArtifactsTest {
@Test private static final List<String> MODULES = List.of("native-common", "native-v26_2_R1");
public void acceptsOnlyRequestedPublishedCoordinates() {
File common = new File("common.jar"); @Rule
File provider = new File("provider.jar"); public TemporaryFolder temporary = new TemporaryFolder();
Map<ComponentIdentifier, File> resolved = Map.of(
module("native-common", "revision"), common,
module("native-v26_2_R1", "revision"), provider);
assertEquals(Map.of("native-common", common, "native-v26_2_R1", provider),
NativeRuntimeArtifacts.publishedArtifacts(resolved,
List.of("native-common", "native-v26_2_R1"), "revision"));
}
@Test @Test
public void rejectsCompositeProjectArtifacts() { public void describesTheEmbeddedProvidersAndRetainsTheirSharedReferences() throws Exception {
ComponentIdentifier project = () -> "project :VolmLib:native-common"; Map<String, File> natives = natives();
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.publishedArtifacts( File output = temporary.newFolder("generated");
Map.of(project, new File("native-common-local-SNAPSHOT.jar")), List.of("native-common"), "revision")); File rules = new File(output, "keep.pro");
} NativeRuntimeArtifacts.generate(natives, MODULES, output, rules);
@Test
public void rejectsUnexpectedCoordinates() {
List<ComponentIdentifier> invalid = List.of(
new PublishedModule("other.group", "native-common", "revision"),
module("native-common", "other-revision"),
module("native-v26_3_R1", "revision"));
for (ComponentIdentifier component : invalid) {
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.publishedArtifacts(
Map.of(component, new File("provider.jar")), List.of("native-common"), "revision"));
}
}
@Test
public void rejectsMissingProviders() {
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.publishedArtifacts(
Map.of(module("native-common", "revision"), new File("common.jar")),
List.of("native-common", "native-v26_2_R1"), "revision"));
}
@Test
public void recordsExactDependenciesAndRetainsSharedProviderReferences() throws Exception {
Path directory = Files.createTempDirectory("native-artifacts");
File provider = directory.resolve("provider.jar").toFile();
ClassWriter writer = new ClassWriter(0);
writer.visit(Opcodes.V17, Opcodes.ACC_PUBLIC, "art/arcane/volmlib/nativelib/v26_2_R1/terrain/Provider", null,
"art/arcane/volmlib/util/collection/KList", null);
writer.visitEnd();
try (JarOutputStream jar = new JarOutputStream(Files.newOutputStream(provider.toPath()))) {
jar.putNextEntry(new JarEntry("art/arcane/volmlib/nativelib/v26_2_R1/terrain/Provider.class"));
jar.write(writer.toByteArray());
jar.closeEntry();
}
File rules = directory.resolve("keep.pro").toFile();
NativeRuntimeArtifacts.generate(Map.of("native-common", provider, "native-v26_2_R1", provider),
"revision", directory.toFile(), rules);
Properties manifest = new Properties(); Properties manifest = new Properties();
try (Reader reader = Files.newBufferedReader(directory.resolve(NativeRuntimeArtifacts.MANIFEST))) { try (Reader reader = Files.newBufferedReader(output.toPath().resolve(NativeRuntimeArtifacts.MANIFEST))) {
manifest.load(reader); manifest.load(reader);
} }
String digest = HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256") assertEquals("native-common,native-v26_2_R1", manifest.getProperty("modules"));
.digest(Files.readAllBytes(provider.toPath()))); assertEquals("embedded", manifest.getProperty("storage"));
assertEquals(digest, manifest.getProperty("native-common.sha256")); assertFalse(manifest.containsKey("repository"));
assertEquals(digest, manifest.getProperty("native-v26_2_R1.sha256")); for (String module : MODULES) {
String digest = digest(Files.readAllBytes(natives.get(module).toPath()));
assertEquals(digest, manifest.getProperty(module + ".sha256"));
assertEquals("com.github.VolmitSoftware.VolmLib:" + module + ":embedded-" + digest,
manifest.getProperty(module + ".coordinate"));
}
assertTrue(Files.readString(rules.toPath()).contains("-keep class art.arcane.volmlib.util.collection.KList { *; }")); assertTrue(Files.readString(rules.toPath()).contains("-keep class art.arcane.volmlib.util.collection.KList { *; }"));
File plugin = directory.resolve("plugin.jar").toFile(); assertEquals(List.of("art/arcane/volmlib/util/collection/KList"),
try (JarOutputStream jar = new JarOutputStream(Files.newOutputStream(plugin.toPath()))) { Files.readAllLines(output.toPath().resolve("META-INF/volmit/runtime-roots.list")));
jar.putNextEntry(new JarEntry(NativeRuntimeArtifacts.MANIFEST)); }
Files.copy(directory.resolve(NativeRuntimeArtifacts.MANIFEST), jar);
@Test
public void rejectsAProviderSetThatDiffersFromTheRuntimeModules() throws Exception {
Map<String, File> natives = natives();
natives.remove("native-v26_2_R1");
File output = temporary.newFolder("generated");
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.generate(natives, MODULES, output,
new File(output, "keep.pro")));
}
@Test
public void verifiesThePluginManifestAgainstTheProvidersBeingEmbedded() throws Exception {
Map<String, File> natives = natives();
File plugin = plugin(natives, Map.of());
NativeRuntimeArtifacts.verify(plugin, MODULES, natives);
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin,
List.of("native-common", "native-v26_3_R1"), natives));
Map<String, File> rebuilt = new TreeMap<>(natives);
rebuilt.put("native-v26_2_R1", provider("rebuilt.jar", "art/arcane/volmlib/util/collection/KMap"));
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin, MODULES, rebuilt));
}
@Test
public void rejectsProviderImplementationsBundledOutsideTheEmbeddedJars() throws Exception {
Map<String, File> natives = natives();
File plugin = plugin(natives, Map.of("art/arcane/volmlib/nativelib/v26_2_R1/terrain/Provider.class", new byte[0]));
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin, MODULES, natives));
}
@Test
public void verifiesTheEmbeddedProviderBytesInsideThePackedRuntime() throws Exception {
Map<String, File> natives = natives();
Map<String, byte[]> runtime = runtime(natives, natives);
NativeRuntimeArtifacts.verifyPacked(packed(runtime), MODULES, natives);
NativeRuntimeArtifacts.verifyPacked(jar("ordinary.jar", runtime), MODULES, natives);
Map<String, File> rebuilt = new TreeMap<>(natives);
rebuilt.put("native-v26_2_R1", provider("rebuilt.jar", "art/arcane/volmlib/util/collection/KMap"));
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verifyPacked(packed(runtime(natives, rebuilt)),
MODULES, natives));
Map<String, byte[]> missing = new TreeMap<>(runtime);
missing.remove(NativeRuntimeArtifacts.RESOURCES + "native-v26_2_R1.jar");
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verifyPacked(packed(missing), MODULES, natives));
}
private Map<String, File> natives() throws IOException {
Map<String, File> natives = new TreeMap<>();
natives.put("native-common", provider("common.jar", "java/lang/Object"));
natives.put("native-v26_2_R1", provider("v26_2_R1.jar", "art/arcane/volmlib/util/collection/KList"));
return natives;
}
private File provider(String name, String superclass) throws IOException {
ClassWriter writer = new ClassWriter(0);
writer.visit(Opcodes.V17, Opcodes.ACC_PUBLIC, "art/arcane/volmlib/nativelib/v26_2_R1/terrain/Provider", null,
superclass, null);
writer.visitEnd();
return jar(name, Map.of("art/arcane/volmlib/nativelib/v26_2_R1/terrain/Provider.class", writer.toByteArray()));
}
private File plugin(Map<String, File> natives, Map<String, byte[]> extra) throws IOException {
File generated = temporary.newFolder();
NativeRuntimeArtifacts.generate(natives, MODULES, generated, new File(generated, "keep.pro"));
Map<String, byte[]> contents = new TreeMap<>(extra);
contents.put(NativeRuntimeArtifacts.MANIFEST,
Files.readAllBytes(generated.toPath().resolve(NativeRuntimeArtifacts.MANIFEST)));
return jar("plugin.jar", contents);
}
private Map<String, byte[]> runtime(Map<String, File> described, Map<String, File> embedded) throws IOException {
File generated = temporary.newFolder();
NativeRuntimeArtifacts.generate(described, MODULES, generated, new File(generated, "keep.pro"));
Map<String, byte[]> contents = new TreeMap<>();
contents.put(NativeRuntimeArtifacts.MANIFEST,
Files.readAllBytes(generated.toPath().resolve(NativeRuntimeArtifacts.MANIFEST)));
for (Map.Entry<String, File> provider : embedded.entrySet()) {
contents.put(NativeRuntimeArtifacts.RESOURCES + provider.getKey() + ".jar",
Files.readAllBytes(provider.getValue().toPath()));
}
return contents;
}
private File packed(Map<String, byte[]> runtime) throws IOException {
ByteArrayOutputStream compressed = new ByteArrayOutputStream();
try (XZOutputStream xz = new XZOutputStream(compressed, new LZMA2Options(1))) {
xz.write(Files.readAllBytes(jar("payload.jar", runtime).toPath()));
}
Map<String, byte[]> outer = new TreeMap<>();
outer.put(NativeRuntimeArtifacts.MANIFEST, runtime.get(NativeRuntimeArtifacts.MANIFEST));
outer.put("META-INF/volmit/runtime.jar.xz", compressed.toByteArray());
return jar("packed.jar", outer);
}
private File jar(String name, Map<String, byte[]> contents) throws IOException {
Path file = temporary.newFolder().toPath().resolve(name);
try (JarOutputStream jar = new JarOutputStream(Files.newOutputStream(file))) {
for (Map.Entry<String, byte[]> entry : contents.entrySet()) {
jar.putNextEntry(new JarEntry(entry.getKey()));
jar.write(entry.getValue());
jar.closeEntry(); jar.closeEntry();
} }
NativeRuntimeArtifacts.verify(plugin, List.of("v26_2_R1"), "revision"); }
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin, List.of("v26_3_R1"), "revision")); return file.toFile();
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin, List.of("v26_2_R1"), "other"));
} }
private static ModuleComponentIdentifier module(String module, String version) { private static String digest(byte[] bytes) throws Exception {
return new PublishedModule("com.github.VolmitSoftware.VolmLib", module, version); return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(bytes));
}
private record PublishedModule(String group, String module, String version)
implements ModuleComponentIdentifier, ModuleIdentifier {
@Override
public String getGroup() {
return group;
}
@Override
public String getModule() {
return module;
}
@Override
public String getVersion() {
return version;
}
@Override
public ModuleIdentifier getModuleIdentifier() {
return this;
}
@Override
public String getName() {
return module;
}
@Override
public String getDisplayName() {
return group + ":" + module + ":" + version;
}
} }
} }
+3 -6
View File
@@ -38,9 +38,6 @@ plugins {
apply from: rootProject.file('gradle/runtime-relocations.gradle') apply from: rootProject.file('gradle/runtime-relocations.gradle')
def lib = 'art.arcane.iris.util' def lib = 'art.arcane.iris.util'
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
.get()
String languageSourceReference = providers.gradleProperty('languageRevision').orElse('master').get() String languageSourceReference = providers.gradleProperty('languageRevision').orElse('master').get()
List<File> languageSourceFiles = fileTree('src/main/resources/languages') { List<File> languageSourceFiles = fileTree('src/main/resources/languages') {
@@ -93,10 +90,10 @@ tasks.named('processResources').configure {
*/ */
dependencies { dependencies {
api(project(':spi')) api(project(':spi'))
api("com.github.VolmitSoftware.VolmLib:native-api:${volmLibCoordinate.tokenize(':').last()}") { api('com.github.VolmitSoftware.VolmLib:native-api:master-SNAPSHOT') {
transitive = false transitive = false
} }
api("com.github.VolmitSoftware.VolmLib:native-terrain-api:${volmLibCoordinate.tokenize(':').last()}") { api('com.github.VolmitSoftware.VolmLib:native-terrain-api:master-SNAPSHOT') {
transitive = false transitive = false
} }
@@ -129,7 +126,7 @@ dependencies {
// Shaded // Shaded
implementation('de.crazydev22.slimjar.helper:spigot:2.1.9') implementation('de.crazydev22.slimjar.helper:spigot:2.1.9')
implementation(volmLibCoordinate) { implementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
implementation('com.moandjiezana.toml:toml4j:0.7.2') { implementation('com.moandjiezana.toml:toml4j:0.7.2') {
-1
View File
@@ -28,4 +28,3 @@ apiVersion=26.1
fabricLoaderVersion=0.19.5 fabricLoaderVersion=0.19.5
forgeVersion=26.3-66.0.8 forgeVersion=26.3-66.0.8
neoForgeVersion=26.3.0.33-beta neoForgeVersion=26.3.0.33-beta
volmLibCoordinate=com.github.VolmitSoftware.VolmLib:volmlib-shared:d24d28acddbf3555c0c30ac99569ebacd476ce27
+1 -2
View File
@@ -13,13 +13,12 @@ Configuration kernelDependencies = configurations.create('generationKernelDepend
extendsFrom(configurations.implementation, configurations.slim, configurations.annotationProcessor) extendsFrom(configurations.implementation, configurations.slim, configurations.annotationProcessor)
} }
dependencies.add(kernelDependencies.name, libs.guava) dependencies.add(kernelDependencies.name, libs.guava)
String nativeLibraryVersion = providers.gradleProperty('volmLibCoordinate').get().tokenize(':').last()
List<String> nativeRevisionModules = ['native-common', 'native-minecraft26_2-sources'] List<String> nativeRevisionModules = ['native-common', 'native-minecraft26_2-sources']
for (String adapter : rootProject.extensions.extraProperties.get('nativeDevelopmentAdapters')) { for (String adapter : rootProject.extensions.extraProperties.get('nativeDevelopmentAdapters')) {
nativeRevisionModules.add('native-' + adapter) nativeRevisionModules.add('native-' + adapter)
} }
for (String module : nativeRevisionModules) { for (String module : nativeRevisionModules) {
dependencies.add(kernelDependencies.name, "com.github.VolmitSoftware.VolmLib:${module}:${nativeLibraryVersion}") { dependencies.add(kernelDependencies.name, "com.github.VolmitSoftware.VolmLib:${module}:master-SNAPSHOT") {
transitive = false transitive = false
} }
} }
+1 -5
View File
@@ -3,16 +3,12 @@ Configuration nativeMinecraftSources = configurations.create('nativeMinecraftSou
canBeResolved = true canBeResolved = true
} }
Properties nativeLibraryProperties = new Properties()
file('../../gradle.properties').withInputStream { InputStream stream -> nativeLibraryProperties.load(stream) }
String nativeLibraryCoordinate = providers.gradleProperty('volmLibCoordinate')
.getOrElse(nativeLibraryProperties.getProperty('volmLibCoordinate'))
String nativeSourceLoader = extensions.extraProperties.get('nativeSourceLoader') String nativeSourceLoader = extensions.extraProperties.get('nativeSourceLoader')
String nativeSourceImplementation = 'minecraft26_2' String nativeSourceImplementation = 'minecraft26_2'
String nativeSourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3') String nativeSourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
extensions.extraProperties.set('nativeSourceImplementation', nativeSourceImplementation) extensions.extraProperties.set('nativeSourceImplementation', nativeSourceImplementation)
dependencies.add(nativeMinecraftSources.name, dependencies.add(nativeMinecraftSources.name,
"com.github.VolmitSoftware.VolmLib:native-${nativeSourceImplementation}-sources:${nativeLibraryCoordinate.tokenize(':').last()}") "com.github.VolmitSoftware.VolmLib:native-${nativeSourceImplementation}-sources:master-SNAPSHOT")
TaskProvider<Sync> unpackNativeMinecraftSources = tasks.register('unpackNativeMinecraftSources', Sync) { TaskProvider<Sync> unpackNativeMinecraftSources = tasks.register('unpackNativeMinecraftSources', Sync) {
dependsOn(nativeMinecraftSources) dependsOn(nativeMinecraftSources)
+49 -4
View File
@@ -40,10 +40,17 @@
* otherwise walk up from settingsDir looking for a `VolmLib` directory * otherwise walk up from settingsDir looking for a `VolmLib` directory
* that contains a settings script. * that contains a settings script.
* *
* When nothing is found the build falls back to the published `volmLibCoordinate` from * When nothing is found, or substitution is disabled, every VolmLib coordinate resolves the published
* gradle.properties. * master-SNAPSHOT from JitPack instead, re-checked on every build like the rest of the plugin fleet.
*
* The outcome is logged once per top-level build and handed to the build scripts through `gradle`
* extra properties: `volmLibDirectory` (the substituted checkout, or null) and `volmLibStamp` (the
* content of META-INF/volmit/volmlib.properties in every shipped jar).
*/ */
import org.gradle.api.artifacts.Configuration
import org.gradle.process.ExecOutput
import java.io.File import java.io.File
boolean irisHasVolmLibSettings(File directory) { boolean irisHasVolmLibSettings(File directory) {
@@ -85,9 +92,47 @@ boolean irisUseLocalVolmLib = providers.gradleProperty('useLocalVolmLib')
.orElse('true') .orElse('true')
.map { String value -> value.equalsIgnoreCase('true') } .map { String value -> value.equalsIgnoreCase('true') }
.get() .get()
File irisLocalVolmLibDirectory = irisResolveLocalVolmLibDirectory() File irisLocalVolmLibDirectory = irisUseLocalVolmLib ? irisResolveLocalVolmLibDirectory() : null
if (irisUseLocalVolmLib && irisLocalVolmLibDirectory != null) { String irisGit(File directory, String... arguments) {
try {
ExecOutput result = providers.exec {
commandLine(['git', '-C', directory.absolutePath] + arguments.toList())
ignoreExitValue = true
}
return result.result.get().exitValue == 0 ? result.standardOutput.asText.get().trim() : null
} catch (Exception ignored) {
return null
}
}
Map<String, String> irisVolmLibStamp
String irisVolmLibDescription
if (irisLocalVolmLibDirectory == null) {
irisVolmLibStamp = [source: 'published master-SNAPSHOT']
irisVolmLibDescription = 'published master-SNAPSHOT'
gradle.allprojects { Project project ->
project.buildscript.configurations.configureEach { Configuration configuration ->
configuration.resolutionStrategy.cacheChangingModulesFor(0, 'seconds')
}
project.configurations.configureEach { Configuration configuration ->
configuration.resolutionStrategy.cacheChangingModulesFor(0, 'seconds')
}
}
} else {
String commit = irisGit(irisLocalVolmLibDirectory, 'rev-parse', 'HEAD')
String status = commit == null ? null : irisGit(irisLocalVolmLibDirectory, 'status', '--porcelain')
String dirty = status == null ? 'unknown' : String.valueOf(!status.isEmpty())
irisVolmLibStamp = [source: 'local', commit: commit ?: 'unknown', dirty: dirty]
irisVolmLibDescription = "${irisLocalVolmLibDirectory.canonicalPath} @ ${commit == null ? 'unknown' : commit.take(7)}${dirty == 'true' ? '+dirty' : ''}"
}
gradle.extensions.extraProperties.set('volmLibDirectory', irisLocalVolmLibDirectory)
gradle.extensions.extraProperties.set('volmLibStamp', irisVolmLibStamp)
if (gradle.parent == null) {
logger.lifecycle("VolmLib: ${irisVolmLibDescription}")
}
if (irisLocalVolmLibDirectory != null) {
includeBuild(irisLocalVolmLibDirectory) { includeBuild(irisLocalVolmLibDirectory) {
dependencySubstitution { dependencySubstitution {
substitute(module('com.github.VolmitSoftware:VolmLib')).using(project(':shared')) substitute(module('com.github.VolmitSoftware:VolmLib')).using(project(':shared'))
+26
View File
@@ -0,0 +1,26 @@
/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Writes the VolmLib provenance that gradle/volmlib-resolution.settings.gradle resolved. Every shipped jar
// carries it as META-INF/volmit/volmlib.properties.
Map<String, String> volmLibStamp = (Map<String, String>) gradle.extensions.extraProperties.get('volmLibStamp')
tasks.register('generateVolmLibStamp', WriteProperties) {
destinationFile.set(layout.buildDirectory.file('generated/volmlib-stamp/volmlib.properties'))
properties(volmLibStamp)
}
+1 -1
View File
@@ -1,4 +1,4 @@
jdk: jdk:
- openjdk25 - openjdk25
install: install:
- ./gradlew --no-daemon build publishToMavenLocal -PuseLocalVolmLib=false -PuseMavenLocal=false - ./gradlew --no-daemon build publishToMavenLocal -PuseLocalVolmLib=false
+2 -6
View File
@@ -9,10 +9,6 @@ application {
mainClass = 'art.arcane.iris.probe.ClassloadProbe' mainClass = 'art.arcane.iris.probe.ClassloadProbe'
} }
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
.get()
configurations { configurations {
studioProbeApi studioProbeApi
} }
@@ -23,10 +19,10 @@ dependencies {
testImplementation('junit:junit:4.13.2') testImplementation('junit:junit:4.13.2')
testImplementation(libs.gson) testImplementation(libs.gson)
testImplementation(testFixtures(project(':core'))) testImplementation(testFixtures(project(':core')))
testImplementation(volmLibCoordinate) { testImplementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
compileOnly(volmLibCoordinate) { compileOnly('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
transitive = false transitive = false
} }
runtimeOnly(libs.paralithic) runtimeOnly(libs.paralithic)
-59
View File
@@ -1,59 +0,0 @@
@echo off
REM Publishes VolmLib to the local Maven repository under the coordinate this project
REM resolves by default: com.github.VolmitSoftware:VolmLib:master-SNAPSHOT.
REM
REM VolmLib is normally picked up as a composite build straight from source, so this is
REM only needed when you build with -PuseLocalVolmLib=false, or when another tool has to
REM resolve VolmLib from the local Maven repository rather than the included build.
REM
REM The lookup mirrors settings.gradle: it walks up from this script looking for a
REM VolmLib checkout sitting beside the project root. Set VOLMLIB_DIR to override.
REM Any extra arguments are forwarded to gradle.
setlocal
set "SCRIPT_DIR=%~dp0"
if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
set "VOLMLIB_DIRECTORY="
if defined VOLMLIB_DIR call :check "%VOLMLIB_DIR%"
if not defined VOLMLIB_DIRECTORY call :search "%SCRIPT_DIR%"
if not defined VOLMLIB_DIRECTORY (
echo Could not find a VolmLib checkout. 1>&2
echo Expected a VolmLib directory beside this project root, or VOLMLIB_DIR pointing at one. 1>&2
exit /b 1
)
echo ==^> Publishing VolmLib from %VOLMLIB_DIRECTORY%
pushd "%VOLMLIB_DIRECTORY%"
if errorlevel 1 exit /b 1
call gradlew.bat publishToMavenLocal -Pgroup=com.github.VolmitSoftware -Pversion=master-SNAPSHOT -PvolmLibArtifactId=VolmLib %*
set "PUBLISH_RESULT=%ERRORLEVEL%"
popd
exit /b %PUBLISH_RESULT%
:check
if exist "%~1\settings.gradle" set "VOLMLIB_DIRECTORY=%~f1"
if exist "%~1\settings.gradle.kts" set "VOLMLIB_DIRECTORY=%~f1"
goto :eof
:search
set "CURRENT=%~f1"
:search_loop
if exist "%CURRENT%\VolmLib\settings.gradle" (
set "VOLMLIB_DIRECTORY=%CURRENT%\VolmLib"
goto :eof
)
if exist "%CURRENT%\VolmLib\settings.gradle.kts" (
set "VOLMLIB_DIRECTORY=%CURRENT%\VolmLib"
goto :eof
)
for %%I in ("%CURRENT%\..") do set "PARENT=%%~fI"
if /i "%PARENT%"=="%CURRENT%" goto :eof
set "CURRENT=%PARENT%"
goto :search_loop
-57
View File
@@ -1,57 +0,0 @@
#!/usr/bin/env bash
#
# Publishes VolmLib to the local Maven repository under the coordinate this project
# resolves by default: com.github.VolmitSoftware:VolmLib:master-SNAPSHOT.
#
# VolmLib is normally picked up as a composite build straight from source, so this is
# only needed when you build with -PuseLocalVolmLib=false, or when another tool has to
# resolve VolmLib from ~/.m2 rather than from the included build.
#
# The lookup mirrors settings.gradle: it walks up from this script looking for a
# VolmLib checkout sitting beside the project root. Set VOLMLIB_DIR to override.
# Any extra arguments are forwarded to gradle.
set -o pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
has_volmlib_settings() {
[[ -f "$1/settings.gradle" || -f "$1/settings.gradle.kts" ]]
}
resolve_volmlib_directory() {
if [[ -n "$VOLMLIB_DIR" ]] && has_volmlib_settings "$VOLMLIB_DIR"; then
printf '%s' "$VOLMLIB_DIR"
return 0
fi
local current="$SCRIPT_DIR"
while [[ -n "$current" ]]; do
if has_volmlib_settings "$current/VolmLib"; then
printf '%s' "$current/VolmLib"
return 0
fi
local parent
parent="$(dirname -- "$current")"
[[ "$parent" == "$current" ]] && break
current="$parent"
done
return 1
}
if ! VOLMLIB_DIRECTORY="$(resolve_volmlib_directory)"; then
printf 'Could not find a VolmLib checkout.\n' >&2
printf 'Expected a VolmLib directory beside this project root, or VOLMLIB_DIR pointing at one.\n' >&2
exit 1
fi
printf '==> Publishing VolmLib from %s\n' "$VOLMLIB_DIRECTORY"
cd "$VOLMLIB_DIRECTORY" || exit 1
./gradlew publishToMavenLocal \
-Pgroup=com.github.VolmitSoftware \
-Pversion=master-SNAPSHOT \
-PvolmLibArtifactId=VolmLib \
"$@"
+1 -1
View File
@@ -12,7 +12,7 @@ java {
} }
dependencies { dependencies {
api("com.github.VolmitSoftware.VolmLib:native-api:${providers.gradleProperty('volmLibCoordinate').get().tokenize(':').last()}") { api('com.github.VolmitSoftware.VolmLib:native-api:master-SNAPSHOT') {
transitive = false transitive = false
} }
testImplementation('junit:junit:4.13.2') testImplementation('junit:junit:4.13.2')