packwiz/migrate/loader.go
comp500 4c23e264b0 Clean up code, filter version numbers for NeoForge as well as Forge
NeoForge doesn't seem to have an update checker JSON yet, so we can't determine
the recommended version
2023-07-30 15:09:18 +01:00

145 lines
4.6 KiB
Go

package migrate
import (
"fmt"
"github.com/packwiz/packwiz/cmdshared"
"github.com/packwiz/packwiz/core"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"os"
)
var loaderCommand = &cobra.Command{
Use: "loader [version|latest|recommended]",
Short: "Migrate your modloader version to a newer version.",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
modpack, err := core.LoadPack()
if err != nil {
// Check if it's a no such file or directory error
if os.IsNotExist(err) {
fmt.Println("No pack.toml file found, run 'packwiz init' to create one!")
os.Exit(1)
}
fmt.Printf("Error loading pack: %s\n", err)
os.Exit(1)
}
var currentLoaders = modpack.GetLoaders()
// Do some sanity checks on the current loader slice
if len(currentLoaders) == 0 {
fmt.Println("No loader is currently set in your pack.toml!")
os.Exit(1)
} else if len(currentLoaders) > 1 {
fmt.Println("You have multiple loaders set in your pack.toml, this is not supported!")
os.Exit(1)
}
// Get the Minecraft version for the pack
mcVersion, err := modpack.GetMCVersion()
if err != nil {
fmt.Printf("Error getting Minecraft version: %s\n", err)
os.Exit(1)
}
if args[0] == "latest" {
fmt.Println("Updating to latest loader version")
// We'll be updating to the latest loader version
for _, loader := range currentLoaders {
_, latest, gottenLoader := getVersionsForLoader(loader, mcVersion)
if !updatePackToVersion(latest, modpack, gottenLoader) {
continue
}
// Write the pack to disk
err = modpack.Write()
if err != nil {
fmt.Printf("Error writing pack.toml: %s\n", err)
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)
// 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)
_ = updatePackToVersion(wantedVersion, modpack, loader)
} else if loader.Name == "liteloader" {
// These are weird and just have a MC version
fmt.Println("LiteLoader only has 1 version per Minecraft version so we're unable to update!")
os.Exit(0)
} else {
// We're on Fabric or quilt
validateVersion(versions, args[0], loader)
if ok := updatePackToVersion(args[0], modpack, loader); !ok {
os.Exit(1)
}
}
// Write the pack to disk
err = modpack.Write()
if err != nil {
fmt.Printf("Error writing pack.toml: %s\n", err)
os.Exit(1)
}
}
},
}
func init() {
migrateCmd.AddCommand(loaderCommand)
}
func getVersionsForLoader(loader, mcVersion string) ([]string, string, 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)
if err != nil {
fmt.Printf("Error getting version list for %s: %s\n", gottenLoader.FriendlyName, err)
os.Exit(1)
}
return versions, latestVersion, gottenLoader
}
func validateVersion(versions []string, version string, gottenLoader core.ModLoaderComponent) {
if !slices.Contains(versions, version) {
fmt.Printf("Version %s is not a valid version for %s\n", version, gottenLoader.FriendlyName)
os.Exit(1)
}
}
func updatePackToVersion(version string, modpack core.Pack, loader core.ModLoaderComponent) bool {
// Check if the version is already set
if version == modpack.Versions[loader.Name] {
fmt.Printf("%s is already on version %s!\n", loader.FriendlyName, version)
return false
}
// Set the latest version
modpack.Versions[loader.Name] = version
fmt.Printf("Updated %s to version %s\n", loader.FriendlyName, version)
return true
}