Merge remote-tracking branch 'FabricMC/dev/0.8' into dev/0.8

# Conflicts:
#	.github/workflows/test-push.yml
#	build.gradle
#	settings.gradle
#	src/test/groovy/net/fabricmc/loom/test/integration/dependencyResolutionManagement.groovy
This commit is contained in:
shedaniel
2021-05-30 19:17:56 +08:00
43 changed files with 1062 additions and 113 deletions

3
.gitignore vendored
View File

@@ -20,4 +20,5 @@
!/settings.gradle
!/Jenkinsfile
!/checkstyle.xml
!/codenarc.groovy
!/codenarc.groovy
!/bootstrap

7
bootstrap/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
# Ignore everything
/*
!/src
!/build.gradle
!/.gitignore
!/test-project

30
bootstrap/build.gradle Normal file
View File

@@ -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()
}

View File

@@ -0,0 +1,7 @@
package net.fabricmc.loom.bootstrap;
import org.gradle.api.plugins.PluginAware;
public interface BootstrappedPlugin {
void apply(PluginAware project);
}

View File

@@ -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<PluginAware> {
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<String> 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);
}
}
}

View File

@@ -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

View File

@@ -0,0 +1,8 @@
plugins {
id 'fabric-loom' version '0.8.local'
}
dependencies {
minecraft "com.mojang:minecraft:1.16.5"
mappings loom.officialMojangMappings()
}

View File

@@ -0,0 +1,10 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
mavenLocal()
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -1 +1,2 @@
rootProject.name = "architectury-loom"
include "bootstrap"

View File

@@ -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<Project> {
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<String> loggedVersions = new HashSet<>(Arrays.asList(System.getProperty("loom.printed.logged", "").split(",")));

View File

@@ -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<PluginAware> {
@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;
}
}

View File

@@ -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<Task> remapJarTasks = dependencyProject.getTasksByName("remapJar", false);
Collection<Task> 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<File> 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>(D dependency, DependencyMetaExtractor<D> metaExtractor, File file) {
public void validateInputs() {
private record DependencyInfo<D>(D dependency, DependencyMetaExtractor<D> 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<D> {

View File

@@ -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);

View File

@@ -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)

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -290,8 +290,6 @@ public class MinecraftMappedProvider extends DependencyProvider {
}
protected void addDependencies(DependencyInfo dependency, Consumer<Runnable> 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")));
}

View File

@@ -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);

View File

@@ -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-----"""
}

View File

@@ -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 | _
}
}

View File

@@ -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()

View File

@@ -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.
}
}

View File

@@ -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

View File

@@ -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!");
}
}

View File

@@ -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!");
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

View File

@@ -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": "*"
}
}

View File

@@ -0,0 +1,14 @@
{
"required": true,
"minVersion": "0.8",
"package": "net.fabricmc.example.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
],
"client": [
"ExampleMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -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.
}
}

View File

@@ -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

View File

@@ -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!");
}
}

View File

@@ -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!");
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

View File

@@ -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"
}

View File

@@ -0,0 +1,2 @@
accessWidener v1 named
extendable class net/minecraft/fluid/FluidState

View File

@@ -0,0 +1,14 @@
{
"required": true,
"minVersion": "0.8",
"package": "net.fabricmc.example.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
],
"client": [
"ExampleMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -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'

View File

@@ -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
}

View File

@@ -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!");
}
}

View File

@@ -0,0 +1,4 @@
{
"schemaVersion": 1,
"id": "modid"
}

View File

@@ -0,0 +1,2 @@
rootProject.name = "fabric-example-lib"