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 }