Add a command for changing the acceptable versions (#206)

* feat: add packwiz settings command to allow for changing acceptable versions

* Add deduping on the list

* Fix typo in comment

* Detect out of order list and give the user an option to correct it

* Support adding and removing specific versions

* Ensure the options aren't nil

* Clean up the slice removal boilerplate

* Fix usage of slices.Delete
This commit is contained in:
Matt Artist 2023-04-08 14:00:40 -04:00 committed by GitHub
parent 9bddd21d32
commit a344ba11ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 167 additions and 3 deletions

View File

@ -417,7 +417,7 @@ func getLatestFile(modInfoData modInfo, mcVersions []string, fileID uint32, pack
// Possible to reach this point without obtaining file info; particularly from GameVersionLatestFiles // Possible to reach this point without obtaining file info; particularly from GameVersionLatestFiles
if fileID == 0 { if fileID == 0 {
return modFileInfo{}, errors.New("mod not available for the configured Minecraft version(s) (use the acceptable-game-versions option to accept more) or loader") return modFileInfo{}, errors.New("mod not available for the configured Minecraft version(s) (use the 'packwiz settings acceptable-versions' command to accept more) or loader")
} }
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/packwiz/packwiz/cmd" "github.com/packwiz/packwiz/cmd"
_ "github.com/packwiz/packwiz/curseforge" _ "github.com/packwiz/packwiz/curseforge"
_ "github.com/packwiz/packwiz/modrinth" _ "github.com/packwiz/packwiz/modrinth"
_ "github.com/packwiz/packwiz/settings"
_ "github.com/packwiz/packwiz/url" _ "github.com/packwiz/packwiz/url"
_ "github.com/packwiz/packwiz/utils" _ "github.com/packwiz/packwiz/utils"
) )

View File

@ -205,7 +205,7 @@ func installProject(project *modrinthApi.Project, versionFilename string, pack c
return fmt.Errorf("failed to get latest version: %v", err) return fmt.Errorf("failed to get latest version: %v", err)
} }
if latestVersion.ID == nil { if latestVersion.ID == nil {
return errors.New("mod not available for the configured Minecraft version(s) (use the acceptable-game-versions option to accept more) or loader") return errors.New("mod not available for the configured Minecraft version(s) (use the 'packwiz settings acceptable-versions' command to accept more) or loader")
} }
return installVersion(project, latestVersion, versionFilename, pack, index) return installVersion(project, latestVersion, versionFilename, pack, index)

View File

@ -287,7 +287,7 @@ func getLatestVersion(projectID string, name string, pack core.Pack) (*modrinthA
} }
if len(result) == 0 { if len(result) == 0 {
// TODO: retry with datapack specified, to determine what the issue is? or just request all and filter afterwards // TODO: retry with datapack specified, to determine what the issue is? or just request all and filter afterwards
return nil, errors.New("no valid versions found\n\tUse the acceptable-game-versions option to accept more game versions\n\tTo use datapacks, add a datapack loader mod and specify the datapack-folder option with the folder this mod loads datapacks from") return nil, errors.New("no valid versions found\n\tUse the 'packwiz settings acceptable-versions' command to accept more game versions\n\tTo use datapacks, add a datapack loader mod and specify the datapack-folder option with the folder this mod loads datapacks from")
} }
// TODO: option to always compare using flexver? // TODO: option to always compare using flexver?

View File

@ -0,0 +1,147 @@
package settings
import (
"fmt"
"github.com/packwiz/packwiz/cmdshared"
"github.com/packwiz/packwiz/core"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/unascribed/FlexVer/go/flexver"
"golang.org/x/exp/slices"
"os"
"strings"
)
var acceptableVersionsCommand = &cobra.Command{
Use: "acceptable-versions",
Short: "Manage your pack's acceptable Minecraft versions. This must be a comma seperated list of Minecraft versions, e.g. 1.16.3,1.16.4,1.16.5",
Aliases: []string{"av"},
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 currentVersions []string
// Check if they have no options whatsoever
if modpack.Options == nil {
// Initialize the options
modpack.Options = make(map[string]interface{})
}
// Check if the acceptable-game-versions is nil, which would mean their pack.toml doesn't have it set yet
if modpack.Options["acceptable-game-versions"] != nil {
// Convert the interface{} to a string slice
for _, v := range modpack.Options["acceptable-game-versions"].([]interface{}) {
currentVersions = append(currentVersions, v.(string))
}
}
// Check our flags to see if we're adding or removing
if viper.GetBool("settings.acceptable-versions.add") {
// Adding
acceptableVersion := args[0]
// Check if the version is already in the list
if slices.Contains(currentVersions, acceptableVersion) {
fmt.Printf("Version %s is already in your acceptable versions list!\n", acceptableVersion)
os.Exit(1)
}
// Add the version to the list and re-sort it
currentVersions = append(currentVersions, acceptableVersion)
flexver.VersionSlice(currentVersions).Sort()
// Set the new list
modpack.Options["acceptable-game-versions"] = currentVersions
// Save the pack
err = modpack.Write()
if err != nil {
fmt.Printf("Error writing pack: %s\n", err)
os.Exit(1)
}
// Print success message
prettyList := strings.Join(currentVersions, ", ")
fmt.Printf("Added %s to acceptable versions list, now %s\n", acceptableVersion, prettyList)
} else if viper.GetBool("settings.acceptable-versions.remove") {
// Removing
acceptableVersion := args[0]
// Check if the version is in the list
if !slices.Contains(currentVersions, acceptableVersion) {
fmt.Printf("Version %s is not in your acceptable versions list!\n", acceptableVersion)
os.Exit(1)
}
// Remove the version from the list
i := slices.Index(currentVersions, acceptableVersion)
currentVersions = slices.Delete(currentVersions, i, i+1)
// Sort it just in case it's out of order
flexver.VersionSlice(currentVersions).Sort()
// Set the new list
modpack.Options["acceptable-game-versions"] = currentVersions
// Save the pack
err = modpack.Write()
if err != nil {
fmt.Printf("Error writing pack: %s\n", err)
os.Exit(1)
}
// Print success message
prettyList := strings.Join(currentVersions, ", ")
fmt.Printf("Removed %s from acceptable versions list, now %s\n", acceptableVersion, prettyList)
} else {
// Overwriting
acceptableVersions := args[0]
acceptableVersionsList := strings.Split(acceptableVersions, ",")
// Dedupe the list
acceptableVersionsDeduped := []string(nil)
for i, v := range acceptableVersionsList {
if !slices.Contains(acceptableVersionsList[i+1:], v) {
acceptableVersionsDeduped = append(acceptableVersionsDeduped, v)
}
}
// Check if the list of versions is out of order, lowest to highest, and inform the user if it is
// Compare the versions one by one to the next one, if the next one is lower, then it's out of order
// If it's only 1 element long, then it's already sorted
if len(acceptableVersionsDeduped) > 1 {
for i, v := range acceptableVersionsDeduped {
if flexver.Less(acceptableVersionsDeduped[i+1], v) {
fmt.Printf("Warning: Your acceptable versions list is out of order. ")
// Give a do you mean example
// Clone the list
acceptableVersionsDedupedClone := make([]string, len(acceptableVersionsDeduped))
copy(acceptableVersionsDedupedClone, acceptableVersionsDeduped)
flexver.VersionSlice(acceptableVersionsDedupedClone).Sort()
fmt.Printf("Did you mean %s?\n", strings.Join(acceptableVersionsDedupedClone, ", "))
if cmdshared.PromptYesNo("Would you like to fix this automatically? [Y/n] ") {
// If yes we'll just set the list to the sorted one
acceptableVersionsDeduped = acceptableVersionsDedupedClone
break
} else {
// If no we'll just continue
break
}
}
}
}
modpack.Options["acceptable-game-versions"] = acceptableVersionsDeduped
err = modpack.Write()
if err != nil {
fmt.Printf("Error writing pack: %s\n", err)
os.Exit(1)
}
// Print success message
prettyList := strings.Join(acceptableVersionsDeduped, ", ")
fmt.Printf("Set acceptable versions to %s\n", prettyList)
}
},
}
func init() {
settingsCmd.AddCommand(acceptableVersionsCommand)
// Add and remove flags for adding or removing specific versions
acceptableVersionsCommand.Flags().BoolP("add", "a", false, "Add a version to the list")
acceptableVersionsCommand.Flags().BoolP("remove", "r", false, "Remove a version from the list")
_ = viper.BindPFlag("settings.acceptable-versions.add", acceptableVersionsCommand.Flags().Lookup("add"))
_ = viper.BindPFlag("settings.acceptable-versions.remove", acceptableVersionsCommand.Flags().Lookup("remove"))
}

16
settings/settings.go Normal file
View File

@ -0,0 +1,16 @@
package settings
import (
"github.com/packwiz/packwiz/cmd"
"github.com/spf13/cobra"
)
// settingsCmd represents the base command when called without any subcommands
var settingsCmd = &cobra.Command{
Use: "settings",
Short: "Manage pack settings",
}
func init() {
cmd.Add(settingsCmd)
}