diff --git a/cmd/init.go b/cmd/init.go index 52448c9..d8cdd09 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -3,6 +3,7 @@ package cmd import ( "bufio" "fmt" + "maps" "os" "path/filepath" "slices" @@ -89,7 +90,7 @@ var initCmd = &cobra.Command{ modLoaderVersions := make(map[string]string) if modLoaderName != "none" { if ok { - versions, latestVersion, err := loader.VersionListGetter(mcVersion) + versionData, err := core.DoQuery(core.MakeQuery(loader, mcVersion)) if err != nil { fmt.Printf("Error loading versions: %s\n", err) os.Exit(1) @@ -97,9 +98,9 @@ var initCmd = &cobra.Command{ componentVersion := viper.GetString("init." + loader.Name + "-version") if len(componentVersion) == 0 { if viper.GetBool("init." + loader.Name + "-latest") { - componentVersion = latestVersion + componentVersion = versionData.Latest } else { - componentVersion = initReadValue(loader.FriendlyName+" version ["+latestVersion+"]: ", latestVersion) + componentVersion = initReadValue(loader.FriendlyName+" version ["+versionData.Latest+"]: ", versionData.Latest) } } v := componentVersion @@ -108,7 +109,7 @@ var initCmd = &cobra.Command{ if loader.Name == "forge" || (loader.Name == "neoforge" && mcVersion == "1.20.1") { v = cmdshared.GetRawForgeVersion(componentVersion) } - if !slices.Contains(versions, v) { + if !slices.Contains(versionData.Versions, v) { fmt.Println("Given " + loader.FriendlyName + " version cannot be found!") os.Exit(1) } @@ -116,13 +117,8 @@ var initCmd = &cobra.Command{ } else { fmt.Println("Given mod loader is not supported! Use \"none\" to specify no modloader, or to configure one manually.") fmt.Print("The following mod loaders are supported: ") - keys := make([]string, len(core.ModLoaders)) - i := 0 - for k := range core.ModLoaders { - keys[i] = k - i++ - } - fmt.Println(strings.Join(keys, ", ")) + loader_names := slices.Collect(maps.Keys(core.ModLoaders)) + fmt.Println(strings.Join(loader_names, ", ")) os.Exit(1) } } diff --git a/core/version_test_files/fabric.xml b/core/version_test_files/fabric.xml new file mode 100644 index 0000000..bee0486 --- /dev/null +++ b/core/version_test_files/fabric.xml @@ -0,0 +1,107 @@ + + + net.fabricmc + fabric-loader + + 0.17.3 + 0.17.3 + + 0.1.0.48 + 0.1.0.49 + 0.1.0.50 + 0.1.0.51 + 0.1.0.52 + 0.2.0.53 + 0.2.0.54 + 0.2.0.55 + 0.2.0.56 + 0.2.0.57 + 0.2.0.58 + 0.2.0.59 + 0.2.0.60 + 0.2.0.61 + 0.2.0.62 + 0.3.3.99 + 0.3.3.100 + 0.3.3.101 + 0.3.3.102 + 0.3.7.109 + 0.3.7.110 + 0.3.7.111 + 0.4.0+build.112 + 0.4.0+build.113 + 0.4.0+build.114 + 0.4.0+build.115 + 0.4.0+build.116 + 0.4.1+build.122 + 0.4.1+build.123 + 0.4.1+build.124 + 0.4.1+build.127 + 0.9.1+build.205 + 0.9.2+build.206 + 0.9.3+build.207 + 0.10.0+build.208 + 0.10.1+build.209 + 0.10.2+build.210 + 0.10.5+build.213 + 0.10.6+build.214 + 0.10.7 + 0.10.8 + 0.11.0 + 0.11.1 + 0.11.2 + 0.11.3 + 0.11.5 + 0.12.4 + 0.12.5 + 0.12.6 + 0.12.7 + 0.12.8 + 0.12.9 + 0.12.10 + 0.12.11 + 0.12.12 + 0.13.0 + 0.13.1 + 0.13.2 + 0.13.3 + 0.14.0 + 0.14.4 + 0.14.5 + 0.14.6 + 0.14.7 + 0.14.8 + 0.14.9 + 0.14.10 + 0.14.11 + 0.14.12 + 0.14.13 + 0.14.14 + 0.14.19 + 0.14.20 + 0.14.21 + 0.14.22 + 0.14.23 + 0.14.24 + 0.14.25 + 0.15.0 + 0.15.8 + 0.15.9 + 0.15.10 + 0.15.11 + 0.16.0 + 0.16.1 + 0.16.2 + 0.16.3 + 0.16.11 + 0.16.12 + 0.16.13 + 0.16.14 + 0.17.0 + 0.17.1 + 0.17.2 + 0.17.3 + + 20251009160949 + + diff --git a/core/version_test_files/forge.xml b/core/version_test_files/forge.xml new file mode 100644 index 0000000..b11aea8 --- /dev/null +++ b/core/version_test_files/forge.xml @@ -0,0 +1,290 @@ + + + net.minecraftforge + forge + + 1.21.10-60.0.14 + 1.21.10-60.0.14 + + 1.21-51.0.33 + 1.21-51.0.32 + 1.21-51.0.21 + 1.21-51.0.18 + 1.21-51.0.17 + 1.21-51.0.16 + 1.21-51.0.15 + 1.21-51.0.13 + 1.21-51.0.8 + 1.21-51.0.7 + 1.21-51.0.6 + 1.21-51.0.5 + 1.21-51.0.4 + 1.21-51.0.3 + 1.21-51.0.1 + 1.21-51.0.0 + 1.21.8-58.0.3 + 1.21.8-58.0.2 + 1.21.8-58.0.1 + 1.21.8-58.0.0 + 1.21.7-57.0.3 + 1.21.7-57.0.2 + 1.21.5-55.0.17 + 1.21.1-52.0.0 + 1.20-46.0.14 + 1.20-46.0.11 + 1.20-46.0.10 + 1.20-46.0.2 + 1.20-46.0.1 + 1.20.6-50.2.1 + 1.20.6-50.2.0 + 1.20.6-50.1.51 + 1.19-41.0.98 + 1.19.2-43.2.21 + 1.18.2-40.1.92 + 1.16.1-32.0.10 + 1.16.1-32.0.9 + 1.16.1-32.0.8 + 1.16.1-32.0.7 + 1.16.1-32.0.6 + 1.16.1-32.0.2 + 1.16.1-32.0.1 + 1.15-29.0.4 + 1.15-29.0.3 + 1.15-29.0.2 + 1.15-29.0.1 + 1.15-29.0.0 + 1.15.2-31.2.57 + 1.14.3-27.0.3 + 1.14.3-27.0.2 + 1.14.3-27.0.1 + 1.14.3-27.0.0 + 1.14.2-26.0.63 + 1.14.2-26.0.62 + 1.14.2-26.0.61 + 1.14.2-26.0.60 + 1.12-14.21.0.2324 + 1.12-14.21.0.2323 + 1.12-14.21.0.2322 + 1.12-14.21.0.2320 + 1.12.2-14.23.5.2860 + 1.12.2-14.23.4.2721 + 1.12.2-14.23.4.2720-4627 + 1.12.2-14.23.4.2719 + 1.12.1-14.22.0.2444 + 1.11-13.19.1.2199 + 1.11-13.19.0.2130 + 1.11-13.19.0.2129-1.11.x + 1.11-13.19.0.2128-1.11.x + 1.11-13.19.0.2127-1.11.x + 1.11-13.19.0.2126-1.11.x + 1.11.2-13.20.1.2588 + 1.11.2-13.20.0.2245-3630 + 1.11.2-13.20.0.2244 + 1.11.2-13.20.0.2200 + 1.10-12.18.0.2000-1.10.0 + 1.10-12.18.0.1999-1.10.0 + 1.10-12.18.0.1981-1.10.0 + 1.10.2-12.18.3.2511 + 1.10.2-12.18.3.2488 + 1.10.2-12.18.1.2019 + 1.10.2-12.18.1.2018 + 1.10.2-12.18.1.2017 + 1.10.2-12.18.1.2016-failtests + 1.10.2-12.18.1.2015-failtests + 1.10.2-12.18.1.2014 + 1.10.2-12.18.1.2013 + 1.10.2-12.18.0.2010 + 1.10.2-12.18.0.2009 + 1.10.2-12.18.0.2008 + 1.10.2-12.18.0.2007-1.10.0 + 1.10.2-12.18.0.2001-1.10.0 + 1.9-12.16.1.1938-1.9.0 + 1.9-12.16.1.1934 + 1.9-12.16.0.1886 + 1.9-12.16.0.1885-1.9 + 1.9-12.16.0.1766-1.9 + 1.9.4-12.17.0.2317-1.9.4 + 1.9.4-12.17.0.2051 + 1.9.4-12.17.0.1990 + 1.9.4-12.17.0.1987 + 1.9.4-12.17.0.1976 + 1.9.4-12.17.0.1975 + 1.9.4-12.17.0.1974-1.9.4 + 1.9.4-12.17.0.1973 + 1.9.4-12.17.0.1937 + 1.9.4-12.17.0.1936-1.9.4 + 1.9.4-12.17.0.1935-1.9.4 + 1.9.4-12.17.0.1920-1.9.4 + 1.9.4-12.17.0.1919-EHUnit + 1.9.4-12.17.0.1908-1.9.4 + 1.8-11.14.4.1577 + 1.8-11.14.0.1296 + 1.8-11.14.0.1295-1.8 + 1.8-11.14.0.1237-1.8 + 1.8.9-11.15.1.2318-1.8.9 + 1.8.9-11.15.1.1902-1.8.9 + 1.8.9-11.15.1.1890-1.8.9 + 1.8.9-11.15.1.1875 + 1.8.9-11.15.1.1873 + 1.8.9-11.15.1.1758 + 1.8.9-11.15.1.1757 + 1.8.9-11.15.1.1756 + 1.8.9-11.15.1.1755 + 1.8.9-11.15.0.1657 + 1.8.9-11.15.0.1656 + 1.8.8-11.15.0.1655 + 1.8.8-11.15.0.1654-1.8.8 + 1.8.8-11.15.0.1653-1.8.8 + 1.8.8-11.14.4.1579-1.8.8 + 1.8.8-11.14.4.1576-1.8.8 + 1.8.8-11.14.4.1575-1.8.8 + 1.7.10-10.13.4.1614-1.7.10 + 1.7.10-10.13.3.1406-1.7.10 + 1.7.10-10.13.3.1403-1.7.10 + 1.7.10-10.13.3.1401-1710ls + 1.7.10-10.13.3.1400-1.7.10 + 1.7.10-10.13.3.1399-1.7.10 + 1.7.10-10.13.3.1395-1710ls + 1.7.10-10.13.3.1394-1710ls + 1.7.10-10.13.3.1393-1710ls + 1.7.10-10.13.3.1391-1710ls + 1.7.10-10.13.3.1389-1710ls + 1.7.10-10.13.3.1388-1.7.10 + 1.7.10-10.13.2.1307-1.7.10 + 1.7.10-10.13.2.1300-1.7.10 + 1.7.10-10.13.2.1291 + 1.7.10-10.13.2.1286 + 1.7.10-10.13.2.1284 + 1.7.10-10.13.2.1283 + 1.7.10-10.13.2.1277 + 1.7.10-10.13.2.1276 + 1.7.10-10.13.2.1275 + 1.7.10-10.13.1.1219 + 1.7.10-10.13.1.1217 + 1.7.10-10.13.1.1216-new + 1.7.10-10.13.1.1215-new + 1.7.10-10.13.1.1214-new + 1.7.10-10.13.1.1213-new + 1.7.10-10.13.1.1212-new + 1.7.10-10.13.1.1211-new + 1.7.10-10.13.1.1210-new + 1.7.10-10.13.0.1208 + 1.7.10-10.13.0.1150 + 1.7.2-10.12.2.1161-mc172 + 1.7.2-10.12.2.1155-mc172 + 1.7.2-10.12.2.1154-mc172 + 1.7.2-10.12.2.1147 + 1.7.2-10.12.2.1145 + 1.7.2-10.12.0.1030 + 1.7.2-10.12.0.1029 + 1.7.2-10.12.0.1028 + 1.7.2-10.12.0.1027 + 1.7.2-10.12.0.1026 + 1.7.2-10.12.0.1025 + 1.7.2-10.12.0.1024 + 1.7.2-10.12.0.1023 + 1.7.2-10.12.0.1022 + 1.7.2-10.12.0.1021 + 1.7.2-10.12.0.1020 + 1.7.2-10.12.0.1000 + 1.7.2-10.12.0.999 + 1.7.2-10.12.0.998 + 1.7.10_pre4-10.12.2.1149-prerelease + 1.7.10_pre4-10.12.2.1148-prerelease + 1.7.10_pre4-10.12.2.1146-prerelease + 1.7.10_pre4-10.12.2.1144-prerelease + 1.7.10_pre4-10.12.2.1143-prerelease + 1.7.10_pre4-10.12.2.1142-prerelease + 1.7.10_pre4-10.12.2.1141-prerelease + 1.7.10_pre4-10.12.2.1139-prerelease + 1.7.10_pre4-10.12.2.1138-prerelease + 1.7.10_pre4-10.12.2.1137-prerelease + 1.6.4-9.11.1.1345 + 1.6.4-9.11.1.965 + 1.6.4-9.11.1.964 + 1.6.4-9.11.1.963 + 1.6.4-9.11.1.961 + 1.6.4-9.11.1.960 + 1.6.1-8.9.0.775 + 1.6.1-8.9.0.749 + 1.5-7.7.0.598 + 1.5-7.7.0.565 + 1.5-7.7.0.563 + 1.5-7.7.0.562 + 1.5-7.7.0.561 + 1.5-7.7.0.560 + 1.5-7.7.0.559 + 1.5.2-7.8.1.738 + 1.5.2-7.8.1.737 + 1.5.2-7.8.0.736 + 1.5.2-7.8.0.735 + 1.5.2-7.8.0.734 + 1.5.2-7.8.0.733 + 1.5.2-7.8.0.732 + 1.5.2-7.8.0.731 + 1.5.2-7.8.0.730 + 1.5.2-7.8.0.729 + 1.5.2-7.8.0.728 + 1.5.2-7.8.0.727 + 1.1-1.3.2.3 + 1.1-1.3.2.2 + 1.1-1.3.2.1 + 1.21.8-58.0.4 + 1.21.1-52.1.3 + 1.20.1-47.4.6 + 1.21.8-58.0.5 + 1.19.4-45.4.2 + 1.15.2-31.2.60 + 1.21.8-58.0.6 + 1.21.8-58.0.7 + 1.21.8-58.0.8 + 1.21.8-58.0.9 + 1.21.8-58.0.10 + 1.21.5-55.0.25 + 1.21.5-55.1.0 + 1.21.8-58.1.0 + 1.20.4-49.2.1 + 1.20.1-47.4.8 + 1.21.8-58.1.1 + 1.21.8-58.1.2 + 1.21.8-58.1.3 + 1.21.8-58.1.4 + 1.20.1-47.4.9 + 1.21.5-55.1.1 + 1.21.3-53.1.3 + 1.21.4-54.1.7 + 1.20.6-50.2.2 + 1.20.4-49.2.2 + 1.21.1-52.1.4 + 1.21.8-58.1.6 + 1.21.5-55.1.2 + 1.21.4-54.1.8 + 1.21.3-53.1.4 + 1.21.1-52.1.5 + 1.21.9-59.0.0 + 1.21.9-59.0.1 + 1.21.9-59.0.2 + 1.21.8-58.1.7 + 1.21.9-59.0.3 + 1.21.9-59.0.4 + 1.21.9-59.0.5 + 1.21.10-60.0.0 + 1.20.1-47.4.10 + 1.21.10-60.0.1 + 1.21.10-60.0.3 + 1.21.10-60.0.4 + 1.21.10-60.0.5 + 1.21.10-60.0.6 + 1.21.10-60.0.7 + 1.21.10-60.0.8 + 1.21.10-60.0.9 + 1.21.1-52.1.6 + 1.21.10-60.0.10 + 1.21.10-60.0.11 + 1.21.10-60.0.12 + 1.21.10-60.0.13 + 1.21.10-60.0.14 + + 20251031200755 + + diff --git a/core/version_test_files/liteloader.xml b/core/version_test_files/liteloader.xml new file mode 100644 index 0000000..4411e1c --- /dev/null +++ b/core/version_test_files/liteloader.xml @@ -0,0 +1,23 @@ + + + com.mumfrey + liteloader + + 1.9.4-SNAPSHOT + + + 1.8.9-SNAPSHOT + 1.9-SNAPSHOT + 1.9.4-SNAPSHOT + 1.8-SNAPSHOT + 1.10-SNAPSHOT + 1.10.2-SNAPSHOT + 1.11-SNAPSHOT + 1.11.2-SNAPSHOT + 1.12-SNAPSHOT + 1.12.1-SNAPSHOT + 1.12.2-SNAPSHOT + + 20171128144432 + + diff --git a/core/version_test_files/neoforge.xml b/core/version_test_files/neoforge.xml new file mode 100644 index 0000000..0662a4f --- /dev/null +++ b/core/version_test_files/neoforge.xml @@ -0,0 +1,183 @@ + + + net.neoforged + neoforge + + 21.10.43-beta + 21.10.43-beta + + 21.10.5-beta + 21.10.4-beta + 21.10.3-beta + 21.10.2-beta + 21.10.1-beta + 21.10.0-beta + 21.9.16-beta + 21.9.15-beta + 21.9.14-beta + 21.9.13-beta + 21.9.12-beta + 21.9.11-beta + 21.9.10-beta + 21.9.9-beta + 21.9.8-beta + 21.9.7-beta + 21.9.6-beta + 21.9.5-beta + 21.9.4-beta + 21.9.3-beta + 21.9.2-beta + 21.9.1-beta + 21.9.0-beta + 21.8.47 + 21.8.42 + 21.8.41 + 21.3.1-beta + 21.3.0-beta + 21.2.1-beta + 21.2.0-beta + 21.1.209 + 21.1.208 + 21.1.207 + 21.1.206 + 21.1.205 + 21.1.204 + 21.1.203 + 21.1.202 + 21.1.201 + 21.1.35 + 21.1.34 + 21.1.33 + 21.1.32 + 21.1.31 + 21.1.30 + 21.1.29 + 21.1.28 + 21.1.27 + 21.1.26 + 21.1.25 + 21.1.24 + 21.1.23 + 21.1.22 + 21.1.21 + 21.1.20 + 21.1.19 + 21.1.18 + 21.1.17 + 21.1.16 + 21.1.15 + 21.1.13 + 21.1.12 + 21.1.11 + 21.1.10 + 21.1.9 + 21.1.8 + 21.1.7 + 21.1.6 + 21.1.1 + 21.0.167 + 21.0.143 + 21.0.142-beta + 21.0.138-beta + 21.0.102-beta + 21.0.100-beta + 21.0.99-beta + 21.0.92-beta + 21.0.91-beta + 21.0.90-beta + 21.0.89-beta + 21.0.41-beta + 21.0.40-beta + 21.0.39-beta + 21.0.2-beta + 21.0.1-beta + 21.0.0-beta + 20.6.138 + 20.6.115 + 20.6.114-beta + 20.6.80-beta + 20.6.79-beta + 20.6.11-beta + 20.6.10-beta + 20.6.9-beta + 20.6.8-beta + 20.5.10-beta + 20.5.9-beta + 20.5.8-beta + 20.5.7-beta + 20.5.6-beta + 20.5.5-beta + 20.5.4-beta + 20.5.3-beta + 20.5.2-beta + 20.5.1-beta + 20.5.0-beta + 20.4.250 + 20.4.249 + 20.4.167 + 20.4.166-beta + 20.4.95-beta + 20.4.44-beta + 20.3.1-beta + 20.2.93 + 20.2.92 + 20.2.91 + 20.2.90 + 20.2.89 + 20.2.88 + 20.2.86 + 20.2.85-beta + 20.2.59-beta + 20.2.30-beta + 20.2.29-beta + 20.2.8-beta + 20.2.6-beta + 20.2.5-beta + 20.2.4-beta + 20.2.3-beta + 0.25w14craftmine.5-beta + 0.25w14craftmine.4-beta + 0.25w14craftmine.3-beta + 21.10.6-beta + 21.4.155 + 21.10.7-beta + 21.10.8-beta + 21.10.9-beta + 21.10.10-beta + 21.1.210 + 21.10.11-beta + 21.10.12-beta + 21.10.13-beta + 21.10.14-beta + 21.10.15-beta + 21.1.211 + 21.10.16-beta + 21.10.17-beta + 21.10.18-beta + 21.10.19-beta + 21.10.20-beta + 21.10.21-beta + 21.10.22-beta + 21.10.23-beta + 21.10.24-beta + 21.10.25-beta + 21.1.212 + 21.8.48 + 21.10.28-beta + 21.10.29-beta + 21.1.213 + 20.4.251 + 20.6.139 + 21.3.94 + 21.10.30-beta + 21.10.31-beta + 21.10.32-beta + 21.10.33-beta + 21.8.49 + 21.10.34-beta + 21.10.42-beta + 21.10.43-beta + + 20251101100329 + + diff --git a/core/version_test_files/neoforge_old.xml b/core/version_test_files/neoforge_old.xml new file mode 100644 index 0000000..9969f7e --- /dev/null +++ b/core/version_test_files/neoforge_old.xml @@ -0,0 +1,75 @@ + + + net.neoforged + forge + + 1.20.1-47.1.106 + 1.20.1-47.1.106 + + 1.20.1-47.1.7 + 1.20.1-47.1.5 + 1.20.1-47.1.8 + 1.20.1-47.1.9 + 1.20.1-47.1.11 + 1.20.1-47.1.12 + 1.20.1-47.1.23 + 1.20.1-47.1.25 + 1.20.1-47.1.26 + 1.20.1-47.1.27 + 1.20.1-47.1.28 + 1.20.1-47.1.54 + 1.20.1-47.1.55 + 1.20.1-47.1.56 + 1.20.1-47.1.57 + 1.20.1-47.1.58 + 1.20.1-47.1.59 + 1.20.1-47.1.60 + 1.20.1-47.1.61 + 1.20.1-47.1.62 + 1.20.1-47.1.63 + 1.20.1-47.1.64 + 1.20.1-47.1.65 + 1.20.1-47.1.66 + 1.20.1-47.1.67 + 1.20.1-47.1.69 + 1.20.1-47.1.70 + 1.20.1-47.1.71 + 1.20.1-47.1.72 + 1.20.1-47.1.73 + 1.20.1-47.1.74 + 1.20.1-47.1.75 + 1.20.1-47.1.76 + 1.20.1-47.1.77 + 1.20.1-47.1.78 + 1.20.1-47.1.79 + 1.20.1-47.1.80 + 1.20.1-47.1.81 + 47.1.82 + 1.20.1-47.1.83 + 1.20.1-47.1.84 + 1.20.1-47.1.85 + 1.20.1-47.1.86 + 1.20.1-47.1.87 + 1.20.1-47.1.88 + 1.20.1-47.1.90 + 1.20.1-47.1.91 + 1.20.1-47.1.89 + 1.20.1-47.1.92 + 1.20.1-47.1.93 + 1.20.1-47.1.94 + 1.20.1-47.1.95 + 1.20.1-47.1.96 + 1.20.1-47.1.97 + 1.20.1-47.1.98 + 1.20.1-47.1.99 + 1.20.1-47.1.100 + 1.20.1-47.1.101 + 1.20.1-47.1.102 + 1.20.1-47.1.103 + 1.20.1-47.1.104 + 1.20.1-47.1.105 + 1.20.1-47.1.106 + + 20240528174429 + + diff --git a/core/version_test_files/quilt.xml b/core/version_test_files/quilt.xml new file mode 100644 index 0000000..fec0013 --- /dev/null +++ b/core/version_test_files/quilt.xml @@ -0,0 +1,73 @@ + + + org.quiltmc + quilt-loader + + 0.29.3-beta.1 + 0.29.3-beta.1 + + 0.16.0-beta.1 + 0.16.0-beta.2 + 0.16.0-beta.3 + 0.16.0-beta.5 + 0.16.0-beta.6 + 0.16.0-beta.7 + 0.16.0-beta.8 + 0.16.0-beta.9 + 0.18.1-beta.18 + 0.18.1-beta.19 + 0.17.7 + 0.18.1-beta.20 + 0.18.1-beta.21 + 0.18.1-beta.77 + 0.18.1-beta.78 + 0.18.1-beta.79 + 0.18.1 + 0.18.2 + 0.18.3-pre.1 + 0.18.3-pre.2 + 0.18.3 + 0.18.4-pre.1 + 0.18.4-pre.2 + 0.18.4-pre.3 + 0.18.4 + 0.18.5 + 0.19.0-beta.1 + 0.18.6-beta.1 + 0.19.0-beta.2 + 0.18.6 + 0.19.0-beta.3 + 0.18.7 + 0.19.0-beta.4 + 0.18.9 + 0.18.10 + 0.19.0-beta.12 + 0.19.0-beta.13 + 0.19.0-beta.16 + 0.19.3-beta.1 + 0.20.0-beta.4 + 0.20.0-beta.5 + 0.20.0-beta.6 + 0.20.0-beta.7 + 0.20.0-beta.8 + 0.20.0-beta.9 + 0.20.0-beta.10 + 0.20.0-beta.11 + 0.29.0-beta.4 + 0.29.0-beta.5 + 0.29.0-beta.6 + 0.29.0-beta.7 + 0.29.0-beta.8 + 0.29.0 + 0.29.1-beta.1 + 0.29.1 + 0.29.2-beta.1 + 0.29.2-beta.2 + 0.29.2-beta.4 + 0.29.2-beta.5 + 0.29.2 + 0.29.3-beta.1 + + 20251025205845 + + diff --git a/core/versionutil.go b/core/versionutil.go index d9dcd46..3a54a54 100644 --- a/core/versionutil.go +++ b/core/versionutil.go @@ -24,167 +24,248 @@ type MavenMetadata struct { } `xml:"versioning"` } -type ModLoaderComponent struct { - Name string - FriendlyName string - VersionListGetter func(mcVersion string) ([]string, string, error) +type ModLoaderVersions struct { + // All Versions of this modloader + Versions []string + // The Latest/preferred version for this modloader + Latest string } -var ModLoaders = map[string]ModLoaderComponent{ - "fabric": { +type ModLoaderComponent struct { + // An identifier for the modloader + Name string + // A user-friendly name + FriendlyName string + // Retrieves the list of all modloader versions. Modloader versions are always filtered to those compatible + // with a specific minecraft version. + VersionListGetter func(q VersionListQuery) (*ModLoaderVersions, error) +} + +var modLoadersList = []ModLoaderComponent{ + { // There's no need to specify yarn version - yarn isn't used outside a dev environment, and intermediary corresponds to game version anyway - Name: "fabric", - FriendlyName: "Fabric loader", - VersionListGetter: FetchMavenVersionList("https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml"), + Name: "fabric", + FriendlyName: "Fabric loader", + VersionListGetter: func(q VersionListQuery) (*ModLoaderVersions, error) { + // Fabric loaders isn't locked to a mc version per se + return fetchVersionsFromMaven(q, "https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml") + }, }, - "forge": { + { Name: "forge", FriendlyName: "Forge", - VersionListGetter: FetchMavenVersionPrefixedListStrip("https://files.minecraftforge.net/maven/net/minecraftforge/forge/maven-metadata.xml", "Forge"), + VersionListGetter: fetchForForge, }, - "liteloader": { - Name: "liteloader", - FriendlyName: "LiteLoader", - VersionListGetter: FetchMavenVersionPrefixedList("https://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/maven-metadata.xml", "LiteLoader"), + { + Name: "liteloader", + FriendlyName: "LiteLoader", + VersionListGetter: func(q VersionListQuery) (*ModLoaderVersions, error) { + return fetchLiteloaderStyle(q, "https://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/maven-metadata.xml") + }, }, - "quilt": { - Name: "quilt", - FriendlyName: "Quilt loader", - VersionListGetter: FetchMavenVersionList("https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-loader/maven-metadata.xml"), + { + Name: "quilt", + FriendlyName: "Quilt loader", + VersionListGetter: func(q VersionListQuery) (*ModLoaderVersions, error) { + return fetchVersionsFromMaven(q, "https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-loader/maven-metadata.xml") + }, }, - "neoforge": { + { Name: "neoforge", FriendlyName: "NeoForge", - VersionListGetter: FetchNeoForge(), + VersionListGetter: fetchForNeoForge, }, } -func FetchMavenVersionList(url string) func(mcVersion string) ([]string, string, error) { - return func(mcVersion string) ([]string, string, error) { - res, err := GetWithUA(url, "application/xml") - if err != nil { - return []string{}, "", err - } - dec := xml.NewDecoder(res.Body) - out := MavenMetadata{} - err = dec.Decode(&out) - if err != nil { - return []string{}, "", err - } - return out.Versioning.Versions.Version, out.Versioning.Release, nil +// A map containing information about all supported modloaders. +// Can be indexed by the [ModLoaderComponent]'s name, which serves as an identifier. +var ModLoaders = createModloaderMap(modLoadersList) + +func createModloaderMap(input []ModLoaderComponent) map[string]ModLoaderComponent { + var mlMap = make(map[string]ModLoaderComponent) + for _, loader := range input { + mlMap[loader.Name] = loader + } + return mlMap +} + +type QueryType int + +const ( + // The Latest field will contain the last released loader version + Latest QueryType = iota + // The Latest field will contain the loader version recommended for use + Recommended +) + +type VersionListQuery struct { + // Which loader to query versions for + Loader ModLoaderComponent + // Which minecraft version the returned loader versions should be compatible with + McVersion string + // Determines how the latest version is determined + QueryType QueryType +} + +func MakeQuery(loader ModLoaderComponent, mcVersion string) VersionListQuery { + return VersionListQuery{ + Loader: loader, + McVersion: mcVersion, + QueryType: Latest, } } -func FetchMavenVersionFiltered(url string, friendlyName string, filter func(version string, mcVersion string) bool) func(mcVersion string) ([]string, string, error) { - return func(mcVersion string) ([]string, string, error) { - res, err := GetWithUA(url, "application/xml") - if err != nil { - return []string{}, "", err - } - dec := xml.NewDecoder(res.Body) - out := MavenMetadata{} - err = dec.Decode(&out) - if err != nil { - return []string{}, "", err - } - allowedVersions := make([]string, 0, len(out.Versioning.Versions.Version)) - for _, v := range out.Versioning.Versions.Version { - if filter(v, mcVersion) { - allowedVersions = append(allowedVersions, v) - } - } - if len(allowedVersions) == 0 { - return []string{}, "", errors.New("no " + friendlyName + " versions available for this Minecraft version") - } - if filter(out.Versioning.Release, mcVersion) { - return allowedVersions, out.Versioning.Release, nil - } - if filter(out.Versioning.Latest, mcVersion) { - return allowedVersions, out.Versioning.Latest, nil - } - // Sort list to get largest version - flexver.VersionSlice(allowedVersions).Sort() - return allowedVersions, allowedVersions[len(allowedVersions)-1], nil +func (in VersionListQuery) WithQueryType(queryType QueryType) VersionListQuery { + return VersionListQuery{ + Loader: in.Loader, + McVersion: in.McVersion, + QueryType: queryType, } } -func FetchMavenVersionPrefixedList(url string, friendlyName string) func(mcVersion string) ([]string, string, error) { - return FetchMavenVersionFiltered(url, friendlyName, hasPrefixSplitDash) +// Queries the versions of a modloader +func DoQuery(q VersionListQuery) (*ModLoaderVersions, error) { + return q.Loader.VersionListGetter(q) } -func FetchMavenVersionPrefixedListStrip(url string, friendlyName string) func(mcVersion string) ([]string, string, error) { - noStrip := FetchMavenVersionPrefixedList(url, friendlyName) - return func(mcVersion string) ([]string, string, error) { - versions, latestVersion, err := noStrip(mcVersion) - if err != nil { - return nil, "", err - } - for k, v := range versions { - versions[k] = removeMcVersion(v, mcVersion) - } - latestVersion = removeMcVersion(latestVersion, mcVersion) - return versions, latestVersion, nil - } +// Retrieve a list of versions from maven, with no filtering or processing of the maven data +func fetchVersionsFromMaven(q VersionListQuery, url string) (*ModLoaderVersions, error) { + identity_function := func(version string) *string { return &version } + return fetchMavenWithFilterMap(q, url, identity_function) } -func removeMcVersion(str string, mcVersion string) string { - components := strings.Split(str, "-") - newComponents := make([]string, 0) - for _, v := range components { - if v != mcVersion { - newComponents = append(newComponents, v) +func fetchForgeStyle(q VersionListQuery, url string) (*ModLoaderVersions, error) { + // Forge style: + // each version is formatted like `mcVersion-forgeVersion` + // eg: `1.18.1-39.0.18` + return fetchMavenWithFilterMap(q, url, func(version string) *string { + before, after, f := strings.Cut(version, "-") + if !f { + // The version didn't have a dash? Lets just reject it entirely + return nil } - } - return strings.Join(newComponents, "-") -} - -func hasPrefixSplitDash(str string, prefix string) bool { - components := strings.Split(str, "-") - if len(components) > 1 && components[0] == prefix { - return true - } - return false -} - -func FetchNeoForge() func(mcVersion string) ([]string, string, error) { - // NeoForge reused Forge's versioning scheme for 1.20.1, but moved to their own versioning scheme for 1.20.2 and above - neoforgeOld := FetchMavenVersionPrefixedListStrip("https://maven.neoforged.net/releases/net/neoforged/forge/maven-metadata.xml", "NeoForge") - neoforgeNew := FetchMavenWithNeoForgeStyleVersions("https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml", "NeoForge") - - return func(mcVersion string) ([]string, string, error) { - if mcVersion == "1.20.1" { - return neoforgeOld(mcVersion) - } else { - return neoforgeNew(mcVersion) + if before != q.McVersion { + // The part before the dash should match the mc version we're looking for + return nil } - } -} - -func FetchMavenWithNeoForgeStyleVersions(url string, friendlyName string) func(mcVersion string) ([]string, string, error) { - return FetchMavenVersionFiltered(url, friendlyName, func(neoforgeVersion string, mcVersion string) bool { - // Minecraft versions are in the form of 1.a.b - // Neoforge versions are in the form of a.b.x - // Eg, for minecraft 1.20.6, neoforge version 20.6.2 and 20.6.83-beta would both be valid versions - // for minecraft 1.20.2, neoforge version 20.2.23-beta - // for minecraft 1.21, neoforge version 21.0.143 would be valid - var mcSplit = strings.Split(mcVersion, ".") - if len(mcSplit) < 2 { - // This does not appear to be a minecraft version that's formatted in a way that matches neoforge - return false - } - var mcMajor = mcSplit[1] - var mcMinor = "0" - if len(mcSplit) > 2 { - mcMinor = mcSplit[2] - } - - // We can only accept an exact version number match, because otherwise 1.21.1 would pull in loader versions for 1.21.10. - var requiredPrefix = mcMajor + "." + mcMinor + "." - - return strings.HasPrefix(neoforgeVersion, requiredPrefix) + // The part after the dash is the actual version, and the part we care about + return &after }) } +func fetchNeoForgeStyle(q VersionListQuery, url string) (*ModLoaderVersions, error) { + // NeoForge style: + // If minecraft versions are in the form of 1.a.b, then neoforge versions are in the form of a.b.x + // Eg, for minecraft 1.20.6, neoforge version 20.6.2 and 20.6.83-beta would both be valid versions + // for minecraft 1.20.2, neoforge version 20.2.23-beta + // for minecraft 1.21, neoforge version 21.0.143 would be valid + + var mcSplit = strings.Split(q.McVersion, ".") + if len(mcSplit) < 2 { + // This does not appear to be a minecraft version that's formatted in a way that matches neoforge + return nil, fmt.Errorf("packwiz cannot detect compatible %s versions for this Minecraft version (%s)", q.Loader.FriendlyName, q.McVersion) + } + var mcMajor = mcSplit[1] + var mcMinor = "0" + if len(mcSplit) > 2 { + mcMinor = mcSplit[2] + } + // Note that the period at the end is significant, we don't want to match `21.10.43` as being for 1.21.1 (instead of 1.21.10) + var requiredPrefix = mcMajor + "." + mcMinor + "." + + return fetchMavenWithFilterMap(q, url, func(version string) *string { + if !strings.HasPrefix(version, requiredPrefix) { + // Reject NeoForge versions that don't have the right prefix for this mc version + return nil + } + return &version + }) +} + +func fetchLiteloaderStyle(q VersionListQuery, url string) (*ModLoaderVersions, error) { + // Liteloader style: + // each version is formatted like `mcVersion-SNAPSHOT` + // eg: `1.12.2-SNAPSHOT` + // (yes, it appears like liteloader only has a single version per mc version) + return fetchMavenWithFilterMap(q, url, func(version string) *string { + before, _, f := strings.Cut(version, "-") + // Check if the part before the dash matches the mc version we're looking for + if f && before == q.McVersion { + return &version + } else { + return nil + } + }) +} + +// Retrieves all versions through maven metadata, and then processes the using the provided `filterMap` function. +// When `filterMap` returns a string, the version will be renamed to the provided string. If `nil` is returned, the +// version is marked as invalid and will not be considered in the result. +func fetchMavenWithFilterMap(q VersionListQuery, url string, filterMap func(version string) *string) (*ModLoaderVersions, error) { + res, err := GetWithUA(url, "application/xml") + if err != nil { + return nil, err + } + dec := xml.NewDecoder(res.Body) + out := MavenMetadata{} + err = dec.Decode(&out) + if err != nil { + return nil, err + } + + // Pass all of the versions listed in the maven through our filterMap + versions := make([]string, 0, len(out.Versioning.Versions.Version)) + for _, v := range out.Versioning.Versions.Version { + mappedV := filterMap(v) + if mappedV != nil { + versions = append(versions, *mappedV) + } + } + + if len(versions) == 0 { + return nil, errors.New("no " + q.Loader.FriendlyName + " versions available for " + q.McVersion) + } + + // Determine the latest release + var latestRelease = "" + release := filterMap(out.Versioning.Release) + latest := filterMap(out.Versioning.Latest) + if release != nil { + latestRelease = *release + } else if latest != nil { + latestRelease = *latest + } else { + // Maven was useless, just rely on flexver sorting + flexver.VersionSlice(versions).Sort() + latestRelease = versions[len(versions)-1] + } + return &ModLoaderVersions{versions, latestRelease}, nil +} + +func fetchForNeoForge(q VersionListQuery) (*ModLoaderVersions, error) { + // NeoForge reused Forge's versioning scheme for 1.20.1, but moved to their own versioning scheme for 1.20.2 and above + if q.McVersion == "1.20.1" { + return fetchForgeStyle(q, "https://maven.neoforged.net/releases/net/neoforged/forge/maven-metadata.xml") + } else { + return fetchNeoForgeStyle(q, "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml") + } +} + +func fetchForForge(q VersionListQuery) (*ModLoaderVersions, error) { + result, err := fetchForgeStyle(q, "https://files.minecraftforge.net/maven/net/minecraftforge/forge/maven-metadata.xml") + if err != nil { + return nil, err + } + // Forge is the only loader which defines a special recommended version + if q.QueryType == Recommended { + recommended := getForgeRecommended(q) + if recommended != "" { + result.Latest = recommended + } + } + return result, nil +} + func ComponentToFriendlyName(component string) string { if component == "minecraft" { return "Minecraft" @@ -215,8 +296,8 @@ type ForgeRecommended struct { Versions map[string]string `json:"promos"` } -// GetForgeRecommended gets the recommended version of Forge for the given Minecraft version -func GetForgeRecommended(mcVersion string) string { +// getForgeRecommended gets the recommended version of Forge for the given Minecraft version +func getForgeRecommended(q VersionListQuery) string { res, err := GetWithUA("https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json", "application/json") if err != nil { return "" @@ -230,11 +311,11 @@ func GetForgeRecommended(mcVersion string) string { } // Get mcVersion-recommended, if it doesn't exist then get mcVersion-latest // If neither exist, return empty string - recommendedString := fmt.Sprintf("%s-recommended", mcVersion) + recommendedString := fmt.Sprintf("%s-recommended", q.McVersion) if out.Versions[recommendedString] != "" { return out.Versions[recommendedString] } - latestString := fmt.Sprintf("%s-latest", mcVersion) + latestString := fmt.Sprintf("%s-latest", q.McVersion) if out.Versions[latestString] != "" { return out.Versions[latestString] } diff --git a/core/versionutil_test.go b/core/versionutil_test.go new file mode 100644 index 0000000..c40db5c --- /dev/null +++ b/core/versionutil_test.go @@ -0,0 +1,129 @@ +package core + +import ( + "embed" + "os" + "slices" + "strings" + "testing" + + "github.com/jarcoal/httpmock" +) + +// For reproducability, we store a list of sample xml files for various endpoints +// these have been edited slightly to cut down on the number of entries, but are +// otherwise taken from the endpoints themselves + +//go:embed version_test_files/* +var versionTestFiles embed.FS + +func registerMock(url string, filename string) { + bytes, err := versionTestFiles.ReadFile("version_test_files/" + filename) + if err != nil { + println("Error " + filename + " not in version_test_files/") + os.Exit(1) + } + httpmock.RegisterResponder("GET", url, httpmock.NewBytesResponder(200, bytes)) +} + +func queryWithMock(t *testing.T, q VersionListQuery) *ModLoaderVersions { + httpmock.Activate(t) + + registerMock("https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml", "fabric.xml") + registerMock("https://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/maven-metadata.xml", "liteloader.xml") + registerMock("https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-loader/maven-metadata.xml", "quilt.xml") + registerMock("https://files.minecraftforge.net/maven/net/minecraftforge/forge/maven-metadata.xml", "forge.xml") + registerMock("https://maven.neoforged.net/releases/net/neoforged/forge/maven-metadata.xml", "neoforge_old.xml") + registerMock("https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml", "neoforge.xml") + + versionData, err := DoQuery(q) + + if err != nil { + t.Logf("Error fetching versions for %s: %s", q.Loader.FriendlyName, err) + if strings.Contains(err.Error(), "no responder found") { + t.Log("You likely need to register a mock for this url") + } + t.FailNow() + } + + return versionData +} + +func expectLatest(t *testing.T, loader string, version string, expectedLatest string) string { + loaderData, ok := ModLoaders[loader] + if !ok { + t.Fatal("Could not find loader") + } + versionData := queryWithMock(t, MakeQuery(loaderData, version)) + + if len(versionData.Versions) == 0 { + t.Error("There should be at least one version") + } + if versionData.Latest != expectedLatest { + t.Errorf("Expected latest version to be %s, found %s", expectedLatest, versionData.Latest) + } + + return versionData.Latest +} + +func expectValid(t *testing.T, loader string, version string, expectedValid string) { + loaderData, ok := ModLoaders[loader] + if !ok { + t.Fatal("Could not find loader") + } + versionData := queryWithMock(t, MakeQuery(loaderData, version)) + + if !slices.Contains(versionData.Versions, expectedValid) { + t.Errorf("Expected %s to be a valid version for %s. Valid versions:\n%s", expectedValid, loaderData.FriendlyName, versionData.Versions) + } +} + +func expectInvalid(t *testing.T, loader string, version string, expectedValid string) { + loaderData, ok := ModLoaders[loader] + if !ok { + t.Fatal("Could not find loader") + } + versionData := queryWithMock(t, MakeQuery(loaderData, version)) + + if slices.Contains(versionData.Versions, expectedValid) { + t.Errorf("Expected %s not to be a valid version for %s. Valid versions:\n%s", expectedValid, loaderData.FriendlyName, versionData.Versions) + } +} + +func TestFabric121(t *testing.T) { + expectLatest(t, "fabric", "1.21", "0.17.3") +} + +func TestFabric010Valid(t *testing.T) { + expectValid(t, "fabric", "1.21", "0.10.6+build.214") +} + +func TestQuilt121(t *testing.T) { + expectLatest(t, "quilt", "1.21", "0.29.3-beta.1") +} + +func TestForge121(t *testing.T) { + expectLatest(t, "forge", "1.21", "51.0.33") +} + +func TestLiteLoader112(t *testing.T) { + expectLatest(t, "liteloader", "1.12", "1.12-SNAPSHOT") +} + +func TestNeoForge1201(t *testing.T) { + expectLatest(t, "neoforge", "1.20.1", "47.1.106") +} + +func TestNeoForge121(t *testing.T) { + expectLatest(t, "neoforge", "1.21", "21.0.167") +} + +func TestNeoForge1211(t *testing.T) { + expectLatest(t, "neoforge", "1.21.1", "21.1.213") + expectValid(t, "neoforge", "1.21.1", "21.1.201") + expectInvalid(t, "neoforge", "1.21.1", "21.10.43-beta") +} + +func TestNeoForge1210(t *testing.T) { + expectLatest(t, "neoforge", "1.21.10", "21.10.43-beta") +} diff --git a/go.mod b/go.mod index 8fcb8e4..5c431d2 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jarcoal/httpmock v1.4.1 github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect diff --git a/go.sum b/go.sum index 1e4dc76..22fe0e0 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac h1:AfRcPFr4 github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac/go.mod h1:KOzUkqpWM2xArNm82cehGc5PBFYV1Qadzzt81aJi7F0= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A= +github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= diff --git a/migrate/loader.go b/migrate/loader.go index b068498..3b6bdf1 100644 --- a/migrate/loader.go +++ b/migrate/loader.go @@ -40,12 +40,18 @@ var loaderCommand = &cobra.Command{ fmt.Printf("Error getting Minecraft version: %s\n", err) os.Exit(1) } - if args[0] == "latest" { - fmt.Println("Updating to latest loader version") + if args[0] == "latest" || args[0] == "recommended" { + fmt.Printf("Updating to %s loader version\n", args[0]) + + queryType := core.Latest + if args[0] == "recommended" { + queryType = core.Recommended + } + // We'll be updating to the latest loader version for _, loader := range currentLoaders { - _, latest, gottenLoader := getVersionsForLoader(loader, mcVersion) - if !updatePackToVersion(latest, modpack, gottenLoader) { + versionData, gottenLoader := getVersionsForLoader(loader, mcVersion, queryType) + if !updatePackToVersion(versionData.Latest, modpack, gottenLoader) { continue } // Write the pack to disk @@ -55,36 +61,14 @@ var loaderCommand = &cobra.Command{ continue } } - } else if args[0] == "recommended" { - // TODO: Figure out a way to get the recommended version, this is Forge only - // Ensure we're on Forge - if !slices.Contains(currentLoaders, "forge") { - fmt.Println("The recommended loader version is only available on Forge!") - os.Exit(1) - } - // We'll be updating to the recommended loader version - recommendedVer := core.GetForgeRecommended(mcVersion) - if recommendedVer == "" { - fmt.Println("Error getting recommended Forge version!") - os.Exit(1) - } - if ok := updatePackToVersion(recommendedVer, modpack, core.ModLoaders["forge"]); !ok { - os.Exit(1) - } - // Write the pack to disk - err = modpack.Write() - if err != nil { - fmt.Printf("Error writing pack.toml: %s", err) - os.Exit(1) - } } else { fmt.Println("Updating to explicit loader version") // This one is easy :D - versions, _, loader := getVersionsForLoader(currentLoaders[0], mcVersion) + versionData, loader := getVersionsForLoader(currentLoaders[0], mcVersion, core.Latest) // Check if the loader happens to be Forge/NeoForge, since there's two version formats if loader.Name == "forge" || loader.Name == "neoforge" { wantedVersion := cmdshared.GetRawForgeVersion(args[0]) - validateVersion(versions, wantedVersion, loader) + validateVersion(versionData.Versions, wantedVersion, loader) _ = updatePackToVersion(wantedVersion, modpack, loader) } else if loader.Name == "liteloader" { // These are weird and just have a MC version @@ -92,7 +76,7 @@ var loaderCommand = &cobra.Command{ os.Exit(0) } else { // We're on Fabric or quilt - validateVersion(versions, args[0], loader) + validateVersion(versionData.Versions, args[0], loader) if ok := updatePackToVersion(args[0], modpack, loader); !ok { os.Exit(1) } @@ -111,18 +95,18 @@ func init() { migrateCmd.AddCommand(loaderCommand) } -func getVersionsForLoader(loader, mcVersion string) ([]string, string, core.ModLoaderComponent) { +func getVersionsForLoader(loader, mcVersion string, queryType core.QueryType) (*core.ModLoaderVersions, core.ModLoaderComponent) { gottenLoader, ok := core.ModLoaders[loader] if !ok { fmt.Printf("Unknown loader %s\n", loader) os.Exit(1) } - versions, latestVersion, err := gottenLoader.VersionListGetter(mcVersion) + versionData, err := core.DoQuery(core.MakeQuery(gottenLoader, mcVersion).WithQueryType(queryType)) if err != nil { fmt.Printf("Error getting version list for %s: %s\n", gottenLoader.FriendlyName, err) os.Exit(1) } - return versions, latestVersion, gottenLoader + return versionData, gottenLoader } func validateVersion(versions []string, version string, gottenLoader core.ModLoaderComponent) {