diff --git a/build.gradle b/build.gradle index f5c5e0e..f912386 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,15 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -import java.nio.file.Files -import java.nio.file.Paths +import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer plugins { id 'java' id 'eclipse' id 'maven-publish' - id 'com.gradleup.shadow' version '9.4.1' - id 'net.minecraftforge.gitversion' version '3.1.7' - id 'net.minecraftforge.licenser' version '1.2.0' - id 'net.minecraftforge.gradleutils' version '3.4.4' - id 'net.minecraftforge.changelog' version '3.2.1' + alias libs.plugins.gradleutils + alias libs.plugins.gitversion + alias libs.plugins.changelog + alias libs.plugins.licenser + alias libs.plugins.shadow } gradleutils.displayName = 'Installer' @@ -34,26 +32,37 @@ java { withSourcesJar() } -test { - useJUnitPlatform() +configurations { + multirelease { + extendsFrom implementation + canBeConsumed = true + canBeResolved = false + attributes { + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, 'multi-release')) + } + } } dependencies { implementation(libs.jopt.simple) implementation(libs.gson) - testImplementation(libs.junit.api) - testRuntimeOnly(libs.bundles.junit.runtime) } -Files.list(Paths.get(projectDir.absolutePath)) - .filter(Files::isRegularFile) - .filter(path -> path.getFileName().toString().endsWith('-installer.jar')) - .findFirst() - .ifPresent(path -> { - var firstFile = path.toFile() - logger.lifecycle("Detected test installer: ${firstFile.name}") - dependencies.implementation(files(firstFile)) - }) +// This isn't great, but it alows us to drop a existing jar file into the root folder and do some debugging +def testJars = fileTree(dir: projectDir).matching{ include '*-installer.jar' } +if (testJars.files.size() == 1) { + logger.lifecycle("Detected test installer: ${testJars.singleFile.name}") + def testData = tasks.register('testData', Jar) { + from(zipTree(testJars.singleFile)) { + exclude('**/*.class') + exclude('META-INF/**') + exclude('joptsimple/**') + } + includeEmptyDirs = false + archiveClassifier = 'test-data' + } + dependencies.implementation(files(testData)) +} tasks.named('jar', Jar) { manifest { @@ -69,9 +78,55 @@ tasks.named('jar', Jar) { } } +def multiReleaseJar = tasks.register('multiReleaseJar', Jar) { + manifest { + from(tasks.named('jar').get().manifest) + attributes(['Multi-Release': 'true']) + } + archiveClassifier = 'multi-release' + from(zipTree(tasks.named('jar', Jar).flatMap { it.archiveFile })) +} + +def addRelease = version -> { + var cfg = configurations.register('java' + version) { + transitive = false + } + dependencies.add('java' + version, project(':installer-java' + version)) + + multiReleaseJar.configure { + from(cfg.map{ zipTree(it.singleFile) }) { + into('META-INF/versions/' + version) + exclude('META-INF/**') + includeEmptyDirs = false + } + } +} +addRelease(9) + + tasks.named('shadowJar', ShadowJar) { archiveClassifier = 'fatjar' minimize() + + // Add out multi-release elements + from(multiReleaseJar.map{ zipTree(it.archiveFile) }) { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + } + + // Meta stuff we don't need + exclude('com/google/errorprone/**') + exclude('META-INF/maven/**') + exclude('META-INF/proguard/**') + + // We shouldn't ever need to care about conflicts as this is an executable jar, but just be safe + relocate('joptsimple', 'net.minecraftforge.installer.shadow.joptsimple') + relocate('com.google.gson', 'net.minecraftforge.installer.shadow.gson') + + // Rewrite JOpt's message files, so that help text is displayed nicely. + transform(PropertiesFileTransformer) { + paths = [ 'Messages.properties$' ] + keyTransformer = { key -> 'net.minecraftforge.installer.shadow.' + key } + } } tasks.withType(JavaCompile).configureEach { @@ -79,7 +134,7 @@ tasks.withType(JavaCompile).configureEach { } artifacts { - archives shadowJar + multirelease multiReleaseJar } changelog { @@ -92,6 +147,7 @@ publishing { gradleutils.promote(it) from components.java + artifact multiReleaseJar artifactId = 'installer' diff --git a/installer-java9/build.gradle b/installer-java9/build.gradle new file mode 100644 index 0000000..61d5e9e --- /dev/null +++ b/installer-java9/build.gradle @@ -0,0 +1,29 @@ +plugins { + id 'java' + id 'eclipse' + alias libs.plugins.gradleutils + alias libs.plugins.gitversion + alias libs.plugins.licenser +} + +repositories { + mavenCentral() + maven gradleutils.forgeMaven +} + +license { + header = rootProject.file('LICENSE-header.txt') + newLine = false +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(9) +} + +dependencies { + implementation(rootProject) +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} diff --git a/installer-java9/src/main/java/net/minecraftforge/installer/MRTest.java b/installer-java9/src/main/java/net/minecraftforge/installer/MRTest.java new file mode 100644 index 0000000..059b5bd --- /dev/null +++ b/installer-java9/src/main/java/net/minecraftforge/installer/MRTest.java @@ -0,0 +1,12 @@ +/* + * Copyright (c) Forge Development LLC + * SPDX-License-Identifier: LGPL-2.1-only + */ +package net.minecraftforge.installer; + +public class MRTest { + public static int getVersion() { + MRTest.class.getModule(); + return 9; + } +} diff --git a/installer-test/build.gradle b/installer-test/build.gradle new file mode 100644 index 0000000..02fcd0a --- /dev/null +++ b/installer-test/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'java' + id 'eclipse' + alias libs.plugins.gradleutils + alias libs.plugins.gitversion + alias libs.plugins.licenser +} + +repositories { + mavenCentral() + maven gradleutils.forgeMaven +} + +license { + header = rootProject.file('LICENSE-header.txt') + newLine = false +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(8) + withSourcesJar() +} + +test { + useJUnitPlatform() +} + +dependencies { + testImplementation(rootProject) { + attributes { + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, 'multi-release')) + } + } + testImplementation(libs.junit.api) + testRuntimeOnly(libs.bundles.junit.runtime) +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} diff --git a/proguard.pro b/proguard.pro deleted file mode 100644 index e63fac8..0000000 --- a/proguard.pro +++ /dev/null @@ -1,31 +0,0 @@ --dontoptimize --dontobfuscate -#-dontpreverify --dontwarn javax.annotation.** --dontwarn javax.inject.** --dontwarn com.google.gson.** - - -# Keep - Applications. Keep all application classes, along with their 'main' -# methods. --keepclasseswithmembers public class * { - public static void main(java.lang.String[]); -} - -# Also keep - Enumerations. Keep the special static methods that are required in -# enumeration classes. --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - -# Also keep - Swing UI L&F. Keep all extensions of javax.swing.plaf.ComponentUI, -# along with the special 'createUI' method. --keep class * extends javax.swing.plaf.ComponentUI { - public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent); -} - -# Keep names - Native method names. Keep all native class/method names. --keepclasseswithmembers,allowshrinking class * { - native ; -} diff --git a/settings.gradle b/settings.gradle index d291251..ec754ce 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,6 +15,12 @@ plugins { dependencyResolutionManagement { versionCatalogs { libs { + plugin 'licenser', 'net.minecraftforge.licenser' version '1.2.0' + plugin 'gradleutils', 'net.minecraftforge.gradleutils' version '3.3.21' + plugin 'gitversion', 'net.minecraftforge.gitversion' version '3.1.6' + plugin 'changelog', 'net.minecraftforge.changelog' version '3.1.3' + plugin 'shadow', 'com.gradleup.shadow' version '9.2.2' + library('gson', 'com.google.code.gson:gson:2.13.2') library('jopt-simple', 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3') @@ -28,3 +34,5 @@ dependencyResolutionManagement { } rootProject.name = 'Installer' +include(':installer-test') +include(':installer-java9') diff --git a/src/main/java/net/minecraftforge/installer/DownloadUtils.java b/src/main/java/net/minecraftforge/installer/DownloadUtils.java index bc336c2..3069821 100644 --- a/src/main/java/net/minecraftforge/installer/DownloadUtils.java +++ b/src/main/java/net/minecraftforge/installer/DownloadUtils.java @@ -16,7 +16,6 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; diff --git a/src/main/java/net/minecraftforge/installer/MRTest.java b/src/main/java/net/minecraftforge/installer/MRTest.java new file mode 100644 index 0000000..0496e1c --- /dev/null +++ b/src/main/java/net/minecraftforge/installer/MRTest.java @@ -0,0 +1,11 @@ +/* + * Copyright (c) Forge Development LLC + * SPDX-License-Identifier: LGPL-2.1-only + */ +package net.minecraftforge.installer; + +public class MRTest { + public static int getVersion() { + return 8; + } +} diff --git a/src/main/java/net/minecraftforge/installer/SimpleInstaller.java b/src/main/java/net/minecraftforge/installer/SimpleInstaller.java index 7ad95e7..e37da5a 100644 --- a/src/main/java/net/minecraftforge/installer/SimpleInstaller.java +++ b/src/main/java/net/minecraftforge/installer/SimpleInstaller.java @@ -54,6 +54,7 @@ public static void main(String[] args) throws IOException, URISyntaxException { String javaVersion = System.getProperty("java.version", "missing java version"); String jvmVersion = System.getProperty("java.vm.version", "missing jvm version"); monitor.message(String.format("JVM info: %s - %s - %s", vendor, javaVersion, jvmVersion)); + monitor.message("Multi-Release: " + MRTest.getVersion()); monitor.message("java.net.preferIPv4Stack=" + System.getProperty("java.net.preferIPv4Stack")); monitor.message("Current Time: " + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date())); diff --git a/src/test/java/net/minecraftforge/installer/test/TestTokens.java b/src/test/java/net/minecraftforge/installer/test/TestTokens.java deleted file mode 100644 index 5077bd7..0000000 --- a/src/test/java/net/minecraftforge/installer/test/TestTokens.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) Forge Development LLC - * SPDX-License-Identifier: LGPL-2.1-only - */ -package net.minecraftforge.installer.test; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; - -import org.junit.jupiter.api.Test; - -import net.minecraftforge.installer.json.Util; -import static org.junit.jupiter.api.Assertions.*; - -public class TestTokens { - @Test - public void testTokens() { - Map> tokens = new HashMap<>(); - tokens.put("VERSION", () -> "1.17"); - tokens.put("NAME", () -> "Foo"); - assertEquals(Util.replaceTokens(tokens, "{VERSION}"), "1.17"); - assertEquals(Util.replaceTokens(tokens, "{NAME}"), "Foo"); - assertEquals(Util.replaceTokens(tokens, "{NAME}-{VERSION}"), "Foo-1.17"); - assertEquals(Util.replaceTokens(tokens, "{NAME}/{VERSION}/something"), "Foo/1.17/something"); - assertEquals(Util.replaceTokens(tokens, "{VERSION}}"), "1.17}"); - assertThrows(IllegalArgumentException.class, () -> Util.replaceTokens(tokens, "{{VERSION}")); - assertEquals(Util.replaceTokens(tokens, "'{VERSION}'"), "{VERSION}"); - assertEquals(Util.replaceTokens(tokens, "'test'"), "test"); - assertEquals(Util.replaceTokens(tokens, "This is a \\'test\\'"), "This is a 'test'"); - } -}