mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-12 03:24:14 +00:00
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:
@@ -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
|
||||
`../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.
|
||||
|
||||
## Adapters / modded development
|
||||
|
||||
@@ -2,15 +2,11 @@ String apiVersion = providers.gradleProperty('apiVersion').get()
|
||||
def mainClass = 'art.arcane.iris.Iris'
|
||||
def bootstrapperClass = 'art.arcane.iris.IrisBootstrap'
|
||||
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
|
||||
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
|
||||
.get()
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(':core'))
|
||||
compileOnly(libs.lombok)
|
||||
annotationProcessor(libs.lombok)
|
||||
compileOnly(volmLibCoordinate) {
|
||||
compileOnly('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
compileOnly(libs.paper.api)
|
||||
@@ -23,7 +19,7 @@ dependencies {
|
||||
testImplementation(libs.bstats)
|
||||
testImplementation(project(':core'))
|
||||
testImplementation(testFixtures(project(':core')))
|
||||
testImplementation(volmLibCoordinate) {
|
||||
testImplementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
compileOnly(libs.placeholderApi)
|
||||
|
||||
@@ -32,11 +32,7 @@ buildscript {
|
||||
maven { url = uri('https://jitpack.io') }
|
||||
}
|
||||
dependencies {
|
||||
Properties libraryProperties = new Properties()
|
||||
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()}")
|
||||
classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +52,13 @@ interface IrisFileOperations {
|
||||
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
|
||||
|
||||
apply from: file('../../gradle/modded-generation-build-revision.gradle')
|
||||
apply from: file('../../gradle/volmlib-stamp.gradle')
|
||||
|
||||
Properties rootProperties = new Properties()
|
||||
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
|
||||
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 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 ->
|
||||
return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
|
||||
}
|
||||
@@ -180,10 +176,10 @@ dependencies {
|
||||
compileOnly(libs.spigot) {
|
||||
transitive = false
|
||||
}
|
||||
add('bundle', volmLibCoordinate) {
|
||||
add('bundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('devBundle', volmLibCoordinate) {
|
||||
add('devBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('bundle', libs.zip) {
|
||||
@@ -286,6 +282,9 @@ tasks.named('shadowJar', ShadowJar).configure {
|
||||
spec.delete(staleLoaderJars, legacyLoaderJar)
|
||||
}
|
||||
}
|
||||
from(tasks.named('generateVolmLibStamp')) {
|
||||
into('META-INF/volmit')
|
||||
}
|
||||
archiveFileName.set(irisArtifactName('Fabric', "${minecraftVersion}+${fabricLoaderVersion}"))
|
||||
configurations = [project.configurations.named('bundle').get()]
|
||||
mergeServiceFiles()
|
||||
|
||||
@@ -32,11 +32,7 @@ buildscript {
|
||||
maven { url = uri('https://jitpack.io') }
|
||||
}
|
||||
dependencies {
|
||||
Properties libraryProperties = new Properties()
|
||||
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()}")
|
||||
classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +52,13 @@ interface IrisFileOperations {
|
||||
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
|
||||
|
||||
apply from: file('../../gradle/modded-generation-build-revision.gradle')
|
||||
apply from: file('../../gradle/volmlib-stamp.gradle')
|
||||
|
||||
Properties rootProperties = new Properties()
|
||||
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
|
||||
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 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 ->
|
||||
String coordinatePrefix = "${minecraftVersion}-"
|
||||
if (loaderVersion.startsWith(coordinatePrefix)) {
|
||||
@@ -173,13 +169,13 @@ dependencies {
|
||||
compileOnly(libs.spigot) {
|
||||
transitive = false
|
||||
}
|
||||
add('bundle', volmLibCoordinate) {
|
||||
add('bundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('devBundle', volmLibCoordinate) {
|
||||
add('devBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('runBundle', volmLibCoordinate) {
|
||||
add('runBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('bundle', libs.zip) {
|
||||
@@ -271,6 +267,9 @@ tasks.named('shadowJar', ShadowJar).configure {
|
||||
spec.delete(staleLoaderJars, legacyLoaderJar)
|
||||
}
|
||||
}
|
||||
from(tasks.named('generateVolmLibStamp')) {
|
||||
into('META-INF/volmit')
|
||||
}
|
||||
manifest {
|
||||
// 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;
|
||||
|
||||
@@ -32,11 +32,7 @@ buildscript {
|
||||
maven { url = uri('https://jitpack.io') }
|
||||
}
|
||||
dependencies {
|
||||
Properties libraryProperties = new Properties()
|
||||
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()}")
|
||||
classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +52,13 @@ interface IrisFileOperations {
|
||||
IrisFileOperations irisFileOperations = objects.newInstance(IrisFileOperations)
|
||||
|
||||
apply from: file('../../gradle/modded-generation-build-revision.gradle')
|
||||
apply from: file('../../gradle/volmlib-stamp.gradle')
|
||||
|
||||
Properties rootProperties = new Properties()
|
||||
file('../../gradle.properties').withInputStream { InputStream stream -> rootProperties.load(stream) }
|
||||
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 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 ->
|
||||
return "Iris v${project.version} [${platform}] ${targetVersion}.jar"
|
||||
}
|
||||
@@ -152,10 +148,10 @@ dependencies {
|
||||
compileOnly(libs.spigot) {
|
||||
transitive = false
|
||||
}
|
||||
add('bundle', volmLibCoordinate) {
|
||||
add('bundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('devBundle', volmLibCoordinate) {
|
||||
add('devBundle', 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
add('bundle', libs.zip) {
|
||||
@@ -274,6 +270,9 @@ tasks.named('shadowJar', ShadowJar).configure {
|
||||
spec.delete(staleLoaderJars, legacyLoaderJar)
|
||||
}
|
||||
}
|
||||
from(tasks.named('generateVolmLibStamp')) {
|
||||
into('META-INF/volmit')
|
||||
}
|
||||
archiveFileName.set(irisArtifactName('NeoForge', "${minecraftVersion}+${neoForgeVersion}"))
|
||||
configurations = [project.configurations.named('bundle').get()]
|
||||
from(sourceSets.main.output)
|
||||
|
||||
+45
-104
@@ -43,8 +43,7 @@ buildscript {
|
||||
maven { url = uri('https://jitpack.io') }
|
||||
}
|
||||
dependencies {
|
||||
String volmLibRevision = providers.gradleProperty('volmLibCoordinate').get().tokenize(':').last()
|
||||
classpath("com.github.VolmitSoftware.VolmLib:packaging:${volmLibRevision}")
|
||||
classpath('com.github.VolmitSoftware.VolmLib:packaging:master-SNAPSHOT')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +54,7 @@ plugins {
|
||||
|
||||
apply plugin: 'art.arcane.volmit-packaging'
|
||||
apply from: file('gradle/runtime-relocations.gradle')
|
||||
apply from: file('gradle/volmlib-stamp.gradle')
|
||||
|
||||
interface IrisFileOperations {
|
||||
@Inject
|
||||
@@ -76,15 +76,9 @@ String bukkitMinecraftRange = providers.gradleProperty('bukkitMinecraftRange').g
|
||||
String fabricLoaderVersion = providers.gradleProperty('fabricLoaderVersion').getOrElse('0.19.5')
|
||||
String forgeVersion = providers.gradleProperty('forgeVersion').getOrElse('26.3-66.0.8')
|
||||
String neoForgeVersion = providers.gradleProperty('neoForgeVersion').getOrElse('26.3.0.33-beta')
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
|
||||
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
|
||||
.get()
|
||||
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()
|
||||
String volmLibShared = 'com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT'
|
||||
File localVolmLibCheckout = (File) gradle.extensions.extraProperties.get('volmLibDirectory')
|
||||
Map<String, String> volmLibStamp = (Map<String, String>) gradle.extensions.extraProperties.get('volmLibStamp')
|
||||
Closure<String> loaderDisplayVersion = { String loaderVersion ->
|
||||
String coordinatePrefix = "${minecraftVersion}-"
|
||||
if (loaderVersion.startsWith(coordinatePrefix)) {
|
||||
@@ -153,11 +147,11 @@ nmsBindings.each { String key ->
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.VolmitSoftware.VolmLib:native-${key}:${volmLibCoordinate.tokenize(':').last()}") {
|
||||
implementation("com.github.VolmitSoftware.VolmLib:native-${key}:master-SNAPSHOT") {
|
||||
transitive = false
|
||||
}
|
||||
compileOnly(project(':core'))
|
||||
compileOnly(volmLibCoordinate) {
|
||||
compileOnly(volmLibShared) {
|
||||
transitive = false
|
||||
}
|
||||
compileOnly(rootProject.libs.annotations)
|
||||
@@ -169,10 +163,10 @@ nmsBindings.each { String key ->
|
||||
}
|
||||
testImplementation(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
|
||||
}
|
||||
testCompileOnly(volmLibCoordinate) {
|
||||
testCompileOnly(volmLibShared) {
|
||||
transitive = false
|
||||
}
|
||||
testRuntimeOnly(project(':core'))
|
||||
@@ -183,49 +177,32 @@ nmsBindings.each { String key ->
|
||||
|
||||
def included = configurations.create('included')
|
||||
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 nativeRuntimeRules = layout.buildDirectory.file('generated/native-runtime-keep.pro')
|
||||
List<String> nativeRuntimeModules = ['native-common'] + nmsBindings.collect { String adapter -> 'native-' + adapter }
|
||||
dependencies {
|
||||
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
|
||||
}
|
||||
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') {
|
||||
inputs.files(publishedNativeRuntime)
|
||||
inputs.property('version', volmLibCoordinate.tokenize(':').last())
|
||||
inputs.property('adapters', nmsBindings)
|
||||
inputs.files(nativeRuntime)
|
||||
inputs.property('modules', nativeRuntimeModules)
|
||||
outputs.dir(nativeRuntimeOutput)
|
||||
outputs.file(nativeRuntimeRules)
|
||||
doLast {
|
||||
Map<ComponentIdentifier, File> resolved = new LinkedHashMap<>()
|
||||
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(),
|
||||
NativeRuntimeArtifacts.generate(embeddedNatives(), nativeRuntimeModules,
|
||||
nativeRuntimeOutput.get().asFile, nativeRuntimeRules.get().asFile)
|
||||
}
|
||||
}
|
||||
@@ -240,6 +217,9 @@ tasks.named('jar', Jar).configure {
|
||||
inputs.files(included)
|
||||
dependsOn(generateNativeRuntime)
|
||||
from(nativeRuntimeOutput)
|
||||
from(tasks.named('generateVolmLibStamp')) {
|
||||
into('META-INF/volmit')
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
includeEmptyDirs = false
|
||||
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,
|
||||
// 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.
|
||||
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 = []
|
||||
[
|
||||
'adapters/modded-common/src',
|
||||
@@ -353,11 +308,11 @@ List<Object> moddedSharedInputs = []
|
||||
'lombok.config',
|
||||
'gradle/libs.versions.toml',
|
||||
'gradle/volmlib-resolution.settings.gradle',
|
||||
'gradle/volmlib-stamp.gradle',
|
||||
'gradle/generation-build-revision.gradle',
|
||||
'gradle/modded-generation-build-revision.gradle',
|
||||
'gradle/native-minecraft-sources.gradle'
|
||||
].each { String path -> moddedSharedInputs.add(layout.projectDirectory.file(path).asFile) }
|
||||
File localVolmLibCheckout = useLocalVolmLib.equalsIgnoreCase('true') ? resolveLocalVolmLibDirectory() : null
|
||||
if (localVolmLibCheckout != null) {
|
||||
moddedSharedInputs.add(fileTree(localVolmLibCheckout) {
|
||||
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
|
||||
).withPropertyName('adapterSources')
|
||||
versions.each { String key, String value -> task.inputs.property(key, value) }
|
||||
task.inputs.property('useLocalVolmLib', useLocalVolmLib)
|
||||
task.inputs.property('volmLibCoordinate', volmLibCoordinate)
|
||||
task.inputs.property('volmLibStamp', volmLibStamp)
|
||||
task.outputs.file(layout.projectDirectory.file("adapters/${adapter}/build/libs/${artifactName}"))
|
||||
return null
|
||||
}
|
||||
@@ -394,8 +348,7 @@ tasks.register('fabricJar', Exec) {
|
||||
"-PirisVersion=${project.version}",
|
||||
"-PminecraftVersion=${minecraftVersion}",
|
||||
"-PfabricLoaderVersion=${fabricLoaderVersion}",
|
||||
"-PuseLocalVolmLib=${useLocalVolmLib}",
|
||||
"-PvolmLibCoordinate=${volmLibCoordinate}"
|
||||
"-PuseLocalVolmLib=${localVolmLibCheckout != null}"
|
||||
]
|
||||
if (localVolmLibCheckout != null) {
|
||||
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
|
||||
@@ -432,8 +385,7 @@ tasks.register('forgeJar', Exec) {
|
||||
"-PirisVersion=${project.version}",
|
||||
"-PminecraftVersion=${minecraftVersion}",
|
||||
"-PforgeVersion=${forgeVersion}",
|
||||
"-PuseLocalVolmLib=${useLocalVolmLib}",
|
||||
"-PvolmLibCoordinate=${volmLibCoordinate}"
|
||||
"-PuseLocalVolmLib=${localVolmLibCheckout != null}"
|
||||
]
|
||||
if (localVolmLibCheckout != null) {
|
||||
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
|
||||
@@ -470,8 +422,7 @@ tasks.register('neoforgeJar', Exec) {
|
||||
"-PirisVersion=${project.version}",
|
||||
"-PminecraftVersion=${minecraftVersion}",
|
||||
"-PneoForgeVersion=${neoForgeVersion}",
|
||||
"-PuseLocalVolmLib=${useLocalVolmLib}",
|
||||
"-PvolmLibCoordinate=${volmLibCoordinate}"
|
||||
"-PuseLocalVolmLib=${localVolmLibCheckout != null}"
|
||||
]
|
||||
if (localVolmLibCheckout != null) {
|
||||
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
|
||||
@@ -528,8 +479,7 @@ tasks.register('moddedTest', Exec) {
|
||||
"-PirisVersion=${project.version}",
|
||||
"-PminecraftVersion=${minecraftVersion}",
|
||||
"-PfabricLoaderVersion=${fabricLoaderVersion}",
|
||||
"-PuseLocalVolmLib=${useLocalVolmLib}",
|
||||
"-PvolmLibCoordinate=${volmLibCoordinate}"
|
||||
"-PuseLocalVolmLib=${localVolmLibCheckout != null}"
|
||||
]
|
||||
if (localVolmLibCheckout != null) {
|
||||
environment('ORG_GRADLE_PROJECT_localVolmLibDirectory', localVolmLibCheckout.absolutePath)
|
||||
@@ -545,8 +495,7 @@ tasks.register('moddedTest', Exec) {
|
||||
inputs.property('irisVersion', project.version.toString())
|
||||
inputs.property('minecraftVersion', minecraftVersion)
|
||||
inputs.property('fabricLoaderVersion', fabricLoaderVersion)
|
||||
inputs.property('useLocalVolmLib', useLocalVolmLib)
|
||||
inputs.property('volmLibCoordinate', volmLibCoordinate)
|
||||
inputs.property('volmLibStamp', volmLibStamp)
|
||||
outputs.dir(layout.projectDirectory.dir('adapters/fabric/build/test-results/test'))
|
||||
mustRunAfter(tasks.named('jar'))
|
||||
mustRunAfter(project(':core').tasks.named('check'))
|
||||
@@ -585,6 +534,7 @@ List<String> commonModdedArtifactEntries = [
|
||||
'native/windows-x86_64/jlibdeflate.dll',
|
||||
'META-INF/iris/generation-kernels/catalog.tsv',
|
||||
'META-INF/iris/generation-kernels/abi-1.revision',
|
||||
'META-INF/volmit/volmlib.properties',
|
||||
'META-INF/services/art.arcane.iris.localization.IrisMessageContributor',
|
||||
'art/arcane/iris/generation/runtime/IrisEngine.class',
|
||||
'art/arcane/iris/pack/datapack/DataVersion.class',
|
||||
@@ -700,6 +650,7 @@ List<String> requiredBukkitArtifactEntries = [
|
||||
'slimjar.dat',
|
||||
'slimjar-resolutions.dat',
|
||||
'META-INF/iris/native-runtime.properties',
|
||||
'META-INF/volmit/volmlib.properties',
|
||||
'iris-language-source.properties',
|
||||
'agent.jar',
|
||||
'art/arcane/iris/Iris.class',
|
||||
@@ -725,6 +676,7 @@ tasks.register('verifyBukkitArtifact') {
|
||||
dependsOn('jar')
|
||||
File artifact = bukkitArtifact
|
||||
inputs.file(artifact)
|
||||
inputs.files(nativeRuntime)
|
||||
inputs.files(commandHandlerSources)
|
||||
inputs.files(mantleComponentSources)
|
||||
doLast {
|
||||
@@ -733,7 +685,7 @@ tasks.register('verifyBukkitArtifact') {
|
||||
requiredBukkitArtifactEntries,
|
||||
16,
|
||||
runtimeDownloadedPrefixes)
|
||||
NativeRuntimeArtifacts.verify(artifact, nmsBindings, volmLibCoordinate.tokenize(':').last())
|
||||
NativeRuntimeArtifacts.verify(artifact, nativeRuntimeModules, embeddedNatives())
|
||||
logger.lifecycle("Verified ${artifact.name} packaging and class reference graph")
|
||||
}
|
||||
}
|
||||
@@ -819,11 +771,6 @@ tasks.register('irisDev', Copy) {
|
||||
dependsOn(':core:javadocJar')
|
||||
}
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy.cacheChangingModulesFor(0, 'seconds')
|
||||
resolutionStrategy.cacheDynamicVersionsFor(0, 'seconds')
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'java'
|
||||
|
||||
@@ -834,9 +781,6 @@ allprojects {
|
||||
}
|
||||
|
||||
repositories {
|
||||
if (useMavenLocal) {
|
||||
mavenLocal()
|
||||
}
|
||||
mavenCentral()
|
||||
maven { url = uri('https://repo.papermc.io/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
|
||||
}
|
||||
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',
|
||||
'NativeBlockFaces', 'NativeStateRotator', 'NativeStateMerger',
|
||||
'NativeRegistryAccess', 'ModdedItem', 'ModdedEntityType', 'NativeTileReader', 'NativeTileData']
|
||||
@@ -1016,10 +960,10 @@ project(':adapters:bukkit:nms:v26_3_R1') {
|
||||
dependencies {
|
||||
offlineImplementation(project(':probe'))
|
||||
offlineImplementation(project(':core'))
|
||||
offlineImplementation("com.github.VolmitSoftware.VolmLib:native-common:${volmLibCoordinate.tokenize(':').last()}") {
|
||||
offlineImplementation('com.github.VolmitSoftware.VolmLib:native-common:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
offlineImplementation(volmLibCoordinate) {
|
||||
offlineImplementation(volmLibShared) {
|
||||
transitive = false
|
||||
}
|
||||
}
|
||||
@@ -1132,14 +1076,11 @@ commands:
|
||||
}
|
||||
|
||||
tasks.withType(PackedJar).configureEach {
|
||||
nativeManifestPath.set('META-INF/iris/native-runtime.properties')
|
||||
nativeResourceDirectory.set('META-INF/iris/native/')
|
||||
dependsOn(tasks.named('verifyBukkitArtifact'), configurations.nativeRuntime)
|
||||
nativeArtifacts.set(providers.provider {
|
||||
Map<ComponentIdentifier, File> resolved = new LinkedHashMap<>()
|
||||
configurations.nativeRuntime.incoming.artifacts.artifacts.each { artifact ->
|
||||
resolved.put(artifact.id.componentIdentifier, artifact.file)
|
||||
nativeManifestPath.set(NativeRuntimeArtifacts.MANIFEST)
|
||||
nativeResourceDirectory.set(NativeRuntimeArtifacts.RESOURCES)
|
||||
dependsOn(tasks.named('verifyBukkitArtifact'), nativeRuntime)
|
||||
nativeArtifacts.set(providers.provider { embeddedNatives() })
|
||||
doLast { PackedJar task ->
|
||||
NativeRuntimeArtifacts.verifyPacked(task.outputJar.get().asFile, nativeRuntimeModules, embeddedNatives())
|
||||
}
|
||||
PackedJar.resolveNativeArtifacts(resolved)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ dependencies {
|
||||
implementation(gradleApi())
|
||||
implementation('org.ow2.asm:asm:9.10.1')
|
||||
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')
|
||||
testImplementation('junit:junit:4.13.2')
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.artifacts.component.ComponentIdentifier;
|
||||
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
|
||||
import org.tukaani.xz.XZInputStream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -11,6 +11,7 @@ import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
@@ -21,46 +22,32 @@ import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public final class NativeRuntimeArtifacts {
|
||||
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 NATIVE = "art/arcane/volmlib/nativelib/";
|
||||
|
||||
private NativeRuntimeArtifacts() {
|
||||
}
|
||||
|
||||
public static Map<String, File> publishedArtifacts(Map<ComponentIdentifier, File> resolved,
|
||||
List<String> modules, String version) {
|
||||
Map<String, File> artifacts = new TreeMap<>();
|
||||
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 {
|
||||
public static void generate(Map<String, File> natives, List<String> modules, File output, File rules) throws IOException {
|
||||
requireModules(natives, modules);
|
||||
Map<String, File> providers = new TreeMap<>(natives);
|
||||
List<String> manifest = new ArrayList<>();
|
||||
manifest.add("modules=" + String.join(",", artifacts.keySet()));
|
||||
manifest.add("repository=https://jitpack.io/");
|
||||
manifest.add("modules=" + String.join(",", providers.keySet()));
|
||||
manifest.add("storage=embedded");
|
||||
Set<String> retained = new TreeSet<>();
|
||||
for (Map.Entry<String, File> artifact : artifacts.entrySet()) {
|
||||
String module = artifact.getKey();
|
||||
manifest.add(module + ".coordinate=" + GROUP + ":" + module + ":" + version);
|
||||
manifest.add(module + ".sha256=" + digest(artifact.getValue()));
|
||||
try (JarFile jar = new JarFile(artifact.getValue())) {
|
||||
for (Map.Entry<String, File> provider : providers.entrySet()) {
|
||||
String module = provider.getKey();
|
||||
String digest = digest(Files.readAllBytes(provider.getValue().toPath()));
|
||||
manifest.add(module + ".coordinate=" + GROUP + ":" + module + ":embedded-" + digest);
|
||||
manifest.add(module + ".sha256=" + digest);
|
||||
try (JarFile jar = new JarFile(provider.getValue())) {
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
@@ -92,31 +79,15 @@ public final class NativeRuntimeArtifacts {
|
||||
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)) {
|
||||
JarEntry entry = jar.getJarEntry(MANIFEST);
|
||||
if (entry == null) {
|
||||
throw new GradleException("Missing native runtime dependency manifest");
|
||||
}
|
||||
Properties manifest = new Properties();
|
||||
try (InputStream input = jar.getInputStream(entry)) {
|
||||
manifest.load(input);
|
||||
}
|
||||
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);
|
||||
}
|
||||
verifyManifest(input.readAllBytes(), natives);
|
||||
}
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
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) {
|
||||
if (!name.startsWith(NATIVE)) {
|
||||
return false;
|
||||
@@ -137,9 +184,9 @@ public final class NativeRuntimeArtifacts {
|
||||
|| relative.matches("v[0-9_]+R[0-9]+/.*");
|
||||
}
|
||||
|
||||
private static String digest(File file) throws IOException {
|
||||
private static String digest(byte[] bytes) {
|
||||
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) {
|
||||
throw new IllegalStateException(exception);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.artifacts.ModuleIdentifier;
|
||||
import org.gradle.api.artifacts.component.ComponentIdentifier;
|
||||
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
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.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -15,122 +18,149 @@ import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class NativeRuntimeArtifactsTest {
|
||||
@Test
|
||||
public void acceptsOnlyRequestedPublishedCoordinates() {
|
||||
File common = new File("common.jar");
|
||||
File provider = new File("provider.jar");
|
||||
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"));
|
||||
}
|
||||
private static final List<String> MODULES = List.of("native-common", "native-v26_2_R1");
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporary = new TemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void rejectsCompositeProjectArtifacts() {
|
||||
ComponentIdentifier project = () -> "project :VolmLib:native-common";
|
||||
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.publishedArtifacts(
|
||||
Map.of(project, new File("native-common-local-SNAPSHOT.jar")), List.of("native-common"), "revision"));
|
||||
}
|
||||
|
||||
@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);
|
||||
public void describesTheEmbeddedProvidersAndRetainsTheirSharedReferences() throws Exception {
|
||||
Map<String, File> natives = natives();
|
||||
File output = temporary.newFolder("generated");
|
||||
File rules = new File(output, "keep.pro");
|
||||
NativeRuntimeArtifacts.generate(natives, MODULES, output, rules);
|
||||
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);
|
||||
}
|
||||
String digest = HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256")
|
||||
.digest(Files.readAllBytes(provider.toPath())));
|
||||
assertEquals(digest, manifest.getProperty("native-common.sha256"));
|
||||
assertEquals(digest, manifest.getProperty("native-v26_2_R1.sha256"));
|
||||
assertEquals("native-common,native-v26_2_R1", manifest.getProperty("modules"));
|
||||
assertEquals("embedded", manifest.getProperty("storage"));
|
||||
assertFalse(manifest.containsKey("repository"));
|
||||
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 { *; }"));
|
||||
File plugin = directory.resolve("plugin.jar").toFile();
|
||||
try (JarOutputStream jar = new JarOutputStream(Files.newOutputStream(plugin.toPath()))) {
|
||||
jar.putNextEntry(new JarEntry(NativeRuntimeArtifacts.MANIFEST));
|
||||
Files.copy(directory.resolve(NativeRuntimeArtifacts.MANIFEST), jar);
|
||||
assertEquals(List.of("art/arcane/volmlib/util/collection/KList"),
|
||||
Files.readAllLines(output.toPath().resolve("META-INF/volmit/runtime-roots.list")));
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
NativeRuntimeArtifacts.verify(plugin, List.of("v26_2_R1"), "revision");
|
||||
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin, List.of("v26_3_R1"), "revision"));
|
||||
assertThrows(GradleException.class, () -> NativeRuntimeArtifacts.verify(plugin, List.of("v26_2_R1"), "other"));
|
||||
}
|
||||
return file.toFile();
|
||||
}
|
||||
|
||||
private static ModuleComponentIdentifier module(String module, String version) {
|
||||
return new PublishedModule("com.github.VolmitSoftware.VolmLib", module, version);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
private static String digest(byte[] bytes) throws Exception {
|
||||
return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -38,9 +38,6 @@ plugins {
|
||||
apply from: rootProject.file('gradle/runtime-relocations.gradle')
|
||||
|
||||
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()
|
||||
List<File> languageSourceFiles = fileTree('src/main/resources/languages') {
|
||||
@@ -93,10 +90,10 @@ tasks.named('processResources').configure {
|
||||
*/
|
||||
dependencies {
|
||||
api(project(':spi'))
|
||||
api("com.github.VolmitSoftware.VolmLib:native-api:${volmLibCoordinate.tokenize(':').last()}") {
|
||||
api('com.github.VolmitSoftware.VolmLib:native-api:master-SNAPSHOT') {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -129,7 +126,7 @@ dependencies {
|
||||
|
||||
// Shaded
|
||||
implementation('de.crazydev22.slimjar.helper:spigot:2.1.9')
|
||||
implementation(volmLibCoordinate) {
|
||||
implementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
implementation('com.moandjiezana.toml:toml4j:0.7.2') {
|
||||
|
||||
@@ -28,4 +28,3 @@ apiVersion=26.1
|
||||
fabricLoaderVersion=0.19.5
|
||||
forgeVersion=26.3-66.0.8
|
||||
neoForgeVersion=26.3.0.33-beta
|
||||
volmLibCoordinate=com.github.VolmitSoftware.VolmLib:volmlib-shared:d24d28acddbf3555c0c30ac99569ebacd476ce27
|
||||
|
||||
@@ -13,13 +13,12 @@ Configuration kernelDependencies = configurations.create('generationKernelDepend
|
||||
extendsFrom(configurations.implementation, configurations.slim, configurations.annotationProcessor)
|
||||
}
|
||||
dependencies.add(kernelDependencies.name, libs.guava)
|
||||
String nativeLibraryVersion = providers.gradleProperty('volmLibCoordinate').get().tokenize(':').last()
|
||||
List<String> nativeRevisionModules = ['native-common', 'native-minecraft26_2-sources']
|
||||
for (String adapter : rootProject.extensions.extraProperties.get('nativeDevelopmentAdapters')) {
|
||||
nativeRevisionModules.add('native-' + adapter)
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,12 @@ Configuration nativeMinecraftSources = configurations.create('nativeMinecraftSou
|
||||
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 nativeSourceImplementation = 'minecraft26_2'
|
||||
String nativeSourceMinecraftVersion = providers.gradleProperty('minecraftVersion').getOrElse('26.3')
|
||||
extensions.extraProperties.set('nativeSourceImplementation', nativeSourceImplementation)
|
||||
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) {
|
||||
dependsOn(nativeMinecraftSources)
|
||||
|
||||
@@ -40,10 +40,17 @@
|
||||
* otherwise walk up from settingsDir looking for a `VolmLib` directory
|
||||
* that contains a settings script.
|
||||
*
|
||||
* When nothing is found the build falls back to the published `volmLibCoordinate` from
|
||||
* gradle.properties.
|
||||
* When nothing is found, or substitution is disabled, every VolmLib coordinate resolves the published
|
||||
* 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
|
||||
|
||||
boolean irisHasVolmLibSettings(File directory) {
|
||||
@@ -85,9 +92,47 @@ boolean irisUseLocalVolmLib = providers.gradleProperty('useLocalVolmLib')
|
||||
.orElse('true')
|
||||
.map { String value -> value.equalsIgnoreCase('true') }
|
||||
.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) {
|
||||
dependencySubstitution {
|
||||
substitute(module('com.github.VolmitSoftware:VolmLib')).using(project(':shared'))
|
||||
|
||||
@@ -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
@@ -1,4 +1,4 @@
|
||||
jdk:
|
||||
- openjdk25
|
||||
install:
|
||||
- ./gradlew --no-daemon build publishToMavenLocal -PuseLocalVolmLib=false -PuseMavenLocal=false
|
||||
- ./gradlew --no-daemon build publishToMavenLocal -PuseLocalVolmLib=false
|
||||
|
||||
+2
-6
@@ -9,10 +9,6 @@ application {
|
||||
mainClass = 'art.arcane.iris.probe.ClassloadProbe'
|
||||
}
|
||||
|
||||
String volmLibCoordinate = providers.gradleProperty('volmLibCoordinate')
|
||||
.orElse('com.github.VolmitSoftware:VolmLib:master-SNAPSHOT')
|
||||
.get()
|
||||
|
||||
configurations {
|
||||
studioProbeApi
|
||||
}
|
||||
@@ -23,10 +19,10 @@ dependencies {
|
||||
testImplementation('junit:junit:4.13.2')
|
||||
testImplementation(libs.gson)
|
||||
testImplementation(testFixtures(project(':core')))
|
||||
testImplementation(volmLibCoordinate) {
|
||||
testImplementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
compileOnly(volmLibCoordinate) {
|
||||
compileOnly('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
runtimeOnly(libs.paralithic)
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -12,7 +12,7 @@ java {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
testImplementation('junit:junit:4.13.2')
|
||||
|
||||
Reference in New Issue
Block a user