diff --git a/src/main/groovy/com/github/winplay02/gitcraft/GitCraftQuirks.java b/src/main/groovy/com/github/winplay02/gitcraft/GitCraftQuirks.java index 6e1478c0..1618c97e 100644 --- a/src/main/groovy/com/github/winplay02/gitcraft/GitCraftQuirks.java +++ b/src/main/groovy/com/github/winplay02/gitcraft/GitCraftQuirks.java @@ -5,6 +5,8 @@ import java.time.ZonedDateTime; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class GitCraftQuirks { /// Mapping quirks @@ -54,4 +56,8 @@ public class GitCraftQuirks { // There are no releases for these parchment versions (yet) public static List parchmentMissingVersions = List.of("1.18", "1.19", "1.19.1", "1.20", "1.20.5", "1.21.2"); + + // Special cases for Omniarchive manifest + public static List omniarchiveSpecialSnapshots = List.of("1.0.0-tominecon", "13w02a-whitetexturefix", "13w04a-whitelinefix", "1.5-pre-whitelinefix", "13w12~-1439"); + public static List omniarchiveLinearSpecials = Stream.concat(Stream.of("c0.0.11a-launcher", "c0.0.13a-launcher", "b1.6-tb3"), omniarchiveSpecialSnapshots.stream()).collect(Collectors.toList()); } diff --git a/src/main/groovy/com/github/winplay02/gitcraft/MinecraftVersionGraph.java b/src/main/groovy/com/github/winplay02/gitcraft/MinecraftVersionGraph.java index 94e05bad..d57426ac 100644 --- a/src/main/groovy/com/github/winplay02/gitcraft/MinecraftVersionGraph.java +++ b/src/main/groovy/com/github/winplay02/gitcraft/MinecraftVersionGraph.java @@ -325,7 +325,7 @@ private OrderedVersion walkBackToBranchPoint(OrderedVersion mcVersion, boolean r Set branches = this.getPreviousVertices(mcVersion); if (branches.size() == 1) { - return this.walkBackToBranchPoint(branches.iterator().next()); + return this.walkBackToBranchPoint(branches.iterator().next(), root); } // version is not a branch point or root, and number of prev versions @@ -342,7 +342,7 @@ private OrderedVersion walkBackToBranchPoint(OrderedVersion mcVersion, boolean r // if path length to tip is not present, then this version // was already marked as lying on a branch if (!this.pathsToTip.containsKey(branch)) { - return this.walkBackToBranchPoint(branch); + return this.walkBackToBranchPoint(branch, root); } int pathToRoot = this.pathsToRoot.get(branch); diff --git a/src/main/groovy/com/github/winplay02/gitcraft/manifest/omniarchive/OmniarchiveMetadataProvider.java b/src/main/groovy/com/github/winplay02/gitcraft/manifest/omniarchive/OmniarchiveMetadataProvider.java index 823cb912..8ed4c80d 100644 --- a/src/main/groovy/com/github/winplay02/gitcraft/manifest/omniarchive/OmniarchiveMetadataProvider.java +++ b/src/main/groovy/com/github/winplay02/gitcraft/manifest/omniarchive/OmniarchiveMetadataProvider.java @@ -1,9 +1,12 @@ package com.github.winplay02.gitcraft.manifest.omniarchive; import java.util.List; +import java.util.regex.Pattern; +import com.github.winplay02.gitcraft.GitCraftQuirks; import com.github.winplay02.gitcraft.manifest.ManifestSource; import com.github.winplay02.gitcraft.manifest.vanilla.MojangLauncherMetadataProvider; +import com.github.winplay02.gitcraft.types.OrderedVersion; public class OmniarchiveMetadataProvider extends MojangLauncherMetadataProvider { @@ -29,11 +32,150 @@ public String getInternalName() { @Override public List getParentVersionIds(String versionId) { switch (versionId) { - case "3D Shareware v1.34" -> { - return List.of("19w13b+1653"); + // Combat + case "combat1" -> { + return List.of("1.14.3-pre4"); + } + case "combat2" -> { + return List.of("combat1", "1.14.4"); + } + case "combat3" -> { + return List.of("combat2"); + } + case "combat4" -> { + return List.of("combat3", "1.15-pre3"); + } + case "combat5" -> { + return List.of("combat4", "1.15.2-pre2"); + } + case "combat6" -> { + return List.of("combat5", "1.16.2-pre3"); + } + case "combat7" -> { + return List.of("combat6", "1.16.2"); + } + case "combat7b" -> { + return List.of("combat7"); + } + case "combat7c" -> { + return List.of("combat7b"); + } + case "combat8" -> { + return List.of("combat7c"); + } + case "combat8b" -> { + return List.of("combat8"); + } + case "combat8c" -> { + return List.of("combat8b"); + } + // Experimental 1.18 + case "1.18-exp1" -> { + return List.of("1.17.1-pre1"); + } + case "1.18-exp2" -> { + return List.of("1.18-exp1"); + } + case "1.18-exp3" -> { + return List.of("1.18-exp2"); + } + case "1.18-exp4" -> { + return List.of("1.18-exp3"); + } + case "1.18-exp5" -> { + return List.of("1.18-exp4"); + } + case "1.18-exp6" -> { + return List.of("1.18-exp5"); + } + case "1.18-exp7" -> { + return List.of("1.18-exp6"); + } + case "21w37a" -> { + return List.of("1.17.1", "1.18-exp7"); + } + // Experimental 1.19 + case "1.19-exp1" -> { + return List.of("1.18.1"); + } + // April + case "2.0-preview" -> { + return List.of("1.5.1"); + } + case "2.0-blue" -> { + return List.of("1.5.1"); + } + case "2.0-purple" -> { + return List.of("1.5.1"); + } + case "2.0-red" -> { + return List.of("1.5.1"); + } + case "3D Shareware v1.34" -> { + return List.of("19w13b-1653"); + } + case "23w13a_or_b-0722" -> { + return List.of("23w13a"); + } + case "23w13a_or_b-1249" -> { + return List.of("23w13a_or_b-0722"); + } + case "24w14potato-0838" -> { + return List.of("24w12a"); + } + case "24w14potato-1104" -> { + return List.of("24w14potato-0838"); + } + //Beta + case "b1.3-demo" -> { + return List.of("b1.3_01"); + } + case "b1.2_02-dev" -> { + return List.of("b1.2_02"); + } + //Classic + case "c0.30-c-1900-renew" -> { + return List.of("c0.30-c-1900"); + } } + + String launcher_duplicate = this.getLauncherVersionDuplicate(versionId); + if (launcher_duplicate != null) { + return List.of(launcher_duplicate); } return super.getParentVersionIds(versionId); } + + private static final Pattern OMNI_NORMAL_SNAPSHOT_PATTERN = Pattern.compile("(^\\d\\dw\\d\\d[a-z](-\\d+)?$)|(^\\d.\\d+(.\\d+)?(-(pre|rc)(\\d+)?(-\\d+)?)?$)"); + + @Override + protected Pattern getNormalSnapshotPattern() { + return OMNI_NORMAL_SNAPSHOT_PATTERN; + } + + private static final String LAUNCHER_SUFFIX = "-launcher"; + + private String getLauncherVersionDuplicate(String versionId) { + if (versionId.endsWith(LAUNCHER_SUFFIX)) { + String potential_duplicate = versionId.substring(0, versionId.length() - LAUNCHER_SUFFIX.length()); + if (this.getVersionsAssumeLoaded().containsKey(potential_duplicate)) { + return potential_duplicate; + } + } + return null; + } + + @Override + public boolean shouldExcludeFromMainBranch(OrderedVersion mcVersion) { + return super.shouldExcludeFromMainBranch(mcVersion) + // Exclude all april fools snapshots + || mcVersion.isAprilFools() + // Exclude special versions such as combat experiments and b1.3-demo + || (mcVersion.isSpecial() + // Allow special versions which do not branch out + && !GitCraftQuirks.omniarchiveLinearSpecials.contains(mcVersion.launcherFriendlyVersionName())) + // Exclude duplicate versions from launcher + || (this.getLauncherVersionDuplicate(mcVersion.launcherFriendlyVersionName()) != null); + } } diff --git a/src/main/groovy/com/github/winplay02/gitcraft/manifest/skyrising/SkyrisingMetadataProvider.java b/src/main/groovy/com/github/winplay02/gitcraft/manifest/skyrising/SkyrisingMetadataProvider.java index d10834ea..b7444fcd 100644 --- a/src/main/groovy/com/github/winplay02/gitcraft/manifest/skyrising/SkyrisingMetadataProvider.java +++ b/src/main/groovy/com/github/winplay02/gitcraft/manifest/skyrising/SkyrisingMetadataProvider.java @@ -130,17 +130,26 @@ protected boolean isExistingVersionMetadataValid(SkyrisingManifest.VersionEntry @Override public List getParentVersions(OrderedVersion mcVersion) { return this.getVersionDetails(mcVersion.launcherFriendlyVersionName()).previous().stream() + .filter(it -> !isClassicOrAlphaServer(it)) .map(this::getVersionByVersionID) - .filter(Objects::nonNull) + .peek(ver -> { + if (ver == null) { + MiscHelper.panic("One or more of the parent versions were not found for %s", mcVersion.friendlyVersion()); + } + }) .toList(); } - private static final Pattern NORMAL_SNAPSHOT_PATTERN = Pattern.compile("(^\\d\\dw\\d\\d[a-z](-\\d+)?$)|(^\\d.\\d+(.\\d+)?(-(pre|rc)((-\\d+|\\d+)(-\\d+)?)?|_[a-z_\\-]+snapshot-\\d+| Pre-Release \\d+)?$)"); + private static final Pattern NORMAL_SNAPSHOT_PATTERN = Pattern.compile("(^\\d\\dw\\d\\d[a-z](-\\d+)?$)|(^\\d.\\d+(.\\d+)?(-(pre|rc)((-\\d+|\\d+)(-\\d+)?)?| Pre-Release \\d+)?$)"); @Override public boolean shouldExclude(OrderedVersion mcVersion) { // classic and alpha servers don't work well with the version graph right now - return mcVersion.launcherFriendlyVersionName().startsWith("server-"); + return isClassicOrAlphaServer(mcVersion.launcherFriendlyVersionName()); + } + + private static boolean isClassicOrAlphaServer(String versionId) { + return versionId.startsWith("server-"); } @Override diff --git a/src/main/groovy/com/github/winplay02/gitcraft/manifest/vanilla/MojangLauncherMetadataProvider.java b/src/main/groovy/com/github/winplay02/gitcraft/manifest/vanilla/MojangLauncherMetadataProvider.java index d7d78a0b..6378023b 100644 --- a/src/main/groovy/com/github/winplay02/gitcraft/manifest/vanilla/MojangLauncherMetadataProvider.java +++ b/src/main/groovy/com/github/winplay02/gitcraft/manifest/vanilla/MojangLauncherMetadataProvider.java @@ -196,6 +196,8 @@ protected boolean isExistingVersionMetadataValid(MojangLauncherManifest.VersionE // Version Override private static final Map minecraftVersionSemVerOverride = Map.of( + // present in Omniarchive manifest and fabric-loader does not parse it correctly + "2.0-preview", "2.0-preview" // FIX until fabric-loader is updated // END FIX ); @@ -256,7 +258,14 @@ private String fixupSemver(String proposedSemVer) { @Override public List getParentVersions(OrderedVersion mcVersion) { List parentVersionIds = this.getParentVersionIds(mcVersion.friendlyVersion()); - return parentVersionIds == null ? null : parentVersionIds.stream().map(this::getVersionByVersionID).toList(); + return parentVersionIds == null ? null : parentVersionIds.stream() + .map(this::getVersionByVersionID) + .peek(ver -> { + if (ver == null) { + MiscHelper.panic("One or more of the parent versions were not found for %s", mcVersion.friendlyVersion()); + } + }) + .toList(); } protected List getParentVersionIds(String versionId) { @@ -266,22 +275,22 @@ protected List getParentVersionIds(String versionId) { return List.of("1.14.3-pre4"); } case "1.14_combat-0" -> { - return List.of("1.14.4", "1.14_combat-212796"); + return List.of("1.14_combat-212796", "1.14.4"); } case "1.14_combat-3" -> { return List.of("1.14_combat-0"); } case "1.15_combat-1" -> { - return List.of("1.15-pre3", "1.14_combat-3"); + return List.of("1.14_combat-3", "1.15-pre3"); } case "1.15_combat-6" -> { - return List.of("1.15.2-pre2", "1.15_combat-1"); + return List.of("1.15_combat-1", "1.15.2-pre2"); } case "1.16_combat-0" -> { - return List.of("1.16.2-pre3", "1.15_combat-6"); + return List.of("1.15_combat-6", "1.16.2-pre3"); } case "1.16_combat-1" -> { - return List.of("1.16.2", "1.16_combat-0"); + return List.of("1.16_combat-0", "1.16.2"); } case "1.16_combat-2" -> { return List.of("1.16_combat-1"); @@ -300,7 +309,7 @@ protected List getParentVersionIds(String versionId) { } // Experimental 1.18 case "1.18_experimental-snapshot-1" -> { - return List.of("1.17.1"); + return List.of("1.17.1-pre1"); } case "1.18_experimental-snapshot-2" -> { return List.of("1.18_experimental-snapshot-1"); @@ -327,9 +336,6 @@ protected List getParentVersionIds(String versionId) { case "1.19_deep_dark_experimental_snapshot-1" -> { return List.of("1.18.1"); } - case "22w11a" -> { - return List.of("1.18.2", "1.19_deep_dark_experimental_snapshot-1"); - } // April case "15w14a" -> { return List.of("1.8.3"); @@ -344,40 +350,43 @@ protected List getParentVersionIds(String versionId) { return List.of("20w13b"); } case "22w13oneblockatatime" -> { - return List.of("22w13a"); - } - case "23w13a_or_b" -> { - return List.of("23w13a_or_b_original", "23w13a"); + return List.of("1.18.2"); } case "23w13a_or_b_original" -> { return List.of("23w13a"); } - case "24w14potato" -> { - return List.of("24w14potato_original", "24w12a"); + case "23w13a_or_b" -> { + return List.of("23w13a_or_b_original"); } case "24w14potato_original" -> { return List.of("24w12a"); } + case "24w14potato" -> { + return List.of("24w14potato_original"); + } case "25w14craftmine" -> { return List.of("1.21.5"); } - // Special case to make version graph not contain a cycle - case "1.9.2" -> { - return List.of("1.9.1"); - } default -> { return null; } } } - private static final Pattern NORMAL_SNAPSHOT_PATTERN = Pattern.compile("(^\\d\\dw\\d\\d[a-z]$)|(^\\d.\\d+(.\\d+)?(-(pre|rc)\\d+|_[a-z_\\-]+snapshot-\\d+| Pre-Release \\d+)?$)"); + private static final Pattern NORMAL_SNAPSHOT_PATTERN = Pattern.compile("(^\\d\\dw\\d\\d[a-z]$)|(^\\d.\\d+(.\\d+)?(-(pre|rc)\\d+| Pre-Release \\d+)?$)"); + + protected Pattern getNormalSnapshotPattern() { + return NORMAL_SNAPSHOT_PATTERN; + } @Override public boolean shouldExcludeFromMainBranch(OrderedVersion mcVersion) { return super.shouldExcludeFromMainBranch(mcVersion) // filter out april fools snapshots and experimental versions, // which often have typical ids that do not match normal snapshots - || (mcVersion.isSnapshotOrPending() && !NORMAL_SNAPSHOT_PATTERN.matcher(mcVersion.launcherFriendlyVersionName()).matches()); + || (mcVersion.isSnapshotOrPending() + && !this.getNormalSnapshotPattern().matcher(mcVersion.launcherFriendlyVersionName()).matches()) + // Exclude april fools that looks like regular snapshot + || Objects.equals(mcVersion.launcherFriendlyVersionName(), "15w14a"); } } diff --git a/src/main/groovy/com/github/winplay02/gitcraft/types/OrderedVersion.java b/src/main/groovy/com/github/winplay02/gitcraft/types/OrderedVersion.java index 2193e50d..921344ba 100644 --- a/src/main/groovy/com/github/winplay02/gitcraft/types/OrderedVersion.java +++ b/src/main/groovy/com/github/winplay02/gitcraft/types/OrderedVersion.java @@ -113,13 +113,44 @@ public int javaVersion() { } public boolean isSnapshot() { - return Objects.equals(this.versionInfo().type(), "snapshot"); + return Objects.equals(this.versionInfo().type(), "snapshot") + // another special case for snapshots from Omniarchive manifest which are marked as "special" + || (this.isSpecial() && GitCraftQuirks.omniarchiveSpecialSnapshots.contains(this.versionInfo().id())); } + // Can be found in Mojang and Skyrising manifests public boolean isPending() { return Objects.equals(this.versionInfo().type(), "pending"); } + public boolean isOldBeta() { + return Objects.equals(this.versionInfo().type(), "old_beta"); + } + + public boolean isOldAlpha() { + return Objects.equals(this.versionInfo().type(), "old_alpha"); + } + + // Can be found in Skyrising manifest + public boolean isAlphaServer() { + return Objects.equals(this.versionInfo().type(), "alpha_server"); + } + + // Can be found in Skyrising manifest + public boolean isClassicServer() { + return Objects.equals(this.versionInfo().type(), "classic_server"); + } + + // Can be found in Omniarchive manifest + public boolean isSpecial() { + return Objects.equals(this.versionInfo().type(), "special"); + } + + // Can be found in Omniarchive manifest + public boolean isAprilFools() { + return Objects.equals(this.versionInfo().type(), "april-fools"); + } + public boolean isSnapshotOrPending() { return this.isSnapshot() || this.isPending(); } diff --git a/src/test/groovy/com/github/winplay02/gitcraft/GitCraftTest.java b/src/test/groovy/com/github/winplay02/gitcraft/GitCraftTest.java index f87b6f96..bc421acf 100644 --- a/src/test/groovy/com/github/winplay02/gitcraft/GitCraftTest.java +++ b/src/test/groovy/com/github/winplay02/gitcraft/GitCraftTest.java @@ -373,7 +373,7 @@ public void pipeline() throws Exception { } Configuration.reset(); // - GitCraft.main(new String[]{"--only-version=1.17.1,1.18_experimental-snapshot-1,21w37a,1.18,22w13oneblockatatime"}); + GitCraft.main(new String[]{"--only-version=1.17.1-pre1,1.18_experimental-snapshot-1,21w37a,1.18,22w13oneblockatatime"}); try (RepoWrapper repoWrapper = GitCraft.getRepository()) { assertNotNull(repoWrapper); assertNotNull(repoWrapper.getGit().getRepository().getRefDatabase().findRef(GitCraft.getRepositoryConfiguration().gitMainlineLinearBranch())); @@ -383,8 +383,8 @@ public void pipeline() throws Exception { assertEquals(1, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.18"))).getParentCount()); assertEquals(2, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("21w37a"))).getParentCount()); assertEquals(1, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.18_experimental-snapshot-1"))).getParentCount()); - assertEquals(0, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1"))).getParentCount()); - RevCommit targetCommit = Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1"))); + assertEquals(0, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1-pre1"))).getParentCount()); + RevCommit targetCommit = Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1-pre1"))); try (TreeWalk walk = TreeWalk.forPath(repoWrapper.getGit().getRepository(), "minecraft/resources/assets", targetCommit.getTree())) { // assertNotNull(walk); } @@ -567,7 +567,7 @@ public void pipelineOldSnapshotSkyrisingOrnithe() throws Exception { @Test public void pipelineReset() throws Exception { Configuration.reset(); - GitCraft.main(new String[]{"--only-version=1.17.1,1.18_experimental-snapshot-1,21w37a,1.18,22w13oneblockatatime", "--refresh", "--refresh-min-version=1.18"}); + GitCraft.main(new String[]{"--only-version=1.17.1-pre1,1.18_experimental-snapshot-1,21w37a,1.18,22w13oneblockatatime", "--refresh", "--refresh-min-version=1.18"}); try (RepoWrapper repoWrapper = GitCraft.getRepository()) { assertNotNull(repoWrapper); assertNotNull(repoWrapper.getGit().getRepository().getRefDatabase().findRef(GitCraft.getRepositoryConfiguration().gitMainlineLinearBranch())); @@ -577,8 +577,8 @@ public void pipelineReset() throws Exception { assertEquals(1, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.18"))).getParentCount()); assertEquals(2, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("21w37a"))).getParentCount()); assertEquals(1, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.18_experimental-snapshot-1"))).getParentCount()); - assertEquals(0, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1"))).getParentCount()); - RevCommit targetCommit = Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1"))); + assertEquals(0, Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1-pre1"))).getParentCount()); + RevCommit targetCommit = Objects.requireNonNull(findCommit(repoWrapper, GitCraft.versionGraph.getMinecraftVersionByName("1.17.1-pre1"))); try (TreeWalk walk = TreeWalk.forPath(repoWrapper.getGit().getRepository(), "minecraft/resources/assets", targetCommit.getTree())) { // assertNotNull(walk); }