Skip to content

Commit 02d12c7

Browse files
committed
Bind cache to jar version
1 parent 0fd5073 commit 02d12c7

File tree

6 files changed

+70
-45
lines changed

6 files changed

+70
-45
lines changed

build.gradle.kts

+6-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,10 @@ val fullJar: Jar by tasks.creating(Jar::class) {
138138
rename("output.json", "adapter_data.json")
139139
}
140140
from(modJar)
141-
manifest.attributes("Embedded-Dependencies-Mod" to modJar.archiveFile.get().asFile.name)
141+
manifest {
142+
from(tasks.jar.get().manifest)
143+
attributes("Embedded-Dependencies-Mod" to modJar.archiveFile.get().asFile.name)
144+
}
142145

143146
archiveClassifier.set("full")
144147
}
@@ -264,7 +267,8 @@ tasks {
264267
"Implementation-Title" to project.name,
265268
"Implementation-Version" to project.version,
266269
"Implementation-Vendor" to "Sinytra",
267-
"Implementation-Timestamp" to LocalDateTime.now()
270+
"Implementation-Timestamp" to LocalDateTime.now(),
271+
"Automatic-Module-Name" to "dev.su5ed.sinytra.connector"
268272
)
269273
}
270274
}

src/main/java/dev/su5ed/sinytra/connector/ConnectorUtil.java

+16-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.google.gson.Gson;
55
import com.google.gson.GsonBuilder;
66
import cpw.mods.modlauncher.api.ServiceRunner;
7+
import dev.su5ed.sinytra.connector.locator.EmbeddedDependencies;
78
import net.minecraftforge.fml.loading.FMLPaths;
89

910
import java.io.IOException;
@@ -43,18 +44,20 @@ public final class ConnectorUtil {
4344
CACHE_ENABLED = prop == null || prop.equals("true");
4445
}
4546

46-
public static CacheFile getCached(String version, Path input, Path output) {
47+
public static CacheFile getCached(Path input, Path output) {
4748
if (CACHE_ENABLED) {
4849
Path inputCache = output.getParent().resolve(output.getFileName() + ".input");
4950
try {
5051
byte[] bytes = Files.readAllBytes(input);
51-
String checksum = version + "," + Hashing.sha256().hashBytes(bytes);
52+
String cacheVersion = EmbeddedDependencies.getJarCacheVersion();
53+
String checksum = cacheVersion + "," + Hashing.sha256().hashBytes(bytes);
5254

5355
if (Files.exists(inputCache) && Files.exists(output)) {
5456
String cached = Files.readString(inputCache);
5557
if (cached.equals(checksum)) {
5658
return new CacheFile(inputCache, checksum, true);
57-
} else {
59+
}
60+
else {
5861
Files.delete(output);
5962
Files.delete(inputCache);
6063
}
@@ -67,16 +70,16 @@ public static CacheFile getCached(String version, Path input, Path output) {
6770
return new CacheFile(null, null, false);
6871
}
6972

70-
public static void cache(String version, Path input, Path output, ServiceRunner action) {
71-
CacheFile cacheFile = getCached(version, input, output);
73+
public static void cache(Path input, Path output, ServiceRunner action) {
74+
CacheFile cacheFile = getCached(input, output);
7275
if (!cacheFile.isUpToDate()) {
7376
try {
7477
Files.deleteIfExists(output);
7578
action.run();
7679
cacheFile.save();
7780
} catch (Throwable t) {
7881
throw new RuntimeException(t);
79-
}
82+
}
8083
}
8184
}
8285

@@ -113,11 +116,13 @@ public boolean isUpToDate() {
113116
}
114117

115118
public void save() {
116-
try {
117-
Files.writeString(this.inputCache, this.inputChecksum);
118-
this.isUpToDate = true;
119-
} catch (IOException e) {
120-
throw new UncheckedIOException(e);
119+
if (this.inputCache != null) {
120+
try {
121+
Files.writeString(this.inputCache, this.inputChecksum);
122+
this.isUpToDate = true;
123+
} catch (IOException e) {
124+
throw new UncheckedIOException(e);
125+
}
121126
}
122127
}
123128
}

src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorLocator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private static JarTransformer.TransformableJar prepareNestedJar(Path tempDir, St
137137
String parentNameWithoutExt = parentName.split("\\.(?!.*\\.)")[0];
138138
// Extract JiJ
139139
Path extracted = tempDir.resolve(parentNameWithoutExt + "$" + path.getFileName().toString());
140-
ConnectorUtil.cache("1", path, extracted, () -> Files.copy(path, extracted));
140+
ConnectorUtil.cache(path, extracted, () -> Files.copy(path, extracted));
141141

142142
return uncheck(() -> JarTransformer.cacheTransformableJar(extracted.toFile()));
143143
}

src/main/java/dev/su5ed/sinytra/connector/locator/EmbeddedDependencies.java

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package dev.su5ed.sinytra.connector.locator;
22

3+
import com.google.common.base.Suppliers;
34
import com.google.common.collect.ImmutableMap;
5+
import com.mojang.logging.LogUtils;
6+
import org.apache.commons.lang3.RandomStringUtils;
7+
import org.jetbrains.annotations.Nullable;
8+
import org.slf4j.Logger;
49

510
import java.io.IOException;
611
import java.io.InputStream;
@@ -12,6 +17,7 @@
1217
import java.nio.file.Files;
1318
import java.nio.file.Path;
1419
import java.util.Map;
20+
import java.util.function.Supplier;
1521
import java.util.jar.Attributes;
1622
import java.util.jar.Manifest;
1723
import java.util.stream.Stream;
@@ -24,6 +30,7 @@
2430
* based on jar manifest attributes.
2531
*/
2632
public final class EmbeddedDependencies {
33+
private static final Logger LOGGER = LogUtils.getLogger();
2734
// Manifest attribute name prefix for embedded dependencies
2835
private static final String JIJ_ATTRIBUTE_PREFIX = "Embedded-Dependencies-";
2936
// Embedded mod jar name
@@ -37,6 +44,15 @@ public final class EmbeddedDependencies {
3744
return Path.of(jarLocation.toURI());
3845
});
3946
private static final Attributes ATTRIBUTES = readManifestAttributes();
47+
private static final Supplier<String> JAR_CACHE_VERSION = Suppliers.memoize(() -> {
48+
String ver = EmbeddedDependencies.class.getPackage().getImplementationVersion();
49+
if (ver == null) {
50+
LOGGER.error("Missing Connector jar version, disabling transformer caching");
51+
// Return a random string to still write an input file, so that once we have a proper version available we refresh the cache
52+
return RandomStringUtils.randomAlphabetic(5);
53+
}
54+
return ver;
55+
});
4056

4157
/**
4258
* {@return a stream of paths of all embedded jars}
@@ -49,6 +65,11 @@ public static Path getAdapterData() {
4965
return SELF_PATH.resolve(ADAPTER_DATA_PATH);
5066
}
5167

68+
@Nullable
69+
public static String getJarCacheVersion() {
70+
return JAR_CACHE_VERSION.get();
71+
}
72+
5273
/**
5374
* Get the root path inside an embedded jar.
5475
*

src/main/java/dev/su5ed/sinytra/connector/transformer/JarTransformer.java

+2-25
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,12 @@
3636
import org.slf4j.Marker;
3737
import org.slf4j.MarkerFactory;
3838

39-
import java.io.ByteArrayOutputStream;
4039
import java.io.File;
4140
import java.io.IOException;
4241
import java.io.InputStream;
4342
import java.io.InputStreamReader;
44-
import java.io.OutputStreamWriter;
4543
import java.io.Reader;
4644
import java.io.UncheckedIOException;
47-
import java.io.Writer;
48-
import java.nio.file.FileSystem;
49-
import java.nio.file.FileSystems;
5045
import java.nio.file.Files;
5146
import java.nio.file.Path;
5247
import java.nio.file.Paths;
@@ -74,8 +69,6 @@ public final class JarTransformer {
7469
private static final String MAPPED_SUFFIX = "_mapped_" + FMLEnvironment.naming + "_" + FMLLoader.versionInfo().mcVersion();
7570
private static final String FABRIC_MAPPING_NAMESPACE = "Fabric-Mapping-Namespace";
7671
private static final String SOURCE_NAMESPACE = "intermediary";
77-
// Increment to invalidate cache
78-
private static final int CACHE_VERSION = 3;
7972
private static final Logger LOGGER = LogUtils.getLogger();
8073
private static final Marker TRANSFORM_MARKER = MarkerFactory.getMarker("TRANSFORM");
8174

@@ -158,7 +151,7 @@ public static TransformableJar cacheTransformableJar(File input) throws IOExcept
158151

159152
FabricModFileMetadata metadata = readModMetadata(input);
160153
FabricModPath path = new FabricModPath(output, metadata);
161-
ConnectorUtil.CacheFile cacheFile = ConnectorUtil.getCached(String.valueOf(CACHE_VERSION), input.toPath(), output);
154+
ConnectorUtil.CacheFile cacheFile = ConnectorUtil.getCached(input.toPath(), output);
162155
return new TransformableJar(input, path, cacheFile);
163156
}
164157

@@ -232,7 +225,7 @@ private static void transformJar(File input, Path output, FabricModFileMetadata
232225
.add(new FieldToMethodTransformer(metadata.modMetadata().getAccessWidener(), resolver.getMap("srg", SOURCE_NAMESPACE)))
233226
.add(remappingTransformer)
234227
.add(new MixinPatchTransformer(metadata.mixinClasses(), refmap.merged().mappings, adapterPatches))
235-
.add(new RefmapRemapper(metadata.mixinConfigs()))
228+
.add(new RefmapRemapper(metadata.mixinConfigs(), refmap.files()))
236229
.add(new ModMetadataGenerator(metadata.modMetadata().getId()))
237230
.logger(s -> LOGGER.trace(TRANSFORM_MARKER, s))
238231
.debug(s -> LOGGER.trace(TRANSFORM_MARKER, s));
@@ -246,22 +239,6 @@ private static void transformJar(File input, Path output, FabricModFileMetadata
246239
throw t;
247240
}
248241

249-
// Write refmaps
250-
try (FileSystem fs = FileSystems.newFileSystem(output, Map.of())) {
251-
refmap.files().forEach((file, data) -> {
252-
Path path = fs.getPath(file);
253-
try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream()) {
254-
try (Writer writer = new OutputStreamWriter(byteStream)) {
255-
data.write(writer);
256-
writer.flush();
257-
}
258-
Files.write(path, byteStream.toByteArray());
259-
} catch (IOException e) {
260-
throw new UncheckedIOException(e);
261-
}
262-
});
263-
}
264-
265242
stopwatch.stop();
266243
LOGGER.debug(TRANSFORM_MARKER, "Jar {} transformed in {} ms", input.getName(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
267244
}

src/main/java/dev/su5ed/sinytra/connector/transformer/RefmapRemapper.java

+24-6
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
import java.io.IOException;
1414
import java.io.InputStream;
1515
import java.io.InputStreamReader;
16+
import java.io.OutputStreamWriter;
1617
import java.io.Reader;
1718
import java.io.UncheckedIOException;
19+
import java.io.Writer;
1820
import java.nio.file.FileSystem;
1921
import java.nio.file.FileSystems;
2022
import java.nio.file.Files;
@@ -32,10 +34,8 @@ public class RefmapRemapper implements Transformer {
3234
private static final String INTERMEDIARY_MAPPING_ENV = "named:intermediary";
3335
private static final String SRG_MAPPING_ENV = "searge";
3436

35-
private final Map<String, String> configs;
36-
3737
public record RefmapFiles(SrgRemappingReferenceMapper.SimpleRefmap merged, Map<String, SrgRemappingReferenceMapper.SimpleRefmap> files) {}
38-
38+
3939
public static RefmapFiles processRefmaps(File input, Collection<String> refmaps, SrgRemappingReferenceMapper remapper) throws IOException {
4040
SrgRemappingReferenceMapper.SimpleRefmap results = new SrgRemappingReferenceMapper.SimpleRefmap(Map.of(), Map.of());
4141
Map<String, SrgRemappingReferenceMapper.SimpleRefmap> refmapFiles = new HashMap<>();
@@ -47,15 +47,19 @@ public static RefmapFiles processRefmaps(File input, Collection<String> refmaps,
4747
SrgRemappingReferenceMapper.SimpleRefmap remapped = remapRefmapInPlace(data, remapper);
4848
refmapFiles.put(refmap, remapped);
4949
results = results.merge(remapped);
50-
} else {
50+
}
51+
else {
5152
LOGGER.warn("Refmap remapper could not find refmap file {}", refmap);
5253
}
5354
}
5455
}
5556
return new RefmapFiles(results, refmapFiles);
5657
}
5758

58-
public RefmapRemapper(Collection<String> configs) {
59+
private final Map<String, String> configs;
60+
private final Map<String, SrgRemappingReferenceMapper.SimpleRefmap> files;
61+
62+
public RefmapRemapper(Collection<String> configs, Map<String, SrgRemappingReferenceMapper.SimpleRefmap> files) {
5963
this.configs = configs.stream()
6064
// Some mods (specifically mixinextras) are present on both platforms, and mixin can fail to select the correct configs for
6165
// each jar due to their names being the same. To avoid conflicts, we assign fabric mixin configs new, unique names.
@@ -65,11 +69,25 @@ public RefmapRemapper(Collection<String> configs) {
6569
// Append unique string to file name
6670
return parts[0] + "-" + RandomStringUtils.randomAlphabetic(5) + "." + parts[1];
6771
}));
72+
this.files = files;
6873
}
6974

7075
@Override
7176
public ResourceEntry process(ResourceEntry entry) {
72-
String rename = this.configs.get(entry.getName());
77+
String name = entry.getName();
78+
if (this.files.containsKey(name)) {
79+
try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream()) {
80+
try (Writer writer = new OutputStreamWriter(byteStream)) {
81+
this.files.get(name).write(writer);
82+
writer.flush();
83+
}
84+
byte[] data = byteStream.toByteArray();
85+
return ResourceEntry.create(name, entry.getTime(), data);
86+
} catch (IOException e) {
87+
throw new UncheckedIOException(e);
88+
}
89+
}
90+
String rename = this.configs.get(name);
7391
if (rename != null) {
7492
return ResourceEntry.create(rename, entry.getTime(), entry.getData());
7593
}

0 commit comments

Comments
 (0)