diff --git a/.gitignore b/.gitignore index c316a770..4354f60f 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ !/settings.gradle !/Jenkinsfile !/checkstyle.xml -!/codenarc.groovy \ No newline at end of file +!/codenarc.groovy +!/bootstrap \ No newline at end of file diff --git a/bootstrap/.gitignore b/bootstrap/.gitignore new file mode 100644 index 00000000..f8dc37c9 --- /dev/null +++ b/bootstrap/.gitignore @@ -0,0 +1,7 @@ +# Ignore everything +/* + +!/src +!/build.gradle +!/.gitignore +!/test-project \ No newline at end of file diff --git a/bootstrap/build.gradle b/bootstrap/build.gradle new file mode 100644 index 00000000..7db4d755 --- /dev/null +++ b/bootstrap/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'java' + id 'groovy' +} + +sourceCompatibility = 8 +targetCompatibility = 8 + +tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + it.options.release = 8 +} + +repositories { + mavenCentral() +} + +dependencies { + implementation gradleApi() + + testImplementation(gradleTestKit()) + testImplementation('org.spockframework:spock-core:2.0-M5-groovy-3.0') { + exclude module: 'groovy-all' + } +} + +test { + maxHeapSize = "4096m" + useJUnitPlatform() +} \ No newline at end of file diff --git a/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java new file mode 100644 index 00000000..c64246ef --- /dev/null +++ b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/BootstrappedPlugin.java @@ -0,0 +1,7 @@ +package net.fabricmc.loom.bootstrap; + +import org.gradle.api.plugins.PluginAware; + +public interface BootstrappedPlugin { + void apply(PluginAware project); +} diff --git a/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java new file mode 100644 index 00000000..54762934 --- /dev/null +++ b/bootstrap/src/main/java/net/fabricmc/loom/bootstrap/LoomGradlePluginBootstrap.java @@ -0,0 +1,72 @@ +package net.fabricmc.loom.bootstrap; + +import java.util.ArrayList; +import java.util.List; + +import org.gradle.api.JavaVersion; +import org.gradle.api.Plugin; +import org.gradle.api.plugins.PluginAware; +import org.gradle.util.GradleVersion; + +/** + * This bootstrap is compiled against a minimal gradle API and java 8, this allows us to show a nice error to users who run on unsupported configurations. + */ +@SuppressWarnings("unused") +public class LoomGradlePluginBootstrap implements Plugin { + private static final int MIN_SUPPORTED_MAJOR_GRADLE_VERSION = 7; + private static final int MIN_SUPPORTED_MAJOR_JAVA_VERSION = 16; + + private static final String PLUGIN_CLASS_NAME = "net.fabricmc.loom.LoomGradlePlugin"; + + @Override + public void apply(PluginAware project) { + List errors = new ArrayList<>(); + + if (!isValidGradleRuntime()) { + errors.add(String.format("You are using an outdated version of Gradle (%s). Gradle %d or higher is required.", GradleVersion.current().getVersion(), MIN_SUPPORTED_MAJOR_GRADLE_VERSION)); + } + + if (!isValidJavaRuntime()) { + errors.add(String.format("You are using an outdated version of Java (%s). Java %d or higher is required.", JavaVersion.current().getMajorVersion(), MIN_SUPPORTED_MAJOR_JAVA_VERSION)); + + if (Boolean.getBoolean("idea.active")) { + // Idea specific error + errors.add("You can change the Java version in the Gradle settings dialog."); + } else { + String javaHome = System.getenv("JAVA_HOME"); + + if (javaHome != null) { + errors.add(String.format("The JAVA_HOME environment variable is currently set to (%s).", javaHome)); + } + } + } + + if (!errors.isEmpty()) { + throw new UnsupportedOperationException(String.join("\n", errors)); + } + + getActivePlugin().apply(project); + } + + private static boolean isValidJavaRuntime() { + // Note use compareTo to ensure compatibility with gradle < 6.0 + return JavaVersion.current().compareTo(JavaVersion.toVersion(MIN_SUPPORTED_MAJOR_JAVA_VERSION)) >= 0; + } + + private static boolean isValidGradleRuntime() { + return getMajorGradleVersion() >= MIN_SUPPORTED_MAJOR_GRADLE_VERSION; + } + + private static int getMajorGradleVersion() { + String version = GradleVersion.current().getVersion(); + return Integer.parseInt(version.substring(0, version.indexOf("."))); + } + + BootstrappedPlugin getActivePlugin() { + try { + return (BootstrappedPlugin) Class.forName(PLUGIN_CLASS_NAME).getConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException("Failed to bootstrap loom", e); + } + } +} diff --git a/bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF b/bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF new file mode 100644 index 00000000..9a1b230b --- /dev/null +++ b/bootstrap/src/main/resources/META-INF/trick-gradle-into-thinking-loom-is-signed.SF @@ -0,0 +1,4 @@ +Trick gradle into thinking that loom is signed to skip over transforming all classes in the jar. +This is required to get the bootstrap to well bootstrap on older gradle versions that dont support java 16. + +See https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/java/org/gradle/internal/classpath/InstrumentingClasspathFileTransformer.java#L129 \ No newline at end of file diff --git a/bootstrap/test-project/build.gradle b/bootstrap/test-project/build.gradle new file mode 100644 index 00000000..2cb6e85a --- /dev/null +++ b/bootstrap/test-project/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'fabric-loom' version '0.8.local' +} + +dependencies { + minecraft "com.mojang:minecraft:1.16.5" + mappings loom.officialMojangMappings() +} \ No newline at end of file diff --git a/bootstrap/test-project/settings.gradle b/bootstrap/test-project/settings.gradle new file mode 100644 index 00000000..37a1b9e0 --- /dev/null +++ b/bootstrap/test-project/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + mavenLocal() + } +} diff --git a/build.gradle b/build.gradle index 9f0edc7f..7e8f8eca 100644 --- a/build.gradle +++ b/build.gradle @@ -57,9 +57,19 @@ repositories { maven { url "https://maven.minecraftforge.net/" } } +configurations { + bootstrap { + transitive false + } + compileClasspath.extendsFrom bootstrap + runtimeClasspath.extendsFrom bootstrap +} + dependencies { implementation gradleApi() + bootstrap project(":bootstrap") + // libraries implementation ('commons-io:commons-io:2.8.0') implementation ('org.zeroturnaround:zt-zip:1.14') @@ -93,7 +103,7 @@ dependencies { implementation "dev.architectury:refmap-remapper:1.0.5" // decompilers - implementation ('net.fabricmc:fabric-fernflower:1.4.0') + implementation ('net.fabricmc:fabric-fernflower:1.4.1') implementation ('org.benf:cfr:0.151') // source code remapping @@ -153,6 +163,8 @@ task mainJar(type: Jar, dependsOn: jar) { manifest { attributes 'Implementation-Version': project.version + ' Build(' + buildNum + ')' } + + from configurations.bootstrap.collect { it.isDirectory() ? it : zipTree(it) } } task sourcesJar(type: Jar, dependsOn: classes) { @@ -191,7 +203,7 @@ gradlePlugin { plugins { fabricLoom { id = 'dev.architectury.loom' - implementationClass = 'net.fabricmc.loom.LoomGradlePlugin' + implementationClass = 'net.fabricmc.loom.bootstrap.LoomGradlePluginBootstrap' } } } @@ -289,6 +301,21 @@ publishing { } } +// Need to tweak this file to pretend we are compatible with j8 so the bootstrap will run. +tasks.withType(GenerateModuleMetadata) { + doLast { + def file = outputFile.get().asFile + + def metadata = new groovy.json.JsonSlurper().parseText(file.text) + + metadata.variants.each { + it.attributes["org.gradle.jvm.version"] = 8 + } + + file.text = groovy.json.JsonOutput.toJson(metadata) + } +} + // A task to output a json file with a list of all the test to run task writeActionsTestMatrix() { doLast { @@ -314,3 +341,7 @@ task writeActionsTestMatrix() { output.text = json } } + +tasks.named('wrapper') { + distributionType = Wrapper.DistributionType.ALL +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e5338d37..d435ce29 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index 960cc9c4..26763f4c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ rootProject.name = "architectury-loom" +include "bootstrap" \ No newline at end of file diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 03201907..4b171024 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -33,9 +33,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.plugins.PluginAware; +import net.fabricmc.loom.bootstrap.BootstrappedPlugin; import net.fabricmc.loom.configuration.CompileConfiguration; import net.fabricmc.loom.configuration.FabricApiExtension; import net.fabricmc.loom.configuration.MavenPublication; @@ -44,12 +45,20 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingsCache; import net.fabricmc.loom.decompilers.DecompilerConfiguration; import net.fabricmc.loom.task.LoomTasks; -public class LoomGradlePlugin implements Plugin { +public class LoomGradlePlugin implements BootstrappedPlugin { public static boolean refreshDeps; public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); @Override + public void apply(PluginAware target) { + target.getPlugins().apply(LoomRepositoryPlugin.class); + + if (target instanceof Project project) { + apply(project); + } + } + public void apply(Project project) { String loomVersion = LoomGradlePlugin.class.getPackage().getImplementationVersion(); Set loggedVersions = new HashSet<>(Arrays.asList(System.getProperty("loom.printed.logged", "").split(","))); diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java new file mode 100644 index 00000000..5ea09a12 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -0,0 +1,200 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom; + +import java.io.File; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.dsl.RepositoryHandler; +import org.gradle.api.artifacts.repositories.IvyArtifactRepository; +import org.gradle.api.initialization.Settings; +import org.gradle.api.invocation.Gradle; +import org.gradle.api.plugins.PluginAware; + +public class LoomRepositoryPlugin implements Plugin { + @Override + public void apply(PluginAware target) { + RepositoryHandler repositories = null; + + if (target instanceof Settings settings) { + repositories = settings.getDependencyResolutionManagement().getRepositories(); + + // leave a marker so projects don't try to override these + settings.getGradle().getPluginManager().apply(LoomRepositoryPlugin.class); + } else if (target instanceof Project project) { + if (project.getGradle().getPlugins().hasPlugin(LoomRepositoryPlugin.class)) { + return; + } + + repositories = project.getRepositories(); + } else if (target instanceof Gradle) { + return; + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + Cache cache = new Cache(target); + + // MavenConfiguration.java + repositories.flatDir(repo -> { + repo.setName("UserLocalCacheFiles"); + repo.dir(cache.getRootBuildCache()); + }); + repositories.maven(repo -> { + repo.setName("UserLocalRemappedMods"); + repo.setUrl(cache.getRemappedModCache()); + }); + repositories.maven(repo -> { + repo.setName("Fabric"); + repo.setUrl("https://maven.fabricmc.net/"); + }); + repositories.maven(repo -> { + repo.setName("Mojang"); + repo.setUrl("https://libraries.minecraft.net/"); + }); + repositories.mavenCentral(); + + // MinecraftMappedProvider.java + repositories.ivy(repo -> { + repo.setUrl(cache.getUserCache()); + repo.patternLayout(layout -> { + layout.artifact("[revision]/[artifact]-[revision](-[classifier])(.[ext])"); + }); + repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + }); + + // MinecraftProcessedProvider.java + repositories.ivy(repo -> { + repo.setUrl(cache.getRootPersistentCache()); + repo.patternLayout(layout -> { + layout.artifact("[revision]/[artifact]-[revision](-[classifier])(.[ext])"); + }); + repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); + }); + } +} + +final class Cache { + private PluginAware target; + + Cache(PluginAware target) { + if (target instanceof Project || target instanceof Settings) { + this.target = target; + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + } + + File getUserCache() { + File gradleUserHomeDir = null; + + if (target instanceof Settings settings) { + gradleUserHomeDir = settings.getGradle().getGradleUserHomeDir(); + } else if (target instanceof Project project) { + gradleUserHomeDir = project.getGradle().getGradleUserHomeDir(); + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + File userCache = new File(gradleUserHomeDir, "caches" + File.separator + "fabric-loom"); + + if (!userCache.exists()) { + userCache.mkdirs(); + } + + return userCache; + } + + public File getRootPersistentCache() { + File rootDir = null; + + if (target instanceof Settings settings) { + rootDir = settings.getRootDir(); + } else if (target instanceof Project project) { + rootDir = project.getRootDir(); + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + File persistentCache = new File(rootDir, ".gradle" + File.separator + "loom-cache"); + + if (!persistentCache.exists()) { + persistentCache.mkdirs(); + } + + return persistentCache; + } + + public File getRootBuildCache() { + File rootDir = null; + + if (target instanceof Settings settings) { + rootDir = settings.getRootDir(); + } else if (target instanceof Project project) { + rootDir = project.getRootDir(); + } else { + throw new IllegalArgumentException("Expected target to be a Project or Settings, but was a " + target.getClass()); + } + + File buildCache = new File(rootDir, "build" + File.separator + "loom-cache"); + + if (!buildCache.exists()) { + buildCache.mkdirs(); + } + + return buildCache; + } + + public File getRemappedModCache() { + File remappedModCache = new File(getRootPersistentCache(), "remapped_mods"); + + if (!remappedModCache.exists()) { + remappedModCache.mkdir(); + } + + return remappedModCache; + } + + public File getNestedModCache() { + File nestedModCache = new File(getRootPersistentCache(), "nested_mods"); + + if (!nestedModCache.exists()) { + nestedModCache.mkdir(); + } + + return nestedModCache; + } + + public File getNativesJarStore() { + File natives = new File(getUserCache(), "natives/jars"); + + if (!natives.exists()) { + natives.mkdirs(); + } + + return natives; + } +} diff --git a/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java b/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java index 8de3103e..60640cb6 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/NestedDependencyProvider.java @@ -32,7 +32,8 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; -import java.util.stream.Collectors; + +import javax.annotation.Nullable; import com.google.gson.JsonObject; import org.apache.commons.io.FileUtils; @@ -42,7 +43,6 @@ import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.DependencySet; import org.gradle.api.artifacts.ProjectDependency; -import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.ResolvedConfiguration; import org.gradle.api.artifacts.ResolvedDependency; import org.gradle.api.tasks.bundling.AbstractArchiveTask; @@ -103,17 +103,17 @@ public final class NestedDependencyProvider implements NestedJarProvider { visited.add(dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion()); - // TODO change this to allow just normal jar tasks, so a project can have a none loom sub project Collection remapJarTasks = dependencyProject.getTasksByName("remapJar", false); Collection jarTasks = dependencyProject.getTasksByName("jar", false); for (Task task : remapJarTasks.isEmpty() ? jarTasks : remapJarTasks) { - if (task instanceof RemapJarTask remapJarTask) { - File file = remapJarTask.getArchiveFile().get().getAsFile(); - fileList.add(new DependencyInfo<>(projectDependency, new ProjectDependencyMetaExtractor(), file)); - } else if (task instanceof AbstractArchiveTask abstractArchiveTask) { - File file = abstractArchiveTask.getArchiveFile().get().getAsFile(); - fileList.add(new DependencyInfo<>(projectDependency, new ProjectDependencyMetaExtractor(), file)); + if (task instanceof AbstractArchiveTask abstractArchiveTask) { + fileList.add(new DependencyInfo<>( + projectDependency, + new ProjectDependencyMetaExtractor(), + abstractArchiveTask.getArchiveFile().get().getAsFile(), + abstractArchiveTask.getArchiveClassifier().getOrNull() + )); } } } @@ -133,14 +133,13 @@ public final class NestedDependencyProvider implements NestedJarProvider { continue; } - List files = dependency - .getModuleArtifacts() - .stream() - .map(ResolvedArtifact::getFile) - .collect(Collectors.toList()); - - for (File file : files) { - fileList.add(new DependencyInfo<>(dependency, new ResolvedDependencyMetaExtractor(), file)); + for (var artifact : dependency.getModuleArtifacts()) { + fileList.add(new DependencyInfo<>( + dependency, + new ResolvedDependencyMetaExtractor(), + artifact.getFile(), + artifact.getClassifier() + )); } } @@ -195,7 +194,12 @@ public final class NestedDependencyProvider implements NestedJarProvider { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("schemaVersion", 1); - jsonObject.addProperty("id", (metaExtractor.group(dependency) + "_" + metaExtractor.name(dependency)).replaceAll("\\.", "_").toLowerCase(Locale.ENGLISH)); + + jsonObject.addProperty("id", + (metaExtractor.group(dependency) + "_" + metaExtractor.name(dependency) + info.getClassifierSuffix()) + .replaceAll("\\.", "_") + .toLowerCase(Locale.ENGLISH) + ); jsonObject.addProperty("version", metaExtractor.version(dependency)); jsonObject.addProperty("name", metaExtractor.name(dependency)); @@ -206,8 +210,8 @@ public final class NestedDependencyProvider implements NestedJarProvider { return LoomGradlePlugin.GSON.toJson(jsonObject); } - private record DependencyInfo(D dependency, DependencyMetaExtractor metaExtractor, File file) { - public void validateInputs() { + private record DependencyInfo(D dependency, DependencyMetaExtractor metaExtractor, File file, @Nullable String classifier) { + void validateInputs() { if (!file.exists()) { throw new RuntimeException("Failed to include nested jars, as it could not be found @ " + file.getAbsolutePath()); } @@ -216,6 +220,14 @@ public final class NestedDependencyProvider implements NestedJarProvider { throw new RuntimeException("Failed to include nested jars, as file was not a jar: " + file.getAbsolutePath()); } } + + String getClassifierSuffix() { + if (classifier == null) { + return ""; + } else { + return "_" + classifier; + } + } } private interface DependencyMetaExtractor { diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 2b6ee858..33ad2a2a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -142,8 +142,6 @@ public final class CompileConfiguration { p.afterEvaluate(project -> { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - MavenConfiguration.setup(project); - LoomDependencyManager dependencyManager = new LoomDependencyManager(); extension.setDependencyManager(dependencyManager); diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index d325457b..e9bb6bae 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -45,6 +45,7 @@ import net.fabricmc.loom.configuration.mods.ModProcessor; import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.SourceRemapper; +import net.fabricmc.loom.LoomRepositoryPlugin; public class LoomDependencyManager { private static class ProviderList { @@ -194,7 +195,9 @@ public class LoomDependencyManager { project.getLogger().debug("Loom adding " + name + " from installer JSON"); - if (jsonElement.getAsJsonObject().has("url")) { + // If user choose to use dependencyResolutionManagement, then they should declare + // these repositories manually in the settings file. + if (jsonElement.getAsJsonObject().has("url") && !project.getGradle().getPlugins().hasPlugin(LoomRepositoryPlugin.class)) { String url = jsonElement.getAsJsonObject().get("url").getAsString(); long count = project.getRepositories().stream().filter(artifactRepository -> artifactRepository instanceof MavenArtifactRepository) .map(artifactRepository -> (MavenArtifactRepository) artifactRepository) diff --git a/src/main/java/net/fabricmc/loom/configuration/MavenConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/MavenConfiguration.java deleted file mode 100644 index dc10e375..00000000 --- a/src/main/java/net/fabricmc/loom/configuration/MavenConfiguration.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2016, 2017, 2018 FabricMC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package net.fabricmc.loom.configuration; - -import org.gradle.api.Project; -import org.gradle.api.artifacts.repositories.MavenArtifactRepository; - -import net.fabricmc.loom.LoomGradleExtension; - -public class MavenConfiguration { - public static void setup(Project project) { - LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - - project.getRepositories().flatDir(repo -> { - repo.setName("UserLocalCacheFiles"); - repo.dir(extension.getRootProjectBuildCache()); - }); - - project.getRepositories().maven(repo -> { - repo.setName("UserLocalRemappedMods"); - repo.setUrl(extension.getRemappedModCache()); - }); - - project.getRepositories().maven(repo -> { - repo.setName("Fabric"); - repo.setUrl("https://maven.fabricmc.net/"); - }); - - project.getRepositories().maven(repo -> { - repo.setName("Mojang"); - repo.setUrl("https://libraries.minecraft.net/"); - }); - - project.getRepositories().maven(repo -> { - repo.setName("Forge"); - repo.setUrl("https://maven.minecraftforge.net/"); - - repo.metadataSources(sources -> { - sources.mavenPom(); - - try { - MavenArtifactRepository.MetadataSources.class.getDeclaredMethod("ignoreGradleMetadataRedirection") - .invoke(sources); - } catch (Throwable ignored) { - // Method not available - } - }); - }); - - project.getRepositories().mavenCentral(); - } -} diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java index 9673a9a4..f547a3b5 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java @@ -37,7 +37,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvid import net.fabricmc.loom.util.Constants; public class MinecraftProcessedProvider extends MinecraftMappedProvider { - public static final String PROJECT_MAPPED_CLASSIFIER = "projectmapped"; + public final String projectMappedClassifier; private File projectMappedJar; @@ -46,6 +46,8 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { public MinecraftProcessedProvider(Project project, JarProcessorManager jarProcessorManager) { super(project); this.jarProcessorManager = jarProcessorManager; + this.projectMappedClassifier = "project-" + project.getPath().replace(':', '@') + + "-mapped"; } @Override @@ -65,14 +67,12 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { jarProcessorManager.process(projectMappedJar); } - getProject().getRepositories().flatDir(repository -> repository.dir(getJarDirectory(getExtension().getProjectPersistentCache(), PROJECT_MAPPED_CLASSIFIER))); - getProject().getDependencies().add(Constants.Configurations.MINECRAFT_NAMED, - getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString(PROJECT_MAPPED_CLASSIFIER))); + getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString(projectMappedClassifier))); } private void invalidateJars() { - File dir = getJarDirectory(getExtension().getUserCache(), PROJECT_MAPPED_CLASSIFIER); + File dir = getJarDirectory(getExtension().getUserCache(), projectMappedClassifier); if (dir.exists()) { getProject().getLogger().warn("Invalidating project jars"); @@ -89,7 +89,7 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { public void initFiles(MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) { super.initFiles(minecraftProvider, mappingsProvider); - projectMappedJar = new File(getJarDirectory(getExtension().getProjectPersistentCache(), PROJECT_MAPPED_CLASSIFIER), "minecraft-" + getJarVersionString(PROJECT_MAPPED_CLASSIFIER) + ".jar"); + projectMappedJar = new File(getJarDirectory(getExtension().getRootProjectPersistentCache(), projectMappedClassifier), "minecraft-" + getJarVersionString(projectMappedClassifier) + ".jar"); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java index 14333000..fbc9ea86 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java @@ -290,8 +290,6 @@ public class MinecraftMappedProvider extends DependencyProvider { } protected void addDependencies(DependencyInfo dependency, Consumer postPopulationScheduler) { - getProject().getRepositories().flatDir(repository -> repository.dir(getJarDirectory(getExtension().getUserCache(), "mapped"))); - getProject().getDependencies().add(Constants.Configurations.MINECRAFT_NAMED, getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString("mapped"))); } diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java index 13df1b66..a93341ad 100644 --- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java +++ b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java @@ -106,7 +106,14 @@ public abstract class AbstractFernFlowerDecompiler implements LoomDecompiler { spec.getMainClass().set(fernFlowerExecutor().getName()); spec.jvmArgs("-Xms200m", "-Xmx3G"); spec.setArgs(args); - spec.setErrorOutput(System.err); + spec.setErrorOutput(new ConsumingOutputStream(line -> { + if (line.startsWith("Inconsistent inner class entries")) { + // Suppress this + return; + } + + System.err.println(line); + })); spec.setStandardOutput(new ConsumingOutputStream(line -> { if (line.startsWith("Listening for transport") || !line.contains("::")) { System.out.println(line); diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy new file mode 100644 index 00000000..3570b220 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/SignedProjectTest.groovy @@ -0,0 +1,96 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.integration + +import net.fabricmc.loom.test.util.ArchiveAssertionsTrait + +import net.fabricmc.loom.test.util.MockMavenServerTrait +import spock.lang.Specification +import spock.lang.Stepwise +import spock.lang.Unroll +import spock.util.environment.RestoreSystemProperties + +import static java.lang.System.setProperty +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +/** + * This tests publishing signed artifacts to a maven server + */ +@Stepwise +class SignedProjectTest extends Specification implements MockMavenServerTrait, ArchiveAssertionsTrait { + @Unroll + @RestoreSystemProperties + def "sign and publish lib #gradle"() { + given: + setProperty('loom.test.secretKey', PRIVATE_KEY) + when: + def result = create("publish", gradle) + then: + result.task(":publish").outcome == SUCCESS + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } + + @Override + String name() { + "signed" + } + + static final String PRIVATE_KEY = """ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQPGBGCm5LMBCADUeHXbe4TmP3qELtz6he7CLaVMFXqL/fU+M7GIrj0qtLU6pJ9v +KSbF3tQATKlU91zkQCIPg41VBlqkx85bOm0u7Nvv4JhWMqE+ZsNoNVXS2xQEyEIW +rX9Cd0/YibU2FpWOlo1l/UZPPD/lYUrkZEhgoKHMHP3SYb5Ohgpy4klTeQdXTRMF +q0IeyFynw3eqrdWmktOEApd7qeu/Hs1NEnZssSZQdAYB4R+tL/ePgIYXsViWvqbT +XDYfmd+AiRnACGtrt5P8tSmKhLPzth36cvqLXI+hSBGHu0PRfvQnfjn3CWq8AaIj +dLsmRYw8NedYZ5DgY3NIRMBkG561Uc1Kj5c7ABEBAAH+BwMCfh5aZV7x7zP/HCCP +WwbuNO9fLKss4J7sNVWdkX/ZsOy5OMLBql70F8PKEovObkYiAWsPUjrQ50VMhCUc +V2443FErPTC9A+5NsJ3Sx+BazbsUd9cprnJIW0tVGP4ij9j14A0VOogJUbzrxonQ +aCQ4OMJi5cxk/o2z/N5WDG92Qb/CxNlp6oxuUgdxXWdhWSpW6XBlBKfMsjK6acpo +gAQg+e8m0FCRrpd+vMoHFPYa0UdY8s2YH88te7YiQYYPf9FI3Uk8FeKRCqgRIwTr +fWd7Ubh2vK0h3ua3gyJm1aqQbIYVk/a2L1KF6tsuh1AYGbyXitx6cujSOukwz3xi +ej4CutY60PoIFihSiBBsRwpvcGr9RoYkJ8tKBqq67xTttYhdlBiedM4/05gdCglw +UXm7O1LVOro6vaI6RzP1hL5Q/OLkx4mxXtaNbsjP1/Urml7bB1aqzeoMXUSlSqB+ +LHavKxonYcEj2cRKRg1v/t2UV0lXyimammJ5c4Hq49bLygYITrT9pL3n9OOmAYBL +/+uv7h640cYWeR8YBQ7jCbdaqP+bJNmIbKlLMZfcS49Bt/WM1kFa6CqvAyNFewuL +CnRbMcdteYGWYvSyvmzKDa7tQ6TILt9ZrJOGPTGrEM2zLIR8H6eDpzXSVwJb/0Nk +apaCzB9GqMDtYpEu+nMg1/EI2oSzj0Ng0pV+rAJr6oLc6Y0iesVKbwg2VgYgzF7U +CG9B15hPofUDKXb43Fig4nWieceDzGveY8vlFeSMBxzxhCRsXKP9oWogtNRJiJ9c +t+VkzBADEb82mnG/QuTBgCxceRBVu4Bg9tPGRSHjBZurtdkKvJqEq5ay/lGZ718b +3Za/hMzR6rakVfKdGs7A2HN68iCkX3cZYn+uaKT8aEUSXoSFZXfJqU3pVi2ql2MN +43RseA0og79mtCFsb29tLXRlc3QgPGxvb20tdGVzdEBleGFtcGxlLmNvbT6JAU4E +EwEKADgWIQSP20iY86Edwz6Qcq0M9Z/0ipBcJgUCYKbkswIbLwULCQgHAgYVCgkI +CwIEFgIDAQIeAQIXgAAKCRAM9Z/0ipBcJruCCADNydlXQRAr799Fr58zf9YGBcH5 +7F3TQpzK2zd6iktFy9cjIu04pYtvdrEP+29hLmy1ibUBI3yx8HH1BxHm8Eu2ZTAn +b5EYkmF73CecdtSu3yL0tmk/4GLO6t2r/SN7imFnq9xKyTqJmtftQngBhgoA6KPk +4ZEkOA1MbVpaSjGy5H1U/XusH1UDA3SZWlOwrY3xO8TfycsR9BijtCqxTnuwNXzT +wWoDPJEzJM/KCs0aXRbwwWALcxqk6sevLwx4D4/k3xxEB8cf5cBJC8bJjnBz5FSi +WBVyzTF8wLkcSacL93kE6swpP+iNkIwkO4eoyTA2RmTJUcz/M0zWS7NEM8S0 +=xl+8 +-----END PGP PRIVATE KEY BLOCK-----""" +} \ No newline at end of file diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy new file mode 100644 index 00000000..a8b27336 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy @@ -0,0 +1,52 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.integration + +import net.fabricmc.loom.test.util.ProjectTestTrait +import spock.lang.Specification +import spock.lang.Unroll + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class DependencyResolutionManagementTest extends Specification implements ProjectTestTrait { + @Override + String name() { + "dependencyResolutionManagement" + } + + @Unroll + def "build (gradle #gradle)"() { + when: + def result = create("build", gradle) + then: + result.task(":basic:build").outcome == SUCCESS + result.task(":projmap:build").outcome == SUCCESS + + where: + gradle | _ + DEFAULT_GRADLE | _ + PRE_RELEASE_GRADLE | _ + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 56ed8c9c..2d0640a2 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -29,7 +29,7 @@ import org.gradle.testkit.runner.GradleRunner trait ProjectTestTrait { final static String DEFAULT_GRADLE = "7.0.1" - final static String PRE_RELEASE_GRADLE = "7.1-20210511220046+0000" + final static String PRE_RELEASE_GRADLE = "7.2-20210527220045+0000" static File gradleHome = File.createTempDir() File testProjectDir = File.createTempDir() diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle b/src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle new file mode 100644 index 00000000..f02447c7 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/build.gradle @@ -0,0 +1,92 @@ +plugins { + id 'fabric-loom' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too + // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used. + // We'll use that if it's available, but otherwise we'll use the older option. + def targetVersion = 8 + if (JavaVersion.current().isJava9Compatible()) { + it.options.release = targetVersion + } +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties b/src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties new file mode 100644 index 00000000..40e9e571 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties + # check these on https://fabricmc.net/use + minecraft_version=1.16.5 + yarn_mappings=1.16.5+build.6 + loader_version=0.11.3 + +# Mod Properties + mod_version = 1.0.0 + maven_group = com.example + archives_base_name = fabric-example-mod + +# Dependencies + # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api + fabric_version=0.32.5+1.16 diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java new file mode 100644 index 00000000..e5ed082e --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/ExampleMod.java @@ -0,0 +1,14 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java new file mode 100644 index 00000000..83ee1a89 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/assets/modid/icon.png b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/assets/modid/icon.png new file mode 100644 index 00000000..047b91f2 Binary files /dev/null and b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/assets/modid/icon.png differ diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..df92d8b1 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/fabric.mod.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.16.x" + }, + "suggests": { + "another-mod": "*" + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json new file mode 100644 index 00000000..21fe73a4 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/basic/src/main/resources/modid.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle b/src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle new file mode 100644 index 00000000..ca8c73f6 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/build.gradle @@ -0,0 +1,96 @@ +plugins { + id 'fabric-loom' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too + // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used. + // We'll use that if it's available, but otherwise we'll use the older option. + def targetVersion = 8 + if (JavaVersion.current().isJava9Compatible()) { + it.options.release = targetVersion + } +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +minecraft { + accessWidener = file("src/main/resources/modid.accesswidener") +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties b/src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties new file mode 100644 index 00000000..40e9e571 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties + # check these on https://fabricmc.net/use + minecraft_version=1.16.5 + yarn_mappings=1.16.5+build.6 + loader_version=0.11.3 + +# Mod Properties + mod_version = 1.0.0 + maven_group = com.example + archives_base_name = fabric-example-mod + +# Dependencies + # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api + fabric_version=0.32.5+1.16 diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java new file mode 100644 index 00000000..e5ed082e --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/ExampleMod.java @@ -0,0 +1,14 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java new file mode 100644 index 00000000..83ee1a89 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java @@ -0,0 +1,15 @@ +package net.fabricmc.example.mixin; + +import net.minecraft.client.gui.screen.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/assets/modid/icon.png b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/assets/modid/icon.png new file mode 100644 index 00000000..047b91f2 Binary files /dev/null and b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/assets/modid/icon.png differ diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..4764df8c --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/fabric.mod.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.16.x" + }, + "suggests": { + "another-mod": "*" + }, + "accessWidener" : "modid.accesswidener" +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener new file mode 100644 index 00000000..9684ec8f --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.accesswidener @@ -0,0 +1,2 @@ +accessWidener v1 named +extendable class net/minecraft/fluid/FluidState diff --git a/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json new file mode 100644 index 00000000..21fe73a4 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/projmap/src/main/resources/modid.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/projects/dependencyResolutionManagement/settings.gradle b/src/test/resources/projects/dependencyResolutionManagement/settings.gradle new file mode 100644 index 00000000..c05e3699 --- /dev/null +++ b/src/test/resources/projects/dependencyResolutionManagement/settings.gradle @@ -0,0 +1,16 @@ +pluginManagement { + plugins { + id 'fabric-loom' + } +} + +plugins { + id 'fabric-loom' +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) +} + +include 'basic' +include 'projmap' \ No newline at end of file diff --git a/src/test/resources/projects/signed/build.gradle b/src/test/resources/projects/signed/build.gradle new file mode 100644 index 00000000..5da48236 --- /dev/null +++ b/src/test/resources/projects/signed/build.gradle @@ -0,0 +1,57 @@ +plugins { + id 'fabric-loom' + id 'maven-publish' + id 'signing' +} + +archivesBaseName = "fabric-example-lib" +version = "1.0.0" +group = "com.example" + +dependencies { + minecraft "com.mojang:minecraft:1.16.5" + mappings "net.fabricmc:yarn:1.16.5+build.5:v2" + modImplementation "net.fabricmc:fabric-loader:0.11.2" +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +java { + withSourcesJar() +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifact(remapJar) { + builtBy remapJar + } + artifact(remapJar) { + builtBy remapJar + classifier "classifier" + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + repositories { + maven { + url "http://localhost:${System.getProperty("loom.test.mavenPort")}/" + allowInsecureProtocol = true + } + } +} + +signing { + def privateKey = System.getProperty("loom.test.secretKey") ?: "no key!" + useInMemoryPgpKeys(privateKey, 'password') + sign publishing.publications.mavenJava +} diff --git a/src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java b/src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java new file mode 100644 index 00000000..e6ec1e65 --- /dev/null +++ b/src/test/resources/projects/signed/main/java/net/fabricmc/example/ExampleLib.java @@ -0,0 +1,13 @@ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleLib implements ModInitializer { + @Override + public void onInitialize() { + } + + public static void hello() { + System.out.println("Hello Fabric world!"); + } +} diff --git a/src/test/resources/projects/signed/main/resources/fabric.mod.json b/src/test/resources/projects/signed/main/resources/fabric.mod.json new file mode 100644 index 00000000..f527100e --- /dev/null +++ b/src/test/resources/projects/signed/main/resources/fabric.mod.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "id": "modid" +} diff --git a/src/test/resources/projects/signed/settings.gradle b/src/test/resources/projects/signed/settings.gradle new file mode 100644 index 00000000..fc4c0f72 --- /dev/null +++ b/src/test/resources/projects/signed/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "fabric-example-lib" +