mirror of
https://github.com/packwiz/packwiz.git
synced 2025-04-19 21:16:30 +02:00
Fix some printfs, clean regexes, switch to fuzzy matching for search
This commit is contained in:
parent
33c93f3ac3
commit
5ba9ff5c73
@ -65,7 +65,7 @@ var initCmd = &cobra.Command{
|
||||
|
||||
mcVersions, err := getValidMCVersions()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to get latest minecraft versions: %s", err)
|
||||
fmt.Printf("Failed to get latest minecraft versions: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ var removeCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("Mod %s removed successfully!", args[0])
|
||||
fmt.Printf("Mod %s removed successfully!\n", args[0])
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ var updateCmd = &cobra.Command{
|
||||
for _, v := range index.GetAllMods() {
|
||||
modData, err := core.LoadMod(v)
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading mod file: %s", err.Error())
|
||||
fmt.Printf("Error reading mod file: %s\n", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ var updateCmd = &cobra.Command{
|
||||
updaterMap[k] = append(slice, modData)
|
||||
}
|
||||
if !updaterFound {
|
||||
fmt.Printf("A supported update system for \"%s\" cannot be found.", modData.Name)
|
||||
fmt.Printf("A supported update system for \"%s\" cannot be found.\n", modData.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,9 @@ func init() {
|
||||
}
|
||||
|
||||
var fileIDRegexes = [...]*regexp.Regexp{
|
||||
regexp.MustCompile("^https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/(.+)\\/files\\/(\\d+)"),
|
||||
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/(.+)\\/files\\/(\\d+)"),
|
||||
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/(.+)\\/download\\/(\\d+)"),
|
||||
regexp.MustCompile("^https?://minecraft\\.curseforge\\.com/projects/(.+)/files/(\\d+)"),
|
||||
regexp.MustCompile("^https?://(?:www\\.)?curseforge\\.com/minecraft/mc-mods/(.+)/files/(\\d+)"),
|
||||
regexp.MustCompile("^https?://(?:www\\.)?curseforge\\.com/minecraft/mc-mods/(.+)/download/(\\d+)"),
|
||||
}
|
||||
|
||||
func getFileIDsFromString(mod string) (bool, int, int, error) {
|
||||
@ -44,8 +44,8 @@ func getFileIDsFromString(mod string) (bool, int, int, error) {
|
||||
}
|
||||
|
||||
var modSlugRegexes = [...]*regexp.Regexp{
|
||||
regexp.MustCompile("^https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)"),
|
||||
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)"),
|
||||
regexp.MustCompile("^https?://minecraft\\.curseforge\\.com/projects/([^/]+)"),
|
||||
regexp.MustCompile("^https?://(?:www\\.)?curseforge\\.com/minecraft/mc-mods/([^/]+)"),
|
||||
// Exact slug matcher
|
||||
regexp.MustCompile("^[a-z][\\da-z\\-_]{0,127}$"),
|
||||
}
|
||||
|
@ -4,11 +4,10 @@ import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/sahilm/fuzzy"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/agnivade/levenshtein"
|
||||
"github.com/comp500/packwiz/core"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/dixonwille/wmenu.v4"
|
||||
@ -71,63 +70,14 @@ var installCmd = &cobra.Command{
|
||||
var modInfoData modInfo
|
||||
|
||||
if !done {
|
||||
fmt.Println("Searching CurseForge...")
|
||||
searchTerm := strings.Join(args, " ")
|
||||
results, err := getSearch(searchTerm, mcVersion)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
fmt.Println("No mods found!")
|
||||
os.Exit(1)
|
||||
} else if len(results) == 1 {
|
||||
modInfoData = results[0]
|
||||
modID = modInfoData.ID
|
||||
modInfoObtained = true
|
||||
done = true
|
||||
} else {
|
||||
// Find the closest value to the search term
|
||||
sort.Slice(results, func(i, j int) bool {
|
||||
return levenshtein.ComputeDistance(searchTerm, results[i].Name) < levenshtein.ComputeDistance(searchTerm, results[j].Name)
|
||||
})
|
||||
|
||||
menu := wmenu.NewMenu("Choose a number:")
|
||||
|
||||
for i, v := range results {
|
||||
menu.Option(v.Name, v, i == 0, nil)
|
||||
}
|
||||
menu.Option("Cancel", nil, false, nil)
|
||||
|
||||
menu.Action(func(menuRes []wmenu.Opt) error {
|
||||
if len(menuRes) != 1 || menuRes[0].Value == nil {
|
||||
fmt.Println("Cancelled!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Why is variable shadowing a thing!!!!
|
||||
var ok bool
|
||||
modInfoData, ok = menuRes[0].Value.(modInfo)
|
||||
if !ok {
|
||||
fmt.Println("Error converting interface from wmenu")
|
||||
os.Exit(1)
|
||||
}
|
||||
modID = modInfoData.ID
|
||||
modInfoObtained = true
|
||||
done = true
|
||||
return nil
|
||||
})
|
||||
err = menu.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !done {
|
||||
return
|
||||
}
|
||||
var cancelled bool
|
||||
cancelled, modInfoData = searchCurseforgeInternal(args, mcVersion)
|
||||
if cancelled {
|
||||
return
|
||||
}
|
||||
done = true
|
||||
modID = modInfoData.ID
|
||||
modInfoObtained = true
|
||||
}
|
||||
|
||||
if !done {
|
||||
@ -220,6 +170,7 @@ var installCmd = &cobra.Command{
|
||||
depFileInfo, err := getLatestFile(currData, mcVersion, 0)
|
||||
if err != nil {
|
||||
fmt.Printf("Error retrieving dependency data: %s\n", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
for _, dep := range depFileInfo.Dependencies {
|
||||
@ -296,6 +247,79 @@ var installCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// Used to implement interface for fuzzy matching
|
||||
type modResultsList []modInfo
|
||||
|
||||
func (r modResultsList) String(i int) string {
|
||||
return r[i].Name
|
||||
}
|
||||
|
||||
func (r modResultsList) Len() int {
|
||||
return len(r)
|
||||
}
|
||||
|
||||
func searchCurseforgeInternal(args []string, mcVersion string) (bool, modInfo) {
|
||||
fmt.Println("Searching CurseForge...")
|
||||
searchTerm := strings.Join(args, " ")
|
||||
results, err := getSearch(searchTerm, mcVersion)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(results) == 0 {
|
||||
fmt.Println("No mods found!")
|
||||
os.Exit(1)
|
||||
} else if len(results) == 1 {
|
||||
return false, results[0]
|
||||
} else {
|
||||
// Fuzzy search on results list
|
||||
fuzzySearchResults := fuzzy.FindFrom(searchTerm, modResultsList(results))
|
||||
|
||||
menu := wmenu.NewMenu("Choose a number:")
|
||||
|
||||
if len(fuzzySearchResults) == 0 {
|
||||
for i, v := range results {
|
||||
menu.Option(v.Name, v, i == 0, nil)
|
||||
}
|
||||
} else {
|
||||
for i, v := range fuzzySearchResults {
|
||||
menu.Option(results[v.Index].Name, results[v.Index], i == 0, nil)
|
||||
}
|
||||
}
|
||||
menu.Option("Cancel", nil, false, nil)
|
||||
|
||||
var modInfoData modInfo
|
||||
var cancelled bool
|
||||
menu.Action(func(menuRes []wmenu.Opt) error {
|
||||
if len(menuRes) != 1 || menuRes[0].Value == nil {
|
||||
fmt.Println("Cancelled!")
|
||||
cancelled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Why is variable shadowing a thing!!!!
|
||||
var ok bool
|
||||
modInfoData, ok = menuRes[0].Value.(modInfo)
|
||||
if !ok {
|
||||
return errors.New("error converting interface from wmenu")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
err = menu.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if cancelled {
|
||||
return true, modInfo{}
|
||||
}
|
||||
return false, modInfoData
|
||||
}
|
||||
// This should never be executed, but Go requires it!
|
||||
return false, modInfo{}
|
||||
}
|
||||
|
||||
func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileInfo, error) {
|
||||
if fileID == 0 {
|
||||
// TODO: change to timestamp-based comparison??
|
||||
|
@ -256,7 +256,6 @@ func getFileInfo(modID int, fileID int) (modFileInfo, error) {
|
||||
return infoRes, nil
|
||||
}
|
||||
|
||||
// TODO: pass gameVersion?
|
||||
func getSearch(searchText string, gameVersion string) ([]modInfo, error) {
|
||||
var infoRes []modInfo
|
||||
client := &http.Client{}
|
||||
|
3
go.mod
3
go.mod
@ -2,7 +2,6 @@ module github.com/comp500/packwiz
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/agnivade/levenshtein v1.0.2
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
|
||||
github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920 // indirect
|
||||
github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817
|
||||
@ -11,8 +10,10 @@ require (
|
||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 // indirect
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect
|
||||
github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.4 // indirect
|
||||
github.com/mitchellh/mapstructure v1.1.2
|
||||
github.com/sahilm/fuzzy v0.1.0
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/viper v1.4.0
|
||||
|
6
go.sum
6
go.sum
@ -4,8 +4,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/agnivade/levenshtein v1.0.2 h1:xKF7WlEzoa+ZVkzBxy0ukdzI2etYiWGlTPMNTBGncKI=
|
||||
github.com/agnivade/levenshtein v1.0.2/go.mod h1:JLvzGblJATanj48SD0YhHTEFGkWvw3ASLFWSiMIFXsE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
@ -76,6 +74,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
@ -104,6 +104,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
|
||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e h1:VAzdS5Nw68fbf5RZ8RDVlUvPXNU6Z3jtPCK/qvm4FoQ=
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
|
Loading…
x
Reference in New Issue
Block a user