3434import java .util .Collections ;
3535import java .util .List ;
3636import java .util .Map ;
37+ import java .util .jar .Attributes ;
3738import java .util .jar .Manifest ;
3839
3940import javax .inject .Inject ;
7475import net .fabricmc .loom .util .service .ScopedServiceFactory ;
7576
7677public abstract class AbstractRemapJarTask extends Jar {
78+ /**
79+ * The main input jar to remap.
80+ * Other contents can be added to this task, but this jar must always be present.
81+ *
82+ * <p>The input file's manifest will be copied into the remapped jar.
83+ */
7784 @ InputFile
7885 public abstract RegularFileProperty getInputFile ();
7986
@@ -143,6 +150,7 @@ public final <P extends AbstractRemapParams> void submitWork(Class<? extends Abs
143150 final WorkQueue workQueue = getWorkerExecutor ().noIsolation ();
144151
145152 workQueue .submit (workAction , params -> {
153+ params .getInputFile ().set (getInputFile ());
146154 params .getArchiveFile ().set (getArchiveFile ());
147155
148156 params .getSourceNamespace ().set (getSourceNamespace ());
@@ -181,6 +189,7 @@ public final <P extends AbstractRemapParams> void submitWork(Class<? extends Abs
181189 protected abstract Provider <? extends ClientEntriesService .Options > getClientOnlyEntriesOptionsProvider (SourceSet clientSourceSet );
182190
183191 public interface AbstractRemapParams extends WorkParameters {
192+ RegularFileProperty getInputFile ();
184193 RegularFileProperty getArchiveFile ();
185194
186195 Property <String > getSourceNamespace ();
@@ -242,11 +251,20 @@ public final void execute() {
242251 }
243252 }
244253
254+ // Note: the inputFile parameter is the remapping input file.
255+ // The main input jar is available in the parameters, but should not be used
256+ // for remapping as it might be missing some files added manually to this task.
245257 protected abstract void execute (Path inputFile ) throws IOException ;
246258
247259 protected void modifyJarManifest () throws IOException {
248260 int count = ZipUtils .transform (outputFile , Map .of (Constants .Manifest .PATH , bytes -> {
249261 var manifest = new Manifest (new ByteArrayInputStream (bytes ));
262+ byte [] sourceManifestBytes = ZipUtils .unpackNullable (getParameters ().getInputFile ().get ().getAsFile ().toPath (), Constants .Manifest .PATH );
263+
264+ if (sourceManifestBytes != null ) {
265+ var sourceManifest = new Manifest (new ByteArrayInputStream (sourceManifestBytes ));
266+ mergeManifests (manifest , sourceManifest );
267+ }
250268
251269 getParameters ().getJarManifestService ().get ().apply (manifest , getParameters ().getManifestAttributes ().get ());
252270 manifest .getMainAttributes ().putValue (Constants .Manifest .MAPPING_NAMESPACE , getParameters ().getTargetNamespace ().get ());
@@ -268,6 +286,24 @@ protected void rewriteJar() throws IOException {
268286 ZipReprocessorUtil .reprocessZip (outputFile , isReproducibleFileOrder , isPreserveFileTimestamps , compression );
269287 }
270288 }
289+
290+ private static void mergeManifests (Manifest target , Manifest source ) {
291+ mergeAttributes (target .getMainAttributes (), source .getMainAttributes ());
292+
293+ source .getEntries ().forEach ((name , sourceAttributes ) -> {
294+ final Attributes targetAttributes = target .getAttributes (name );
295+
296+ if (targetAttributes != null ) {
297+ mergeAttributes (targetAttributes , sourceAttributes );
298+ } else {
299+ target .getEntries ().put (name , sourceAttributes );
300+ }
301+ });
302+ }
303+
304+ private static void mergeAttributes (Attributes target , Attributes source ) {
305+ source .forEach (target ::putIfAbsent );
306+ }
271307 }
272308
273309 @ Deprecated
0 commit comments