Class RemapModsTask

java.lang.Object
org.gradle.api.internal.AbstractTask
org.gradle.api.DefaultTask
net.fabricmc.loom.pipeline.RemapModsTask
All Implemented Interfaces:
Comparable<org.gradle.api.Task>, org.gradle.api.internal.DynamicObjectAware, org.gradle.api.internal.TaskInternal, org.gradle.api.Named, org.gradle.api.plugins.ExtensionAware, org.gradle.api.Task, org.gradle.util.Configurable<org.gradle.api.Task>

@CacheableTask public abstract class RemapModsTask extends org.gradle.api.DefaultTask
L3 流水线:把一个配置里的 mod jar 批量重映射到目标命名空间.

它取代 ModConfigurationRemapper 在配置期同步执行的 mod 重映射。与 RemapMinecraftTask 一起构成 L3 的切换对——二者必须同批接线,因为配置期的 mod 重映射要按路径读 mapped Minecraft jar,只切一个会立刻打断对方。

为什么是「批量」而不是「一 jar 一任务」

mod 重映射需要**整组类型上下文**:字节码里的继承关系可能跨越多个 mod,逐个重映射会 得到与既有实现不同的结果。因此这里沿用原实现的语义——先把所有输入加入 classpath, 再逐个 apply。这也意味着不能把它拆成 Artifact Transform。

产出落位与共享路径的所有权

产物按 Maven 仓库布局写入**构建根下的共享仓库**(.gradle/loom-cache/remapped_mods:同一构建的 所有项目、同一台机器的所有工作树共用同一个目录),路径由坐标与 cache key 决定。因此「每个项目各注册一份 生产者」在这里是不成立的:同一条路径上只能有一个生产者,否则两个任务会写同一个文件(Gradle 9.5 对这种 重叠既不报错也不排序,后完成的覆盖先完成的),而只要有消费方按该路径取产物, 隐式依赖校验就会以「uses this output of task ... without declaring an explicit or implicit dependency」 让整个构建失败——两个项目只是各自依赖自己那份产物时也会失败,因为冲突判定看的是**谁声明了该位置**。

唯一生产者由 RemapMinecraftTaskRegistry.claimAll(org.gradle.api.Project, java.util.List<java.nio.file.Path>, java.util.Map<java.lang.String, java.lang.String>, java.util.function.Function<java.util.List<java.nio.file.Path>, org.gradle.api.tasks.TaskProvider<? extends org.gradle.api.Task>>) 在同一构建内判定,且产物**逐条**声明: 本任务声明的是「自己认领到的那些文件」(getOutputJars()),绝不声明整个共享目录——声明目录会把 别的项目、别的配置的产物一起纳入本任务的快照与清理范围。被别的项目认领的产物仍按完整批次读入 (getMods() 不因认领结果被截断),因此类型上下文与「谁先登记」无关,每条产物的字节是确定的。

消费方按 builtBy 挂到**产出任务的任务路径**上(见 RemappedModArtifacts): 产出方可能是另一份 classloader 里的任务,任务路径是字符串,跨 classloader 可用。

一条依赖可能有多条产物

拆分依赖(SplitModDependency)的消费方读的是 -common / -client 两条带后缀的 产物,而重映射产出的是整体 jar:这类 mod 的**两条**路径都要参与认领与声明,写出时先重映射出整体 jar, 再拆成两半各自落位(见 publishSplit(java.nio.file.Path, java.nio.file.Path, java.util.Set<java.nio.file.Path>))。只认领、只写出无后缀的那一条,消费方的两条路径就都成了 没有生产者的悬空路径——构建全程不报错,症状是编译期少 jar。
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static interface 
    一个待重映射 mod 的描述.

    Nested classes/interfaces inherited from interface org.gradle.api.Named

    org.gradle.api.Named.Namer
  • Field Summary

    Fields inherited from interface org.gradle.api.Task

    TASK_ACTION, TASK_CONSTRUCTOR_ARGS, TASK_DEPENDS_ON, TASK_DESCRIPTION, TASK_GROUP, TASK_NAME, TASK_OVERWRITE, TASK_TYPE
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    static List<Path>
    collectRemapClasspath(Collection<File> remapConfigSourceFiles, Set<File> inputsBeingRemapped)
    从 remap 配置的源文件里筛出应加入重映射 classpath 的路径.
    abstract org.gradle.api.provider.Property<Boolean>
    是否 Forge/NeoForge 系;决定是否执行 AT / CoreMod 加工.
    abstract org.gradle.api.provider.SetProperty<String>
    已知的 indy BSM 集合(含各 mod 元数据里声明的).
    abstract org.gradle.api.provider.Property<KotlinClasspathService.Options>
    Kotlin 重映射支持;仅当项目应用了 Kotlin 插件时存在.
    abstract org.gradle.api.provider.Property<TinyMappingsService.Options>
    映射服务配置;执行期据此取出映射树.
    abstract org.gradle.api.provider.ListProperty<RemapModsTask.ModSpec>
    待重映射的 mod,各自携带自己的 Maven 坐标(决定产出路径).
    abstract org.gradle.api.provider.Property<Boolean>
    是否 NeoForge;决定 AT 是全量映射还是只映射类名.
    abstract org.gradle.api.file.ConfigurableFileCollection
    本任务写出(也因此**声明**)的产物:批次里认领到的那部分,逐条文件.
    abstract org.gradle.api.provider.Property<ModPlatform>
    平台;用于读取各 jar 的 access widener.
    abstract org.gradle.api.file.ConfigurableFileCollection
    重映射 classpath:其它 mod 的原始 jar,以及 mapped Minecraft jar.
    abstract org.gradle.api.provider.Property<Boolean>
    Forge 运行时是否使用 Mojang 命名空间;决定 CoreMod 的映射基准.
    abstract org.gradle.api.provider.Property<String>
    源命名空间(项目的生产命名空间).
    abstract org.gradle.api.provider.Property<String>
    目标命名空间;mod 重映射固定为 named.
    void
     

    Methods inherited from class org.gradle.api.DefaultTask

    compareTo, configure, dependsOn, doFirst, doFirst, doFirst, doLast, doLast, doLast, finalizedBy, getActions, getAnt, getDependsOn, getDescription, getDestroyables, getDidWork, getEnabled, getExtensions, getFinalizedBy, getGroup, getInputs, getLocalState, getLogger, getLogging, getMustRunAfter, getName, getOutputs, getPath, getProject, getShouldRunAfter, getState, getTaskDependencies, getTemporaryDir, getTimeout, hasProperty, mustRunAfter, onlyIf, onlyIf, onlyIf, property, setActions, setDependsOn, setDescription, setDidWork, setEnabled, setFinalizedBy, setGroup, setMustRunAfter, setOnlyIf, setOnlyIf, setOnlyIf, setProperty, setShouldRunAfter, shouldRunAfter, usesService

    Methods inherited from class org.gradle.api.internal.AbstractTask

    acceptServiceReferences, appendParallelSafeAction, doNotTrackState, doNotTrackStateIf, getAsDynamicObject, getIdentityPath, getImpliesSubProjects, getLifecycleDependencies, getOnlyIf, getReasonNotToTrackState, getReasonsNotToTrackState, getReasonTaskIsIncompatibleWithConfigurationCache, getRequiredServices, getServices, getSharedResources, getStandardOutputCapture, getTaskActions, getTaskIdentity, getTemporaryDirFactory, hasTaskActions, injectIntoNewInstance, isCompatibleWithConfigurationCache, isEnabled, isHasCustomActions, notCompatibleWithConfigurationCache, prependParallelSafeAction, restoreOnlyIf, restoreTaskActions, setImpliesSubProjects

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface org.gradle.api.Task

    doNotTrackState, notCompatibleWithConfigurationCache
  • Constructor Details

    • RemapModsTask

      public RemapModsTask()
  • Method Details

    • getMods

      public abstract org.gradle.api.provider.ListProperty<RemapModsTask.ModSpec> getMods()
      待重映射的 mod,各自携带自己的 Maven 坐标(决定产出路径).
    • getRemapClasspath

      @Classpath public abstract org.gradle.api.file.ConfigurableFileCollection getRemapClasspath()
      重映射 classpath:其它 mod 的原始 jar,以及 mapped Minecraft jar.

      必须包含整组输入的类型上下文,且不得包含本轮正在重映射的那些 jar 本身 (它们由 getMods() 提供)。

    • getMappingsServiceOptions

      public abstract org.gradle.api.provider.Property<TinyMappingsService.Options> getMappingsServiceOptions()
      映射服务配置;执行期据此取出映射树.
    • getSourceNamespace

      @Input public abstract org.gradle.api.provider.Property<String> getSourceNamespace()
      源命名空间(项目的生产命名空间).
    • getTargetNamespace

      @Input public abstract org.gradle.api.provider.Property<String> getTargetNamespace()
      目标命名空间;mod 重映射固定为 named.
    • getPlatform

      @Input public abstract org.gradle.api.provider.Property<ModPlatform> getPlatform()
      平台;用于读取各 jar 的 access widener.
    • getKotlinOptions

      @Optional public abstract org.gradle.api.provider.Property<KotlinClasspathService.Options> getKotlinOptions()
      Kotlin 重映射支持;仅当项目应用了 Kotlin 插件时存在.

      Options 本身就是一份任务输入(@Classpath 文件集 + @Input 版本号), 因此可直接作为嵌套输入携带,无需在配置期装配 kotlin 相关重映射。缺省表示项目不用 Kotlin。

    • getForgeLike

      @Input public abstract org.gradle.api.provider.Property<Boolean> getForgeLike()
      是否 Forge/NeoForge 系;决定是否执行 AT / CoreMod 加工.
    • getNeoForge

      @Input public abstract org.gradle.api.provider.Property<Boolean> getNeoForge()
      是否 NeoForge;决定 AT 是全量映射还是只映射类名.
    • getRuntimeMojang

      @Input public abstract org.gradle.api.provider.Property<Boolean> getRuntimeMojang()
      Forge 运行时是否使用 Mojang 命名空间;决定 CoreMod 的映射基准.
    • getKnownIndyBsms

      @Input public abstract org.gradle.api.provider.SetProperty<String> getKnownIndyBsms()
      已知的 indy BSM 集合(含各 mod 元数据里声明的).
    • getOutputJars

      @OutputFiles public abstract org.gradle.api.file.ConfigurableFileCollection getOutputJars()
      本任务写出(也因此**声明**)的产物:批次里认领到的那部分,逐条文件.

      刻意不是 @OutputDirectory:产出根是构建内所有项目共用的共享仓库,声明整个目录会把别人的 产物也算成自己的输出,于是「某个文件该由谁产出」这件事立刻变成冲突(见类注释)。同时它也是执行期 「哪些 mod 要写出」的唯一判据——写出集合与声明集合必须是同一个,才不会出现写了没声明的文件。

    • remap

      public void remap() throws IOException
      Throws:
      IOException
    • collectRemapClasspath

      public static List<Path> collectRemapClasspath(Collection<File> remapConfigSourceFiles, Set<File> inputsBeingRemapped)
      从 remap 配置的源文件里筛出应加入重映射 classpath 的路径.

      两条必须保持的规则:**排除本轮正在重映射的输入**(它们由本任务自己写入产出, 不应再作为 classpath 上下文),且只接受**存在且为普通文件**的条目。

      保留为 public static 而非内联进注册逻辑,是为了让这两条语义可被单元测试直接覆盖 ——它们是静默错误的高发点(多收一个输入会让产物与配置期不等价)。

      Parameters:
      remapConfigSourceFiles - 各 remap 配置源配置下的文件
      inputsBeingRemapped - 本轮正在重映射的输入
      Returns:
      应加入重映射 classpath 的路径