mirror of
https://github.com/packwiz/packwiz.git
synced 2025-04-28 17: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()
|
mcVersions, err := getValidMCVersions()
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ var removeCmd = &cobra.Command{
|
|||||||
os.Exit(1)
|
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() {
|
for _, v := range index.GetAllMods() {
|
||||||
modData, err := core.LoadMod(v)
|
modData, err := core.LoadMod(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error reading mod file: %s", err.Error())
|
fmt.Printf("Error reading mod file: %s\n", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ var updateCmd = &cobra.Command{
|
|||||||
updaterMap[k] = append(slice, modData)
|
updaterMap[k] = append(slice, modData)
|
||||||
}
|
}
|
||||||
if !updaterFound {
|
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{
|
var fileIDRegexes = [...]*regexp.Regexp{
|
||||||
regexp.MustCompile("^https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/(.+)\\/files\\/(\\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/(.+)/files/(\\d+)"),
|
||||||
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/(.+)\\/download\\/(\\d+)"),
|
regexp.MustCompile("^https?://(?:www\\.)?curseforge\\.com/minecraft/mc-mods/(.+)/download/(\\d+)"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileIDsFromString(mod string) (bool, int, int, error) {
|
func getFileIDsFromString(mod string) (bool, int, int, error) {
|
||||||
@ -44,8 +44,8 @@ func getFileIDsFromString(mod string) (bool, int, int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var modSlugRegexes = [...]*regexp.Regexp{
|
var modSlugRegexes = [...]*regexp.Regexp{
|
||||||
regexp.MustCompile("^https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)"),
|
regexp.MustCompile("^https?://minecraft\\.curseforge\\.com/projects/([^/]+)"),
|
||||||
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)"),
|
regexp.MustCompile("^https?://(?:www\\.)?curseforge\\.com/minecraft/mc-mods/([^/]+)"),
|
||||||
// Exact slug matcher
|
// Exact slug matcher
|
||||||
regexp.MustCompile("^[a-z][\\da-z\\-_]{0,127}$"),
|
regexp.MustCompile("^[a-z][\\da-z\\-_]{0,127}$"),
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,10 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/sahilm/fuzzy"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/agnivade/levenshtein"
|
|
||||||
"github.com/comp500/packwiz/core"
|
"github.com/comp500/packwiz/core"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"gopkg.in/dixonwille/wmenu.v4"
|
"gopkg.in/dixonwille/wmenu.v4"
|
||||||
@ -71,63 +70,14 @@ var installCmd = &cobra.Command{
|
|||||||
var modInfoData modInfo
|
var modInfoData modInfo
|
||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
fmt.Println("Searching CurseForge...")
|
var cancelled bool
|
||||||
searchTerm := strings.Join(args, " ")
|
cancelled, modInfoData = searchCurseforgeInternal(args, mcVersion)
|
||||||
results, err := getSearch(searchTerm, mcVersion)
|
if cancelled {
|
||||||
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
|
return
|
||||||
}
|
}
|
||||||
}
|
done = true
|
||||||
|
modID = modInfoData.ID
|
||||||
|
modInfoObtained = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
@ -220,6 +170,7 @@ var installCmd = &cobra.Command{
|
|||||||
depFileInfo, err := getLatestFile(currData, mcVersion, 0)
|
depFileInfo, err := getLatestFile(currData, mcVersion, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error retrieving dependency data: %s\n", err.Error())
|
fmt.Printf("Error retrieving dependency data: %s\n", err.Error())
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dep := range depFileInfo.Dependencies {
|
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) {
|
func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileInfo, error) {
|
||||||
if fileID == 0 {
|
if fileID == 0 {
|
||||||
// TODO: change to timestamp-based comparison??
|
// TODO: change to timestamp-based comparison??
|
||||||
|
@ -256,7 +256,6 @@ func getFileInfo(modID int, fileID int) (modFileInfo, error) {
|
|||||||
return infoRes, nil
|
return infoRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: pass gameVersion?
|
|
||||||
func getSearch(searchText string, gameVersion string) ([]modInfo, error) {
|
func getSearch(searchText string, gameVersion string) ([]modInfo, error) {
|
||||||
var infoRes []modInfo
|
var infoRes []modInfo
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
3
go.mod
3
go.mod
@ -2,7 +2,6 @@ module github.com/comp500/packwiz
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v0.3.1
|
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/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
|
||||||
github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920 // indirect
|
github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920 // indirect
|
||||||
github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817
|
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/fmt v0.0.0-20150411045040-2a5d6d7d2995 // indirect
|
||||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect
|
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect
|
||||||
github.com/igorsobreira/titlecase v0.0.0-20140109233139-4156b5b858ac
|
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/mattn/go-isatty v0.0.4 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.1.2
|
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/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e
|
||||||
github.com/spf13/cobra v0.0.5
|
github.com/spf13/cobra v0.0.5
|
||||||
github.com/spf13/viper v1.4.0
|
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/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 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
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/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/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=
|
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/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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
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 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
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/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 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
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/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 h1:VAzdS5Nw68fbf5RZ8RDVlUvPXNU6Z3jtPCK/qvm4FoQ=
|
||||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user