Apply the same manifest attributes to the sources jar. Including a list of client only entries.

Will be used to split the sources into client/common jars in a later change.
This commit is contained in:
modmuss50
2022-06-20 21:11:11 +01:00
parent f705e997e8
commit 317c6daedd
6 changed files with 106 additions and 82 deletions

View File

@@ -24,18 +24,30 @@
package net.fabricmc.loom.task;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.jar.Manifest;
import javax.inject.Inject;
import com.google.common.base.Preconditions;
import org.gradle.api.Action;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Internal;
import org.gradle.jvm.tasks.Jar;
import org.gradle.workers.WorkAction;
import org.gradle.workers.WorkParameters;
@@ -43,9 +55,14 @@ import org.gradle.workers.WorkQueue;
import org.gradle.workers.WorkerExecutor;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.task.service.JarManifestService;
import net.fabricmc.loom.util.ZipReprocessorUtil;
import net.fabricmc.loom.util.ZipUtils;
public abstract class AbstractRemapJarTask extends Jar {
public static final String MANIFEST_PATH = "META-INF/MANIFEST.MF";
public static final String MANIFEST_NAMESPACE_KEY = "Fabric-Mapping-Namespace";
@InputFile
public abstract RegularFileProperty getInputFile();
@@ -67,11 +84,15 @@ public abstract class AbstractRemapJarTask extends Jar {
@Inject
protected abstract WorkerExecutor getWorkerExecutor();
@Input
public abstract Property<Boolean> getIncludesClientOnlyClasses();
@Inject
public AbstractRemapJarTask() {
getSourceNamespace().convention(MappingsNamespace.NAMED.toString()).finalizeValueOnRead();
getTargetNamespace().convention(MappingsNamespace.INTERMEDIARY.toString()).finalizeValueOnRead();
getRemapperIsolation().convention(false).finalizeValueOnRead();
getIncludesClientOnlyClasses().convention(false).finalizeValueOnRead();
}
public final <P extends AbstractRemapParams> void submitWork(Class<? extends AbstractRemapAction<P>> workAction, Action<P> action) {
@@ -87,10 +108,21 @@ public abstract class AbstractRemapJarTask extends Jar {
params.getArchivePreserveFileTimestamps().set(isPreserveFileTimestamps());
params.getArchiveReproducibleFileOrder().set(isReproducibleFileOrder());
params.getJarManifestService().set(JarManifestService.get(getProject()));
if (getIncludesClientOnlyClasses().get()) {
final List<String> clientOnlyEntries = getClientOnlyEntries();
applyClientOnlyManifestAttributes(params, clientOnlyEntries);
params.getClientOnlyEntries().set(clientOnlyEntries.stream().filter(s -> s.endsWith(".class")).toList());
}
action.execute(params);
});
}
@Internal
protected abstract List<String> getClientOnlyEntries();
public interface AbstractRemapParams extends WorkParameters {
RegularFileProperty getInputFile();
RegularFileProperty getOutputFile();
@@ -100,6 +132,18 @@ public abstract class AbstractRemapJarTask extends Jar {
Property<Boolean> getArchivePreserveFileTimestamps();
Property<Boolean> getArchiveReproducibleFileOrder();
Property<JarManifestService> getJarManifestService();
MapProperty<String, String> getManifestAttributes();
ListProperty<String> getClientOnlyEntries();
}
protected void applyClientOnlyManifestAttributes(AbstractRemapParams params, List<String> entries) {
params.getManifestAttributes().set(Map.of(
"Fabric-Loom-Split-Environment", "true",
"Fabric-Loom-Client-Only-Entries", String.join(";", entries)
));
}
public abstract static class AbstractRemapAction<T extends AbstractRemapParams> implements WorkAction<T> {
@@ -112,6 +156,21 @@ public abstract class AbstractRemapJarTask extends Jar {
outputFile = getParameters().getOutputFile().getAsFile().get().toPath();
}
protected void modifyJarManifest() throws IOException {
int count = ZipUtils.transform(outputFile, Map.of(MANIFEST_PATH, bytes -> {
var manifest = new Manifest(new ByteArrayInputStream(bytes));
getParameters().getJarManifestService().get().apply(manifest, getParameters().getManifestAttributes().get());
manifest.getMainAttributes().putValue(MANIFEST_NAMESPACE_KEY, getParameters().getTargetNamespace().get());
ByteArrayOutputStream out = new ByteArrayOutputStream();
manifest.write(out);
return out.toByteArray();
}));
Preconditions.checkState(count > 0, "Did not transform any jar manifest");
}
protected void rewriteJar() throws IOException {
final boolean isReproducibleFileOrder = getParameters().getArchiveReproducibleFileOrder().get();
final boolean isPreserveFileTimestamps = getParameters().getArchivePreserveFileTimestamps().get();
@@ -127,4 +186,31 @@ public abstract class AbstractRemapJarTask extends Jar {
public RegularFileProperty getInput() {
return getInputFile();
}
protected static List<String> getRootPaths(Set<File> files) {
return files.stream()
.map(root -> {
String rootPath = root.getAbsolutePath().replace("\\", "/");
if (rootPath.charAt(rootPath.length() - 1) != '/') {
rootPath += '/';
}
return rootPath;
}).toList();
}
protected static Function<File, String> relativePath(List<String> rootPaths) {
return file -> {
String s = file.getAbsolutePath().replace("\\", "/");
for (String rootPath : rootPaths) {
if (s.startsWith(rootPath)) {
s = s.substring(rootPath.length());
}
}
return s;
};
}
}