Skip to content

Commit 466c00b

Browse files
authored
cf-files: correctly handle duplicate file refs (#421)
1 parent d55e8f8 commit 466c00b

File tree

4 files changed

+97
-2
lines changed

4 files changed

+97
-2
lines changed

src/main/java/me/itzg/helpers/curseforge/CurseForgeFilesCommand.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,12 @@ private static Map<ModFileIds, FileEntry> buildPreviousFilesFromManifest(CurseFo
199199
oldManifest.getEntries().stream()
200200
.collect(Collectors.toMap(
201201
FileEntry::getIds,
202-
fileEntry -> fileEntry
202+
fileEntry -> fileEntry,
203+
// merge by picking first
204+
(t, t2) -> {
205+
log.warn("Duplicate files detected in previous manifest: {} vs {}", t, t2);
206+
return t;
207+
}
203208
))
204209
: Collections.emptyMap();
205210
}

src/main/java/me/itzg/helpers/curseforge/ModFileRefResolver.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public Mono<List<CurseForgeFile>> resolveModFiles(List<String> modFileRefs, Stri
6666
@NotNull
6767
private static Flux<String> expandFileListings(List<String> modFileRefs) {
6868
return Flux.fromStream(modFileRefs.stream()
69+
.distinct()
6970
// handle @-file containing refs
7071
.flatMap(ref -> {
7172
if (ref.startsWith("@")) {

src/main/java/me/itzg/helpers/files/Manifests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public static <M extends BaseManifest> M load(Path outputDir, String id, Class<M
144144
}
145145
}
146146

147-
private static Path buildManifestPath(Path outputDir, String id) {
147+
public static Path buildManifestPath(Path outputDir, String id) {
148148
return outputDir.resolve(String.format(
149149
".%s-manifest%s", id, SUFFIX
150150
));

src/test/java/me/itzg/helpers/curseforge/CurseForgeFilesCommandTest.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
package me.itzg.helpers.curseforge;
22

3+
import static com.github.tomakehurst.wiremock.client.WireMock.*;
34
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
5+
import static java.util.Collections.singletonList;
46
import static org.assertj.core.api.Assertions.assertThat;
57

8+
import com.github.tomakehurst.wiremock.client.WireMock;
69
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
710
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
811
import java.io.IOException;
12+
import java.nio.charset.StandardCharsets;
913
import java.nio.file.Files;
1014
import java.nio.file.Path;
1115
import java.util.Arrays;
16+
import java.util.Collections;
17+
import me.itzg.helpers.curseforge.model.CurseForgeFile;
18+
import me.itzg.helpers.curseforge.model.CurseForgeMod;
19+
import me.itzg.helpers.curseforge.model.FileIndex;
20+
import me.itzg.helpers.curseforge.model.ModsSearchResponse;
21+
import me.itzg.helpers.files.Manifests;
1222
import org.junit.jupiter.api.Test;
1323
import org.junit.jupiter.api.extension.RegisterExtension;
1424
import org.junit.jupiter.api.io.TempDir;
@@ -107,4 +117,83 @@ void usingListingFile() throws IOException {
107117
assertThat(tempDir.resolve("plugins/worldguard-bukkit-7.0.7-dist.jar")).exists();
108118

109119
}
120+
121+
@Test
122+
void handlesDuplicateManifestEntries() throws IOException {
123+
final Path manifestFile = Files.write(tempDir.resolve(Manifests.buildManifestPath(tempDir, CurseForgeFilesManifest.ID)), ("{\n"
124+
+ " \"@type\": \"me.itzg.helpers.curseforge.CurseForgeFilesManifest\",\n"
125+
+ " \"timestamp\": \"2024-04-27T17:48:56.529386300Z\",\n"
126+
+ " \"files\": null,\n"
127+
+ " \"entries\": [\n"
128+
+ " {\n"
129+
+ " \"ids\": {\n"
130+
+ " \"modId\": 667389,\n"
131+
+ " \"fileId\": 4802504\n"
132+
+ " },\n"
133+
+ " \"filePath\": \"mods\\\\goblintraders-fabric-1.20.1-1.9.3.jar\"\n"
134+
+ " },\n"
135+
+ " {\n"
136+
+ " \"ids\": {\n"
137+
+ " \"modId\": 667389,\n"
138+
+ " \"fileId\": 4802504\n"
139+
+ " },\n"
140+
+ " \"filePath\": \"mods\\\\goblintraders-fabric-1.20.1-1.9.3.jar\"\n"
141+
+ " }\n"
142+
+ " ]\n"
143+
+ "}").getBytes(StandardCharsets.UTF_8));
144+
145+
wm.stubFor(get(urlPathEqualTo("/v1/mods/search"))
146+
.withQueryParam("gameId", WireMock.equalTo("432"))
147+
.withQueryParam("slug", WireMock.equalTo("goblintraders-fabric"))
148+
.withQueryParam("classId", WireMock.equalTo("6"))
149+
.willReturn(
150+
jsonResponse(new ModsSearchResponse()
151+
.setData(singletonList(
152+
new CurseForgeMod()
153+
.setId(667389)
154+
.setClassId(6)
155+
.setGameId(432)
156+
.setLatestFilesIndexes(singletonList(
157+
new FileIndex()
158+
.setGameVersion("1.20.1")
159+
.setFileId(4802504)
160+
))
161+
.setLatestFiles(singletonList(
162+
new CurseForgeFile()
163+
.setId(4802504)
164+
.setModId(667389)
165+
.setDependencies(Collections.emptyList())
166+
// reference cdn.json declaration
167+
.setDownloadUrl(wm.baseUrl() + "/files/goblintraders-fabric-1.20.1-1.9.3.jar")
168+
.setFileName("goblintraders-fabric-1.20.1-1.9.3.jar")
169+
))
170+
)), 200)
171+
)
172+
);
173+
174+
int exitCode = new CommandLine(
175+
new CurseForgeFilesCommand()
176+
)
177+
.setCaseInsensitiveEnumValuesAllowed(true)
178+
.execute(
179+
"--api-base-url", wm.baseUrl(),
180+
"--api-key", "test",
181+
"--output-directory", tempDir.toString(),
182+
"--default-category", "mc-mods",
183+
"--game-version=1.20.1",
184+
"--mod-loader=fabric",
185+
"https://www.curseforge.com/minecraft/mc-mods/goblintraders-fabric",
186+
"https://www.curseforge.com/minecraft/mc-mods/goblintraders-fabric"
187+
);
188+
189+
assertThat(exitCode).isEqualTo(0);
190+
191+
assertThat(manifestFile)
192+
.exists();
193+
194+
final CurseForgeFilesManifest manifest = Manifests.load(tempDir, CurseForgeFilesManifest.ID, CurseForgeFilesManifest.class);
195+
assertThat(manifest).isNotNull();
196+
assertThat(manifest.getEntries()).hasSize(1);
197+
assertThat(manifest.getEntries().get(0).getIds()).isEqualTo(new ModFileIds(667389, 4802504));
198+
}
110199
}

0 commit comments

Comments
 (0)