Introduce loom.productionNamespace (#1447)

* new: loom.productionNamespace

* change: move getProductionNamespaceEnum to LoomGradleExtension

* change: use .convention() for productionNamespace default

* change: productionNamespace.finalizeValueOnRead()

* fix: checkstyle
This commit is contained in:
ishland
2025-11-19 02:23:55 +08:00
committed by GitHub
parent 2deeda4c70
commit dedbf8fa8f
30 changed files with 123 additions and 43 deletions

View File

@@ -84,6 +84,8 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
void setIntermediaryMinecraftProvider(IntermediaryMinecraftProvider<?> intermediaryMinecraftProvider);
MappingsNamespace getProductionNamespaceEnum();
default List<Path> getMinecraftJars(MappingsNamespace mappingsNamespace) {
return switch (mappingsNamespace) {
case NAMED -> getNamedMinecraftProvider().getMinecraftJarPaths();

View File

@@ -242,6 +242,11 @@ public interface LoomGradleExtensionAPI {
*/
Property<String> getIntermediaryUrl();
/**
* @return the production namespace
*/
Property<String> getProductionNamespace();
@ApiStatus.Experimental
Property<MinecraftJarConfiguration<?, ?, ?>> getMinecraftJarConfiguration();

View File

@@ -30,4 +30,6 @@ import net.fabricmc.tinyremapper.TinyRemapper;
public interface MappingProcessorContext {
LazyCloseable<TinyRemapper> createRemapper(MappingsNamespace from, MappingsNamespace to);
MappingsNamespace getProductionNamespace();
}

View File

@@ -44,4 +44,6 @@ public interface ProcessorContext {
MemoryMappingTree getMappings();
boolean disableObfuscation();
MappingsNamespace getProductionNamespace();
}

View File

@@ -31,6 +31,7 @@ import java.util.stream.Stream;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPlugin;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.processors.speccontext.ProjectView;
import net.fabricmc.loom.util.fmj.FabricModJson;
@@ -52,6 +53,8 @@ public interface SpecContext {
*/
List<FabricModJson> modDependenciesCompileRuntimeClient();
MappingsNamespace productionNamespace();
default List<FabricModJson> allMods() {
return Stream.concat(modDependencies().stream(), localMods().stream()).toList();
}

View File

@@ -53,6 +53,7 @@ import org.gradle.api.tasks.javadoc.Javadoc;
import org.gradle.api.tasks.testing.Test;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.api.InterfaceInjectionExtensionAPI;
import net.fabricmc.loom.build.mixin.GroovyApInvoker;
import net.fabricmc.loom.build.mixin.JavaApInvoker;
@@ -74,6 +75,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraft
import net.fabricmc.loom.extension.MixinExtension;
import net.fabricmc.loom.task.service.ClasspathGroupService;
import net.fabricmc.loom.util.Checksum;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.ExceptionUtil;
import net.fabricmc.loom.util.ProcessUtil;
import net.fabricmc.loom.util.gradle.GradleUtils;
@@ -172,6 +174,14 @@ public abstract class CompileConfiguration implements Runnable {
final MinecraftMetadataProvider metadataProvider = MinecraftMetadataProvider.create(configContext);
extension.setMetadataProvider(metadataProvider);
if (metadataProvider.getVersionMeta().isVersionOrNewer(Constants.RELEASE_TIME_1_21_11_UNOBFUSCATED_SNAPSHOTS) && !metadataProvider.getVersionMeta().downloads().containsKey("client_mappings")) {
extension.getProductionNamespace().convention(MappingsNamespace.OFFICIAL.toString());
} else {
extension.getProductionNamespace().convention(MappingsNamespace.INTERMEDIARY.toString());
}
extension.getProductionNamespace().finalizeValue();
var jarConfiguration = extension.getMinecraftJarConfiguration().get();
// Provide the vanilla mc jars

View File

@@ -28,6 +28,7 @@ import java.io.IOException;
import org.jspecify.annotations.Nullable;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor;
import net.fabricmc.loom.util.LazyCloseable;
import net.fabricmc.loom.util.fmj.ModEnvironment;
@@ -44,7 +45,7 @@ public interface AccessWidenerEntry {
String getSortKey();
void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper) throws IOException;
void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper, MappingsNamespace productionNamespace) throws IOException;
void readOfficial(ClassTweakerVisitor visitor) throws IOException;
}

View File

@@ -147,9 +147,9 @@ public class AccessWidenerJarProcessor implements MinecraftJarProcessor<AccessWi
return classTweaker;
}
try (LazyCloseable<TinyRemapper> remapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED)) {
try (LazyCloseable<TinyRemapper> remapper = context.createRemapper(context.getProductionNamespace(), MappingsNamespace.NAMED)) {
for (AccessWidenerEntry widener : accessWideners) {
widener.read(classTweaker, remapper);
widener.read(classTweaker, remapper, context.getProductionNamespace());
}
}

View File

@@ -44,7 +44,7 @@ public record LocalAccessWidenerEntry(Path path, String hash) implements AccessW
}
@Override
public void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper) throws IOException {
public void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper, MappingsNamespace productionNamespace) throws IOException {
var reader = ClassTweakerReader.create(visitor);
reader.read(Files.readAllBytes(path), null);
}

View File

@@ -67,7 +67,7 @@ public record ModAccessWidenerEntry(FabricModJson mod, String path, ModEnvironme
}
@Override
public void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper) throws IOException {
public void read(ClassTweakerVisitor visitor, LazyCloseable<TinyRemapper> remapper, MappingsNamespace productionNamespace) throws IOException {
if (transitiveOnly) {
// Filter for only transitive rules
visitor = new TransitiveOnlyFilter(visitor);
@@ -78,7 +78,7 @@ public record ModAccessWidenerEntry(FabricModJson mod, String path, ModEnvironme
if (!header.getNamespace().equals(MappingsNamespace.NAMED.toString())) {
// Remap the AW if needed
visitor = getRemapper(visitor, remapper.get());
visitor = getRemapper(visitor, remapper.get(), productionNamespace);
}
var reader = ClassTweakerReader.create(visitor);
@@ -103,11 +103,11 @@ public record ModAccessWidenerEntry(FabricModJson mod, String path, ModEnvironme
reader.read(data, mod.getId());
}
private static ClassTweakerRemapperVisitor getRemapper(ClassTweakerVisitor visitor, TinyRemapper tinyRemapper) {
private static ClassTweakerRemapperVisitor getRemapper(ClassTweakerVisitor visitor, TinyRemapper tinyRemapper, MappingsNamespace productionNamespace) {
return new ClassTweakerRemapperVisitor(
visitor,
tinyRemapper.getEnvironment().getRemapper(),
MappingsNamespace.INTERMEDIARY.toString(),
productionNamespace.toString(),
MappingsNamespace.NAMED.toString()
);
}

View File

@@ -59,14 +59,14 @@ public final class TransitiveAccessWidenerMappingsProcessor implements Minecraft
return false;
}
if (!MappingsNamespace.INTERMEDIARY.toString().equals(mappings.getSrcNamespace())) {
throw new IllegalStateException("Mapping tree must have intermediary src mappings not " + mappings.getSrcNamespace());
if (!context.getProductionNamespace().toString().equals(mappings.getSrcNamespace())) {
throw new IllegalStateException("Mapping tree must have " + context.getProductionNamespace().toString() + " src mappings not " + mappings.getSrcNamespace());
}
try (LazyCloseable<TinyRemapper> remapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED)) {
try (LazyCloseable<TinyRemapper> remapper = context.createRemapper(context.getProductionNamespace(), MappingsNamespace.NAMED)) {
for (AccessWidenerEntry accessWidener : accessWideners) {
var visitor = new MappingCommentClassTweakerVisitor(accessWidener.mappingId(), mappings);
accessWidener.read(visitor, remapper);
accessWidener.read(visitor, remapper, context.getProductionNamespace());
}
} catch (IOException e) {
throw new UncheckedIOException("Failed to transform access widener mappings", e);

View File

@@ -125,12 +125,12 @@ public abstract class InterfaceInjectionProcessor implements MinecraftJarProcess
return spec.injectedInterfaces();
}
// Remap from intermediary->named
// Remap from productionNamespace->named
final MemoryMappingTree mappings = context.getMappings();
final int intermediaryIndex = mappings.getNamespaceId(MappingsNamespace.INTERMEDIARY.toString());
final int productionIndex = mappings.getNamespaceId(context.getProductionNamespace().toString());
final int namedIndex = mappings.getNamespaceId(MappingsNamespace.NAMED.toString());
try (LazyCloseable<TinyRemapper> tinyRemapper = context.createRemapper(MappingsNamespace.INTERMEDIARY, MappingsNamespace.NAMED)) {
try (LazyCloseable<TinyRemapper> tinyRemapper = context.createRemapper(context.getProductionNamespace(), MappingsNamespace.NAMED)) {
final List<InjectedInterface> remappedInjectedInterfaces = spec.injectedInterfaces().stream()
.filter(injectedInterface -> {
return context.includesClient() // The client jar depends on the server, so always apply all to it
@@ -138,7 +138,7 @@ public abstract class InterfaceInjectionProcessor implements MinecraftJarProcess
})
.map(injectedInterface -> remap(
injectedInterface,
s -> mappings.mapClassName(s, intermediaryIndex, namedIndex),
s -> mappings.mapClassName(s, productionIndex, namedIndex),
tinyRemapper.get().getEnvironment().getRemapper()
))
.toList();

View File

@@ -33,7 +33,6 @@ import org.objectweb.asm.commons.Remapper;
import net.fabricmc.classtweaker.api.ClassTweakerReader;
import net.fabricmc.classtweaker.api.ClassTweakerWriter;
import net.fabricmc.classtweaker.visitors.ClassTweakerRemapperVisitor;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.util.fmj.FabricModJson;
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
@@ -41,15 +40,15 @@ public class AccessWidenerUtils {
/**
* Remap a mods access widener from intermediary to named, so that loader can apply it in our dev-env.
*/
public static byte[] remapAccessWidener(byte[] input, Remapper remapper) {
public static byte[] remapAccessWidener(byte[] input, Remapper remapper, String fromNamespace, String toNamespace) {
int version = ClassTweakerReader.readVersion(input);
ClassTweakerWriter writer = ClassTweakerWriter.create(version);
ClassTweakerRemapperVisitor awRemapper = new ClassTweakerRemapperVisitor(
writer,
remapper,
MappingsNamespace.INTERMEDIARY.toString(),
MappingsNamespace.NAMED.toString()
fromNamespace,
toNamespace
);
ClassTweakerReader reader = ClassTweakerReader.create(awRemapper);
reader.read(input, null); // TODO pass modid

View File

@@ -71,7 +71,6 @@ import net.fabricmc.tinyremapper.OutputConsumerPath;
import net.fabricmc.tinyremapper.TinyRemapper;
public class ModProcessor {
private static final String fromM = MappingsNamespace.INTERMEDIARY.toString();
private static final String toM = MappingsNamespace.NAMED.toString();
private static final Logger LOGGER = LoggerFactory.getLogger(ModProcessor.class);
@@ -140,6 +139,8 @@ public class ModProcessor {
final LoomGradleExtension extension = LoomGradleExtension.get(project);
final MappingConfiguration mappingConfiguration = extension.getMappingConfiguration();
MappingsNamespace productionNamespace = extension.getProductionNamespaceEnum();
Set<String> knownIndyBsms = new HashSet<>(extension.getKnownIndyBsms().get());
for (ModDependency modDependency : remapList) {
@@ -148,9 +149,9 @@ public class ModProcessor {
TinyRemapper.Builder builder = TinyRemapper.newRemapper(TinyRemapperLoggerAdapter.INSTANCE)
.withKnownIndyBsm(knownIndyBsms)
.withMappings(TinyRemapperHelper.create(mappingConfiguration.getMappingsService(project, serviceFactory).getMappingTree(), fromM, toM, false))
.withMappings(TinyRemapperHelper.create(mappingConfiguration.getMappingsService(project, serviceFactory).getMappingTree(), productionNamespace.toString(), toM, false))
.renameInvalidLocals(false)
.extraAnalyzeVisitor(AccessWidenerAnalyzeVisitorProvider.createFromMods(fromM, remapList));
.extraAnalyzeVisitor(AccessWidenerAnalyzeVisitorProvider.createFromMods(productionNamespace.toString(), remapList));
final KotlinClasspathService kotlinClasspathService = serviceFactory.getOrNull(KotlinClasspathService.createOptions(project));
KotlinRemapperClassloader kotlinRemapperClassloader = null;
@@ -164,7 +165,7 @@ public class ModProcessor {
final List<ModProcessorExtension> activeExtensions = ModProcessorExtension.EXTENSIONS.stream()
.filter(e -> remapList.stream().anyMatch(e::appliesTo))
.toList();
final ModProcessorExtension.Context context = new ModProcessorExtension.Context(fromM, toM, remapList);
final ModProcessorExtension.Context context = new ModProcessorExtension.Context(productionNamespace.toString(), toM, remapList);
for (ModProcessorExtension modProcessorExtension : activeExtensions) {
LOGGER.info("Applying mod processor extension: {}", modProcessorExtension.getClass().getSimpleName());
@@ -178,12 +179,12 @@ public class ModProcessor {
}
for (RemapperExtensionHolder holder : extension.getRemapperExtensions().get()) {
holder.apply(builder, fromM, toM);
holder.apply(builder, productionNamespace.toString(), toM);
}
final TinyRemapper remapper = builder.build();
remapper.readClassPath(extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY).toArray(Path[]::new));
remapper.readClassPath(extension.getMinecraftJars(productionNamespace).toArray(Path[]::new));
final Map<ModDependency, OutputConsumerPath> outputConsumerMap = new HashMap<>();
final Map<ModDependency, Pair<byte[], String>> accessWidenerMap = new HashMap<>();
@@ -220,7 +221,7 @@ public class ModProcessor {
if (accessWidenerData != null) {
LOGGER.debug("Remapping access widener in {}", dependency.getInputFile());
byte[] remappedAw = AccessWidenerUtils.remapAccessWidener(accessWidenerData.content(), remapper.getEnvironment().getRemapper());
byte[] remappedAw = AccessWidenerUtils.remapAccessWidener(accessWidenerData.content(), remapper.getEnvironment().getRemapper(), productionNamespace.toString(), toM);
accessWidenerMap.put(dependency, new Pair<>(remappedAw, accessWidenerData.path()));
}

View File

@@ -43,7 +43,7 @@ public final class ContextImplHelper {
try {
TinyRemapper tinyRemapper = TinyRemapperHelper.getTinyRemapper(configContext.project(), configContext.serviceFactory(), from.toString(), to.toString());
for (Path minecraftJar : configContext.extension().getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
for (Path minecraftJar : configContext.extension().getMinecraftJars(from)) {
tinyRemapper.readClassPath(minecraftJar);
}

View File

@@ -35,4 +35,9 @@ public record MappingProcessorContextImpl(ConfigContext configContext) implement
public LazyCloseable<TinyRemapper> createRemapper(MappingsNamespace from, MappingsNamespace to) {
return ContextImplHelper.createRemapper(configContext, from, to);
}
@Override
public MappingsNamespace getProductionNamespace() {
return configContext().extension().getProductionNamespaceEnum();
}
}

View File

@@ -80,7 +80,7 @@ public abstract class ModJavadocProcessor implements MinecraftJarProcessor<ModJa
List<ModJavadoc> javadocs = new ArrayList<>();
for (FabricModJson fabricModJson : context.allMods()) {
ModJavadoc javadoc = ModJavadoc.create(fabricModJson);
ModJavadoc javadoc = ModJavadoc.create(fabricModJson, context.productionNamespace());
if (javadoc != null) {
javadocs.add(javadoc);
@@ -116,7 +116,7 @@ public abstract class ModJavadocProcessor implements MinecraftJarProcessor<ModJa
public record ModJavadoc(String modId, MemoryMappingTree mappingTree, String mappingsHash) {
@Nullable
public static ModJavadoc create(FabricModJson fabricModJson) {
public static ModJavadoc create(FabricModJson fabricModJson, MappingsNamespace productionNamespace) {
final String modId = fabricModJson.getId();
final JsonElement customElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.PROVIDED_JAVADOC);
@@ -137,7 +137,7 @@ public abstract class ModJavadocProcessor implements MinecraftJarProcessor<ModJa
// if the format doesn't have them (this includes the Enigma format, which we want to
// support since it's produced by ModEnigmaTask).
final Map<String, String> fallbackNamespaceReplacements = Map.of(
MappingUtil.NS_SOURCE_FALLBACK, MappingsNamespace.INTERMEDIARY.toString(),
MappingUtil.NS_SOURCE_FALLBACK, productionNamespace.toString(),
MappingUtil.NS_TARGET_FALLBACK, MappingsNamespace.NAMED.toString()
);
final MappingNsRenamer renamer = new MappingNsRenamer(mappings, fallbackNamespaceReplacements);
@@ -148,8 +148,8 @@ public abstract class ModJavadocProcessor implements MinecraftJarProcessor<ModJa
throw new UncheckedIOException("Failed to read javadoc from mod: " + modId, e);
}
if (!mappings.getSrcNamespace().equals(MappingsNamespace.INTERMEDIARY.toString())) {
throw new IllegalStateException("Javadoc provided by mod (%s) must be have an intermediary source namespace".formatted(modId));
if (!mappings.getSrcNamespace().equals(productionNamespace.toString())) {
throw new IllegalStateException("Javadoc provided by mod (%s) must be have an %s source namespace".formatted(modId, productionNamespace.toString()));
}
return new ModJavadoc(modId, mappings, mappingsHash);

View File

@@ -70,4 +70,9 @@ public record ProcessorContextImpl(ConfigContext configContext, MinecraftJar min
public boolean disableObfuscation() {
return configContext().extension().disableObfuscation();
}
@Override
public MappingsNamespace getProductionNamespace() {
return configContext().extension().getProductionNamespaceEnum();
}
}

View File

@@ -42,6 +42,7 @@ import java.util.stream.Stream;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.api.processor.SpecContext;
import net.fabricmc.loom.util.AsyncCache;
import net.fabricmc.loom.util.fmj.FabricModJson;
@@ -230,4 +231,9 @@ public record DeobfSpecContext(List<FabricModJson> modDependencies,
copy.removeAll(right);
return copy;
}
@Override
public MappingsNamespace productionNamespace() {
return MappingsNamespace.OFFICIAL;
}
}

View File

@@ -35,6 +35,7 @@ import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.Usage;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.api.RemapConfigurationSettings;
public interface RemappedProjectView extends ProjectView {
@@ -46,6 +47,8 @@ public interface RemappedProjectView extends ProjectView {
List<RemapConfigurationSettings> getRuntimeRemapConfigurations();
MappingsNamespace getProductionNamespace();
class Impl extends AbstractProjectView implements RemappedProjectView {
public Impl(Project project) {
super(project);
@@ -77,5 +80,10 @@ public interface RemappedProjectView extends ProjectView {
public List<RemapConfigurationSettings> getRuntimeRemapConfigurations() {
return extension.getRuntimeRemapConfigurations();
}
@Override
public MappingsNamespace getProductionNamespace() {
return extension.getProductionNamespaceEnum();
}
}
}

View File

@@ -42,6 +42,7 @@ import org.gradle.api.plugins.JavaPlugin;
import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.api.RemapConfigurationSettings;
import net.fabricmc.loom.api.processor.SpecContext;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets;
@@ -58,7 +59,8 @@ import net.fabricmc.loom.util.fmj.FabricModJsonHelpers;
public record RemappedSpecContext(
List<FabricModJson> modDependencies,
List<FabricModJson> localMods,
List<ModHolder> compileRuntimeMods) implements SpecContext {
List<ModHolder> compileRuntimeMods,
MappingsNamespace productionNamespace) implements SpecContext {
public static RemappedSpecContext create(Project project) {
return create(new RemappedProjectView.Impl(project));
}
@@ -69,7 +71,8 @@ public record RemappedSpecContext(
return new RemappedSpecContext(
getDependentMods(projectView, fmjCache),
projectView.getMods(),
getCompileRuntimeMods(projectView, fmjCache)
getCompileRuntimeMods(projectView, fmjCache),
projectView.getProductionNamespace()
);
}

View File

@@ -95,6 +95,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
protected final Property<Boolean> modProvidedJavadoc;
protected final Property<String> intermediary;
protected final Property<IntermediateMappingsProvider> intermediateMappingsProvider;
private final Property<String> productionNamespace;
private final Property<Boolean> runtimeOnlyLog4j;
private final Property<Boolean> splitModDependencies;
private final Property<MinecraftJarConfiguration<?, ?, ?>> minecraftJarConfiguration;
@@ -139,6 +140,8 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
this.modProvidedJavadoc.finalizeValueOnRead();
this.intermediary = project.getObjects().property(String.class)
.convention(DEFAULT_INTERMEDIARY_URL);
this.productionNamespace = project.getObjects().property(String.class);
this.productionNamespace.finalizeValueOnRead();
this.intermediateMappingsProvider = project.getObjects().property(IntermediateMappingsProvider.class);
this.intermediateMappingsProvider.finalizeValueOnRead();
@@ -341,6 +344,11 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
return intermediary;
}
@Override
public Property<String> getProductionNamespace() {
return productionNamespace;
}
@Override
public IntermediateMappingsProvider getIntermediateMappingsProvider() {
if (LoomGradleExtension.get(getProject()).disableObfuscation()) {

View File

@@ -345,6 +345,11 @@ public abstract class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl
return disableObfuscation.get();
}
@Override
public MappingsNamespace getProductionNamespaceEnum() {
return Objects.requireNonNull(MappingsNamespace.of(getProductionNamespace().get()), "Invalid production namespace");
}
@Override
public void nestJars(TaskProvider<? extends Jar> jarTask, FileCollection jars) {
jarTask.configure(task -> {

View File

@@ -99,16 +99,19 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
@Inject
public RemapJarTask() {
super();
LoomGradleExtension extension = LoomGradleExtension.get(getProject());
final ConfigurationContainer configurations = getProject().getConfigurations();
getClasspath().from(configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
getAddNestedDependencies().convention(true).finalizeValueOnRead();
getOptimizeFabricModJson().convention(false).finalizeValueOnRead();
getTargetNamespace().set(extension.getProductionNamespace());
TaskProvider<NestableJarGenerationTask> processIncludeJars = getProject().getTasks().named(Constants.Task.PROCESS_INCLUDE_JARS, NestableJarGenerationTask.class);
getNestedJars().from(processIncludeJars.map(task -> getProject().fileTree(task.getOutputDirectory())));
getNestedJars().builtBy(processIncludeJars);
getUseMixinAP().set(LoomGradleExtension.get(getProject()).getMixin().getUseLegacyMixinAp());
getUseMixinAP().set(extension.getMixin().getUseLegacyMixinAp());
// Make outputs reproducible by default
setReproducibleFileOrder(true);

View File

@@ -88,6 +88,9 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
@Input
protected abstract Property<String> getNativesDirectoryPath();
@Input
protected abstract Property<String> getProductionNamespace();
@InputFile
@Optional
public abstract RegularFileProperty getRemapClasspathFile();
@@ -116,6 +119,7 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
getAssetsDirectoryPath().set(new File(getExtension().getFiles().getUserCache(), "assets").getAbsolutePath());
getNativesDirectoryPath().set(getExtension().getFiles().getNativesDirectory(getProject()).getAbsolutePath());
getDevLauncherConfig().set(getExtension().getFiles().getDevLauncherConfig());
getProductionNamespace().set(getExtension().getProductionNamespaceEnum().toString());
}
@TaskAction
@@ -131,6 +135,7 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
.property("fabric.development", "true")
.property("log4j.configurationFile", getLog4jConfigPaths().get())
.property("log4j2.formatMsgNoLookups", "true")
.property("fabric.defaultModDistributionNamespace", getProductionNamespace().get())
.argument("client", "--assetIndex")
.argument("client", versionInfo.assetIndex().fabricId(getMinecraftVersion().get()))

View File

@@ -40,7 +40,6 @@ import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.api.RemapConfigurationSettings;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.task.AbstractLoomTask;
import net.fabricmc.loom.util.Constants;
@@ -60,7 +59,7 @@ public abstract class GenerateRemapClasspathTask extends AbstractLoomTask {
.map(configurations::named)
.forEach(getRemapClasspath()::from);
for (Path minecraftJar : getExtension().getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
for (Path minecraftJar : getExtension().getMinecraftJars(getExtension().getProductionNamespaceEnum())) {
getRemapClasspath().from(minecraftJar.toFile());
}

View File

@@ -39,6 +39,7 @@ import org.gradle.api.tasks.Optional;
import org.gradle.process.ExecSpec;
import org.jetbrains.annotations.ApiStatus;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.Platform;
@@ -99,7 +100,11 @@ public abstract non-sealed class ClientProductionRunTask extends AbstractProduct
getClasspath().from(getExtension().getMinecraftProvider().getMinecraftClientJar());
getClasspath().from(detachedConfigurationProvider("net.fabricmc:fabric-loader:%s", getProjectLoaderVersion()));
getClasspath().from(detachedConfigurationProvider("net.fabricmc:intermediary:%s", getExtension().getMinecraftVersion()));
if (getExtension().getProductionNamespaceEnum() == MappingsNamespace.INTERMEDIARY) {
getClasspath().from(detachedConfigurationProvider("net.fabricmc:intermediary:%s", getExtension().getMinecraftVersion()));
}
getClasspath().from(getProject().getConfigurations().named(Constants.Configurations.MINECRAFT_TEST_CLIENT_RUNTIME_LIBRARIES));
dependsOn("downloadAssets");

View File

@@ -35,6 +35,7 @@ public class Constants {
public static final String FABRIC_REPOSITORY = "https://maven.fabricmc.net/";
public static final int ASM_VERSION = Opcodes.ASM9;
public static final String RELEASE_TIME_1_21_11_UNOBFUSCATED_SNAPSHOTS = "2025-11-01T00:00:00+00:00";
public static final String RELEASE_TIME_1_3 = "2012-07-25T22:00:00+00:00";
public static final String RELEASE_TIME_BETA_1_0 = "2010-12-19T22:00:00+00:00";

View File

@@ -166,8 +166,8 @@ public class SourceRemapper {
LorenzMappingService lorenzMappingService = serviceFactory.get(LorenzMappingService.createOptions(
project,
mappingConfiguration,
toNamed ? MappingsNamespace.INTERMEDIARY : MappingsNamespace.NAMED,
toNamed ? MappingsNamespace.NAMED : MappingsNamespace.INTERMEDIARY));
toNamed ? extension.getProductionNamespaceEnum() : MappingsNamespace.NAMED,
toNamed ? MappingsNamespace.NAMED : extension.getProductionNamespaceEnum()));
MappingSet mappings = lorenzMappingService.getMappings();
Mercury mercury = createMercuryWithClassPath(project, toNamed);
@@ -182,8 +182,8 @@ public class SourceRemapper {
}
}
for (Path intermediaryJar : extension.getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
mercury.getClassPath().add(intermediaryJar);
for (Path productionJar : extension.getMinecraftJars(extension.getProductionNamespaceEnum())) {
mercury.getClassPath().add(productionJar);
}
for (Path intermediaryJar : extension.getMinecraftJars(MappingsNamespace.NAMED)) {

View File

@@ -74,9 +74,11 @@ class InterfaceInjectionProcessorTest extends Specification {
specContext.localMods() >> [fmj]
specContext.modDependenciesCompileRuntime() >> []
specContext.modDependenciesCompileRuntimeClient() >> []
specContext.productionNamespace() >> MappingsNamespace.INTERMEDIARY
def processorContext = Mock(ProcessorContext)
processorContext.getMappings() >> createMappings()
processorContext.getProductionNamespace() >> MappingsNamespace.INTERMEDIARY
def jar = tempDir.resolve("test.jar")
packageJar(jar)