mirror of
https://github.com/packwiz/packwiz.git
synced 2025-04-19 21:16:30 +02:00
Switch to cobra/viper
This commit is contained in:
parent
8915e16614
commit
4fea7ceebf
54
cmd/refresh.go
Normal file
54
cmd/refresh.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/comp500/packwiz/core"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// refreshCmd represents the refresh command
|
||||||
|
var refreshCmd = &cobra.Command{
|
||||||
|
Use: "refresh",
|
||||||
|
Short: "Refresh the index file",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
fmt.Println("Loading modpack...")
|
||||||
|
pack, err := core.LoadPack()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
index, err := pack.LoadIndex()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = index.Refresh()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = index.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.UpdateIndexHash()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println("Index refreshed!")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(refreshCmd)
|
||||||
|
}
|
71
cmd/remove.go
Normal file
71
cmd/remove.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/comp500/packwiz/core"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// removeCmd represents the remove command
|
||||||
|
var removeCmd = &cobra.Command{
|
||||||
|
Use: "remove",
|
||||||
|
Short: "Remove a mod from the modpack",
|
||||||
|
Aliases: []string{"delete", "uninstall"},
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args[0]) == 0 {
|
||||||
|
fmt.Println("You must specify a mod.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println("Loading modpack...")
|
||||||
|
pack, err := core.LoadPack()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
index, err := pack.LoadIndex()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
resolvedMod, ok := index.FindMod(args[0])
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("You don't have this mod installed.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = os.Remove(resolvedMod)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println("Removing mod from index...")
|
||||||
|
err = index.RemoveFile(resolvedMod)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = index.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.UpdateIndexHash()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Mod %s removed successfully!", args[0])
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(removeCmd)
|
||||||
|
}
|
72
cmd/root.go
Normal file
72
cmd/root.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var packFile string
|
||||||
|
var modsFolder string
|
||||||
|
var cfgFile string
|
||||||
|
|
||||||
|
// rootCmd represents the base command when called without any subcommands
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "packwiz",
|
||||||
|
Short: "A command line tool for creating Minecraft modpacks",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute starts the root command for packwiz
|
||||||
|
func Execute() {
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds a new command as a subcommand to packwiz
|
||||||
|
func Add(newCommand *cobra.Command) {
|
||||||
|
rootCmd.AddCommand(newCommand)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cobra.OnInitialize(initConfig)
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringVar(&packFile, "pack-file", "pack.toml", "The modpack metadata file to use")
|
||||||
|
viper.BindPFlag("pack-file", rootCmd.PersistentFlags().Lookup("pack-file"))
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringVar(&modsFolder, "mods-folder", "mods", "The default folder to store mod metadata files in")
|
||||||
|
viper.BindPFlag("mods-folder", rootCmd.PersistentFlags().Lookup("mods-folder"))
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.packwiz.toml)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// initConfig reads in config file and ENV variables if set.
|
||||||
|
func initConfig() {
|
||||||
|
if cfgFile != "" {
|
||||||
|
// Use config file from the flag.
|
||||||
|
viper.SetConfigFile(cfgFile)
|
||||||
|
} else {
|
||||||
|
// Find home directory.
|
||||||
|
home, err := homedir.Dir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search config in home directory with name ".packwiz" (without extension).
|
||||||
|
viper.AddConfigPath(home)
|
||||||
|
viper.SetConfigName(".packwiz")
|
||||||
|
}
|
||||||
|
|
||||||
|
viper.AutomaticEnv() // read in environment variables that match
|
||||||
|
|
||||||
|
// If a config file is found, read it in.
|
||||||
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
|
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||||
|
}
|
||||||
|
}
|
228
cmd/update.go
Normal file
228
cmd/update.go
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/comp500/packwiz/core"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// updateCmd represents the update command
|
||||||
|
var updateCmd = &cobra.Command{
|
||||||
|
Use: "update",
|
||||||
|
Short: "Update a mod (or all mods) in the modpack",
|
||||||
|
Aliases: []string{"upgrade"},
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// TODO: --check flag?
|
||||||
|
// TODO: specify multiple mods to update at once?
|
||||||
|
|
||||||
|
fmt.Println("Loading modpack...")
|
||||||
|
pack, err := core.LoadPack()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
index, err := pack.LoadIndex()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
mcVersion, err := pack.GetMCVersion()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
multiple := false
|
||||||
|
var singleUpdatedName string
|
||||||
|
if len(args[0]) == 0 || args[0] == "*" {
|
||||||
|
multiple = true
|
||||||
|
|
||||||
|
updaterMap := make(map[string][]core.Mod)
|
||||||
|
fmt.Println("Reading mod files...")
|
||||||
|
for _, v := range index.GetAllMods() {
|
||||||
|
modData, err := core.LoadMod(v)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading mod file: %s", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
updaterFound := false
|
||||||
|
for k := range modData.Update {
|
||||||
|
slice, ok := updaterMap[k]
|
||||||
|
if !ok {
|
||||||
|
_, ok = core.Updaters[k]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
slice = []core.Mod{}
|
||||||
|
}
|
||||||
|
updaterFound = true
|
||||||
|
updaterMap[k] = append(slice, modData)
|
||||||
|
}
|
||||||
|
if !updaterFound {
|
||||||
|
fmt.Printf("A supported update system for \"%s\" cannot be found.", modData.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Checking for updates...")
|
||||||
|
updatesFound := false
|
||||||
|
updaterPointerMap := make(map[string][]*core.Mod)
|
||||||
|
updaterCachedStateMap := make(map[string][]interface{})
|
||||||
|
for k, v := range updaterMap {
|
||||||
|
checks, err := core.Updaters[k].CheckUpdate(v, mcVersion)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: do we return err code 1?
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for i, check := range checks {
|
||||||
|
if check.Error != nil {
|
||||||
|
// TODO: do we return err code 1?
|
||||||
|
// TODO: better error message?
|
||||||
|
fmt.Println(check.Error.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if check.UpdateAvailable {
|
||||||
|
if !updatesFound {
|
||||||
|
fmt.Println("Updates found:")
|
||||||
|
updatesFound = true
|
||||||
|
}
|
||||||
|
fmt.Printf("%s: %s\n", v[i].Name, check.UpdateString)
|
||||||
|
updaterPointerMap[k] = append(updaterPointerMap[k], &v[i])
|
||||||
|
updaterCachedStateMap[k] = append(updaterCachedStateMap[k], check.CachedState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !updatesFound {
|
||||||
|
fmt.Println("All mods are up to date!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("Do you want to update? [Y/n]: ")
|
||||||
|
answer, err := bufio.NewReader(os.Stdin).ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ansNormal := strings.ToLower(strings.TrimSpace(answer))
|
||||||
|
if len(ansNormal) > 0 && ansNormal[0] == 'n' {
|
||||||
|
fmt.Println("Cancelled!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range updaterPointerMap {
|
||||||
|
err := core.Updaters[k].DoUpdate(v, updaterCachedStateMap[k])
|
||||||
|
if err != nil {
|
||||||
|
// TODO: do we return err code 1?
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, modData := range v {
|
||||||
|
format, hash, err := modData.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = index.RefreshFileWithHash(modData.GetFilePath(), format, hash, true)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
modPath, ok := index.FindMod(args[0])
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("You don't have this mod installed.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
modData, err := core.LoadMod(modPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
singleUpdatedName = modData.Name
|
||||||
|
updaterFound := false
|
||||||
|
for k := range modData.Update {
|
||||||
|
updater, ok := core.Updaters[k]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
updaterFound = true
|
||||||
|
|
||||||
|
check, err := updater.CheckUpdate([]core.Mod{modData}, mcVersion)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if len(check) != 1 {
|
||||||
|
fmt.Println("Invalid update check response")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if check[0].UpdateAvailable {
|
||||||
|
fmt.Printf("Update available: %s\n", check[0].UpdateString)
|
||||||
|
|
||||||
|
err = updater.DoUpdate([]*core.Mod{&modData}, []interface{}{check[0].CachedState})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
format, hash, err := modData.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = index.RefreshFileWithHash(modPath, format, hash, true)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("\"%s\" is already up to date!\n", modData.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !updaterFound {
|
||||||
|
// TODO: use file name instead of Name when len(Name) == 0 in all places?
|
||||||
|
fmt.Println("A supported update system for \"" + modData.Name + "\" cannot be found.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = index.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.UpdateIndexHash()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if multiple {
|
||||||
|
fmt.Println("Mods updated!")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("\"%s\" updated!\n", singleUpdatedName)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(updateCmd)
|
||||||
|
}
|
@ -1,6 +0,0 @@
|
|||||||
package core
|
|
||||||
import "github.com/urfave/cli"
|
|
||||||
|
|
||||||
// Commands stores all the commands that packwiz can run. Append to this slice to add your own commands.
|
|
||||||
var Commands []cli.Command
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
|||||||
package core
|
|
||||||
import (
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Flags stores common information passed as flags to the program.
|
|
||||||
type Flags struct {
|
|
||||||
PackFile string
|
|
||||||
ModsFolder string
|
|
||||||
}
|
|
||||||
|
|
||||||
// FlagsFromContext converts a CLI context (from commands) into a Flags struct, for use in helper functions.
|
|
||||||
func FlagsFromContext(c *cli.Context) Flags {
|
|
||||||
return Flags{
|
|
||||||
c.GlobalString("pack-file"),
|
|
||||||
c.GlobalString("mods-folder"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CLIFlags is used internally to initialise the internal flags (easier to keep in one place)
|
|
||||||
var CLIFlags = [...]cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "pack-file",
|
|
||||||
Value: "pack.toml",
|
|
||||||
Usage: "The modpack metadata file to use",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "mods-folder",
|
|
||||||
Value: "mods",
|
|
||||||
Usage: "The mods folder to use",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/denormal/go-gitignore"
|
"github.com/denormal/go-gitignore"
|
||||||
|
"github.com/spf13/viper"
|
||||||
"github.com/vbauerster/mpb/v4"
|
"github.com/vbauerster/mpb/v4"
|
||||||
"github.com/vbauerster/mpb/v4/decor"
|
"github.com/vbauerster/mpb/v4/decor"
|
||||||
)
|
)
|
||||||
@ -20,7 +21,6 @@ import (
|
|||||||
type Index struct {
|
type Index struct {
|
||||||
HashFormat string `toml:"hash-format"`
|
HashFormat string `toml:"hash-format"`
|
||||||
Files []IndexFile `toml:"files"`
|
Files []IndexFile `toml:"files"`
|
||||||
flags Flags
|
|
||||||
indexFile string
|
indexFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,12 +37,11 @@ type IndexFile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LoadIndex attempts to load the index file from a path
|
// LoadIndex attempts to load the index file from a path
|
||||||
func LoadIndex(indexFile string, flags Flags) (Index, error) {
|
func LoadIndex(indexFile string) (Index, error) {
|
||||||
var index Index
|
var index Index
|
||||||
if _, err := toml.DecodeFile(indexFile, &index); err != nil {
|
if _, err := toml.DecodeFile(indexFile, &index); err != nil {
|
||||||
return Index{}, err
|
return Index{}, err
|
||||||
}
|
}
|
||||||
index.flags = flags
|
|
||||||
index.indexFile = indexFile
|
index.indexFile = indexFile
|
||||||
if len(index.HashFormat) == 0 {
|
if len(index.HashFormat) == 0 {
|
||||||
index.HashFormat = "sha256"
|
index.HashFormat = "sha256"
|
||||||
@ -144,7 +143,7 @@ func (in *Index) updateFile(path string) error {
|
|||||||
// of files, like CraftTweaker resources.
|
// of files, like CraftTweaker resources.
|
||||||
absFileDir, err := filepath.Abs(filepath.Dir(path))
|
absFileDir, err := filepath.Abs(filepath.Dir(path))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
absModsDir, err := filepath.Abs(in.flags.ModsFolder)
|
absModsDir, err := filepath.Abs(viper.GetString("mods-folder"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if absFileDir == absModsDir {
|
if absFileDir == absModsDir {
|
||||||
mod = true
|
mod = true
|
||||||
@ -161,11 +160,11 @@ func (in *Index) Refresh() error {
|
|||||||
// for i := 0; i < runtime.NumCPU(); i++ {}
|
// for i := 0; i < runtime.NumCPU(); i++ {}
|
||||||
|
|
||||||
// Is case-sensitivity a problem?
|
// Is case-sensitivity a problem?
|
||||||
pathPF, _ := filepath.Abs(in.flags.PackFile)
|
pathPF, _ := filepath.Abs(viper.GetString("pack-file"))
|
||||||
pathIndex, _ := filepath.Abs(in.indexFile)
|
pathIndex, _ := filepath.Abs(in.indexFile)
|
||||||
|
|
||||||
// TODO: A method of specifying pack root directory?
|
// TODO: A method of specifying pack root directory?
|
||||||
packRoot := filepath.Dir(in.flags.PackFile)
|
packRoot := filepath.Dir(viper.GetString("pack-file"))
|
||||||
ignoreExists := true
|
ignoreExists := true
|
||||||
pathIgnore, _ := filepath.Abs(filepath.Join(packRoot, ".packwizignore"))
|
pathIgnore, _ := filepath.Abs(filepath.Join(packRoot, ".packwizignore"))
|
||||||
ignore, err := gitignore.NewFromFile(filepath.Join(packRoot, ".packwizignore"))
|
ignore, err := gitignore.NewFromFile(filepath.Join(packRoot, ".packwizignore"))
|
||||||
|
@ -67,8 +67,8 @@ func LoadMod(modFile string) (Mod, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetMetaName sets the mod metadata file from a given file name (to be put in the mods folder)
|
// SetMetaName sets the mod metadata file from a given file name (to be put in the mods folder)
|
||||||
func (m *Mod) SetMetaName(metaName string, flags Flags) string {
|
func (m *Mod) SetMetaName(metaName string) string {
|
||||||
m.metaFile = ResolveMod(metaName, flags)
|
m.metaFile = ResolveMod(metaName)
|
||||||
return m.metaFile
|
return m.metaFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
core/pack.go
17
core/pack.go
@ -1,4 +1,5 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@ -8,6 +9,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pack stores the modpack metadata, usually in pack.toml
|
// Pack stores the modpack metadata, usually in pack.toml
|
||||||
@ -22,36 +24,34 @@ type Pack struct {
|
|||||||
Versions map[string]string `toml:"versions"`
|
Versions map[string]string `toml:"versions"`
|
||||||
Client map[string]toml.Primitive `toml:"client"`
|
Client map[string]toml.Primitive `toml:"client"`
|
||||||
Server map[string]toml.Primitive `toml:"server"`
|
Server map[string]toml.Primitive `toml:"server"`
|
||||||
flags Flags
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadPack loads the modpack metadata to a Pack struct
|
// LoadPack loads the modpack metadata to a Pack struct
|
||||||
func LoadPack(flags Flags) (Pack, error) {
|
func LoadPack() (Pack, error) {
|
||||||
var modpack Pack
|
var modpack Pack
|
||||||
if _, err := toml.DecodeFile(flags.PackFile, &modpack); err != nil {
|
if _, err := toml.DecodeFile(viper.GetString("pack-file"), &modpack); err != nil {
|
||||||
return Pack{}, err
|
return Pack{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(modpack.Index.File) == 0 {
|
if len(modpack.Index.File) == 0 {
|
||||||
modpack.Index.File = "index.toml"
|
modpack.Index.File = "index.toml"
|
||||||
}
|
}
|
||||||
modpack.flags = flags
|
|
||||||
return modpack, nil
|
return modpack, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadIndex attempts to load the index file of this modpack
|
// LoadIndex attempts to load the index file of this modpack
|
||||||
func (pack Pack) LoadIndex() (Index, error) {
|
func (pack Pack) LoadIndex() (Index, error) {
|
||||||
if filepath.IsAbs(pack.Index.File) {
|
if filepath.IsAbs(pack.Index.File) {
|
||||||
return LoadIndex(pack.Index.File, pack.flags)
|
return LoadIndex(pack.Index.File)
|
||||||
}
|
}
|
||||||
fileNative := filepath.FromSlash(pack.Index.File)
|
fileNative := filepath.FromSlash(pack.Index.File)
|
||||||
return LoadIndex(filepath.Join(filepath.Dir(pack.flags.PackFile), fileNative), pack.flags)
|
return LoadIndex(filepath.Join(filepath.Dir(viper.GetString("pack-file")), fileNative))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIndexHash recalculates the hash of the index file of this modpack
|
// UpdateIndexHash recalculates the hash of the index file of this modpack
|
||||||
func (pack *Pack) UpdateIndexHash() error {
|
func (pack *Pack) UpdateIndexHash() error {
|
||||||
fileNative := filepath.FromSlash(pack.Index.File)
|
fileNative := filepath.FromSlash(pack.Index.File)
|
||||||
indexFile := filepath.Join(filepath.Dir(pack.flags.PackFile), fileNative)
|
indexFile := filepath.Join(filepath.Dir(viper.GetString("pack-file")), fileNative)
|
||||||
if filepath.IsAbs(pack.Index.File) {
|
if filepath.IsAbs(pack.Index.File) {
|
||||||
indexFile = pack.Index.File
|
indexFile = pack.Index.File
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ func (pack *Pack) UpdateIndexHash() error {
|
|||||||
|
|
||||||
// Write saves the pack file
|
// Write saves the pack file
|
||||||
func (pack Pack) Write() error {
|
func (pack Pack) Write() error {
|
||||||
f, err := os.Create(pack.flags.PackFile)
|
f, err := os.Create(viper.GetString("pack-file"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -98,4 +98,3 @@ func (pack Pack) GetMCVersion() (string, error) {
|
|||||||
}
|
}
|
||||||
return mcVersion, nil
|
return mcVersion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,14 +3,16 @@ package core
|
|||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ModExtension is the file extension of the mod metadata files
|
// ModExtension is the file extension of the mod metadata files
|
||||||
const ModExtension = ".toml"
|
const ModExtension = ".toml"
|
||||||
|
|
||||||
// ResolveMod returns the path to a mod file from it's name
|
// ResolveMod returns the path to a mod file from it's name
|
||||||
func ResolveMod(modName string, flags Flags) string {
|
func ResolveMod(modName string) string {
|
||||||
// TODO: should this work for any metadata file?
|
// TODO: should this work for any metadata file?
|
||||||
fileName := strings.ToLower(strings.TrimSuffix(modName, ModExtension)) + ModExtension
|
fileName := strings.ToLower(strings.TrimSuffix(modName, ModExtension)) + ModExtension
|
||||||
return filepath.Join(flags.ModsFolder, fileName)
|
return filepath.Join(viper.GetString("mods-folder"), fileName)
|
||||||
}
|
}
|
||||||
|
@ -2,44 +2,23 @@ package curseforge
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/comp500/packwiz/cmd"
|
||||||
"github.com/comp500/packwiz/core"
|
"github.com/comp500/packwiz/core"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/skratchdot/open-golang/open"
|
"github.com/spf13/cobra"
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
var curseforgeCmd = &cobra.Command{
|
||||||
core.Commands = append(core.Commands, cli.Command{
|
Use: "curseforge",
|
||||||
Name: "curseforge",
|
|
||||||
Aliases: []string{"cf", "curse"},
|
Aliases: []string{"cf", "curse"},
|
||||||
Usage: "Manage curseforge-based mods",
|
Short: "Manage curseforge-based mods",
|
||||||
Subcommands: []cli.Command{{
|
}
|
||||||
Name: "install",
|
|
||||||
Usage: "Install a mod from a curseforge URL, slug or ID",
|
func init() {
|
||||||
Aliases: []string{"add", "get"},
|
cmd.Add(curseforgeCmd)
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
return cmdInstall(core.FlagsFromContext(c), c.Args().Get(0), c.Args().Tail())
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "import",
|
|
||||||
Usage: "Import an installed curseforge modpack",
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
return cmdImport(core.FlagsFromContext(c), c.Args().Get(0))
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
Name: "open",
|
|
||||||
// TODO: change semantics to "project" rather than "mod", as this supports texture packs and misc content as well?
|
|
||||||
Usage: "Open the project page for a curseforge mod in your browser",
|
|
||||||
Aliases: []string{"doc"},
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
return cmdDoc(core.FlagsFromContext(c), c.Args().Get(0))
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
})
|
|
||||||
core.Updaters["curseforge"] = cfUpdater{}
|
core.Updaters["curseforge"] = cfUpdater{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +78,7 @@ func getModIDFromString(mod string) (bool, int, error) {
|
|||||||
return false, 0, nil
|
return false, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createModFile(flags core.Flags, modInfo modInfo, fileInfo modFileInfo, index *core.Index) error {
|
func createModFile(modInfo modInfo, fileInfo modFileInfo, index *core.Index) error {
|
||||||
updateMap := make(map[string]map[string]interface{})
|
updateMap := make(map[string]map[string]interface{})
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -126,7 +105,7 @@ func createModFile(flags core.Flags, modInfo modInfo, fileInfo modFileInfo, inde
|
|||||||
},
|
},
|
||||||
Update: updateMap,
|
Update: updateMap,
|
||||||
}
|
}
|
||||||
path := modMeta.SetMetaName(modInfo.Slug, flags)
|
path := modMeta.SetMetaName(modInfo.Slug)
|
||||||
|
|
||||||
// If the file already exists, this will overwrite it!!!
|
// If the file already exists, this will overwrite it!!!
|
||||||
// TODO: Should this be improved?
|
// TODO: Should this be improved?
|
||||||
@ -141,45 +120,6 @@ func createModFile(flags core.Flags, modInfo modInfo, fileInfo modFileInfo, inde
|
|||||||
return index.RefreshFileWithHash(path, format, hash, true)
|
return index.RefreshFileWithHash(path, format, hash, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdDoc(flags core.Flags, mod string) error {
|
|
||||||
if len(mod) == 0 {
|
|
||||||
return cli.NewExitError("You must specify a mod.", 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Loading modpack...")
|
|
||||||
pack, err := core.LoadPack(flags)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
index, err := pack.LoadIndex()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
resolvedMod, ok := index.FindMod(mod)
|
|
||||||
if !ok {
|
|
||||||
// TODO: should this auto-refresh???????
|
|
||||||
return cli.NewExitError("You don't have this mod installed.", 1)
|
|
||||||
}
|
|
||||||
modData, err := core.LoadMod(resolvedMod)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
updateData, ok := modData.GetParsedUpdateData("curseforge")
|
|
||||||
if !ok {
|
|
||||||
return cli.NewExitError("This mod doesn't seem to be a curseforge mod!", 1)
|
|
||||||
}
|
|
||||||
cfUpdateData := updateData.(cfUpdateData)
|
|
||||||
fmt.Println("Opening browser...")
|
|
||||||
url := "https://minecraft.curseforge.com/projects/" + strconv.Itoa(cfUpdateData.ProjectID)
|
|
||||||
err = open.Start(url)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Opening page failed, direct link:")
|
|
||||||
fmt.Println(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type cfUpdateData struct {
|
type cfUpdateData struct {
|
||||||
ProjectID int `mapstructure:"project-id"`
|
ProjectID int `mapstructure:"project-id"`
|
||||||
FileID int `mapstructure:"file-id"`
|
FileID int `mapstructure:"file-id"`
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/comp500/packwiz/core"
|
"github.com/comp500/packwiz/core"
|
||||||
"github.com/urfave/cli"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type twitchPackMeta struct {
|
type twitchPackMeta struct {
|
||||||
@ -42,25 +42,34 @@ type twitchPackMeta struct {
|
|||||||
} `json:"installedAddons"`
|
} `json:"installedAddons"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdImport(flags core.Flags, file string) error {
|
// importCmd represents the import command
|
||||||
pack, err := core.LoadPack(flags)
|
var importCmd = &cobra.Command{
|
||||||
|
Use: "import",
|
||||||
|
Short: "Import an installed curseforge modpack",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pack, err := core.LoadPack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
index, err := pack.LoadIndex()
|
index, err := pack.LoadIndex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var packMeta twitchPackMeta
|
var packMeta twitchPackMeta
|
||||||
// TODO: is this relative to something?
|
// TODO: is this relative to something?
|
||||||
f, err := os.Open(file)
|
f, err := os.Open(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = json.NewDecoder(f).Decode(&packMeta)
|
err = json.NewDecoder(f).Decode(&packMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
modIDs := make([]int, len(packMeta.Mods))
|
modIDs := make([]int, len(packMeta.Mods))
|
||||||
@ -72,7 +81,8 @@ func cmdImport(flags core.Flags, file string) error {
|
|||||||
|
|
||||||
modInfos, err := getModInfoMultiple(modIDs)
|
modInfos, err := getModInfoMultiple(modIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
modInfosMap := make(map[int]modInfo)
|
modInfosMap := make(map[int]modInfo)
|
||||||
@ -94,9 +104,10 @@ func cmdImport(flags core.Flags, file string) error {
|
|||||||
|
|
||||||
fmt.Printf("Imported mod \"%s\" successfully!\n", modInfoValue.Name)
|
fmt.Printf("Imported mod \"%s\" successfully!\n", modInfoValue.Name)
|
||||||
|
|
||||||
err = createModFile(flags, modInfoValue, modFileInfo(v.File), &index)
|
err = createModFile(modInfoValue, modFileInfo(v.File), &index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,16 +115,22 @@ func cmdImport(flags core.Flags, file string) error {
|
|||||||
|
|
||||||
err = index.Write()
|
err = index.Write()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = pack.UpdateIndexHash()
|
err = pack.UpdateIndexHash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = pack.Write()
|
err = pack.Write()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
curseforgeCmd.AddCommand(importCmd)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/agnivade/levenshtein"
|
"github.com/agnivade/levenshtein"
|
||||||
"github.com/comp500/packwiz/core"
|
"github.com/comp500/packwiz/core"
|
||||||
"github.com/urfave/cli"
|
"github.com/spf13/cobra"
|
||||||
"gopkg.in/dixonwille/wmenu.v4"
|
"gopkg.in/dixonwille/wmenu.v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,34 +21,45 @@ type installableDep struct {
|
|||||||
fileInfo modFileInfo
|
fileInfo modFileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
// installCmd represents the install command
|
||||||
if len(mod) == 0 {
|
var installCmd = &cobra.Command{
|
||||||
return cli.NewExitError("You must specify a mod.", 1)
|
Use: "install",
|
||||||
|
Short: "Install a mod from a curseforge URL, slug or ID",
|
||||||
|
Aliases: []string{"add", "get"},
|
||||||
|
Args: cobra.ArbitraryArgs,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args[0]) == 0 {
|
||||||
|
fmt.Println("You must specify a mod.")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
pack, err := core.LoadPack(flags)
|
pack, err := core.LoadPack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
index, err := pack.LoadIndex()
|
index, err := pack.LoadIndex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
mcVersion, err := pack.GetMCVersion()
|
mcVersion, err := pack.GetMCVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var done bool
|
var done bool
|
||||||
var modID, fileID int
|
var modID, fileID int
|
||||||
// If modArgsTail has anything, go straight to searching - URLs/Slugs should not have spaces!
|
// If there are more than 1 argument, go straight to searching - URLs/Slugs should not have spaces!
|
||||||
if len(modArgsTail) == 0 {
|
if len(args) == 1 {
|
||||||
done, modID, fileID, err = getFileIDsFromString(mod)
|
done, modID, fileID, err = getFileIDsFromString(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
done, modID, err = getModIDFromString(mod)
|
done, modID, err = getModIDFromString(args[0])
|
||||||
// Ignore error, go to search instead (e.g. lowercase to search instead of as a slug)
|
// Ignore error, go to search instead (e.g. lowercase to search instead of as a slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
done = false
|
done = false
|
||||||
@ -61,15 +72,16 @@ func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
|||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
fmt.Println("Searching CurseForge...")
|
fmt.Println("Searching CurseForge...")
|
||||||
modArgs := append([]string{mod}, modArgsTail...)
|
searchTerm := strings.Join(args, " ")
|
||||||
searchTerm := strings.Join(modArgs, " ")
|
|
||||||
results, err := getSearch(searchTerm, mcVersion)
|
results, err := getSearch(searchTerm, mcVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(results) == 0 {
|
if len(results) == 0 {
|
||||||
return cli.NewExitError("No mods found!", 1)
|
fmt.Println("No mods found!")
|
||||||
|
os.Exit(1)
|
||||||
} else if len(results) == 1 {
|
} else if len(results) == 1 {
|
||||||
modInfoData = results[0]
|
modInfoData = results[0]
|
||||||
modID = modInfoData.ID
|
modID = modInfoData.ID
|
||||||
@ -98,7 +110,8 @@ func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
|||||||
var ok bool
|
var ok bool
|
||||||
modInfoData, ok = menuRes[0].Value.(modInfo)
|
modInfoData, ok = menuRes[0].Value.(modInfo)
|
||||||
if !ok {
|
if !ok {
|
||||||
return cli.NewExitError("Error converting interface from wmenu", 1)
|
fmt.Println("Error converting interface from wmenu")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
modID = modInfoData.ID
|
modID = modInfoData.ID
|
||||||
modInfoObtained = true
|
modInfoObtained = true
|
||||||
@ -107,33 +120,38 @@ func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
|||||||
})
|
})
|
||||||
err = menu.Run()
|
err = menu.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return cli.NewExitError("No mods found!", 1)
|
fmt.Println("No mods found!")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !modInfoObtained {
|
if !modInfoObtained {
|
||||||
modInfoData, err = getModInfo(modID)
|
modInfoData, err = getModInfo(modID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileInfoData modFileInfo
|
var fileInfoData modFileInfo
|
||||||
fileInfoData, err = getLatestFile(modInfoData, mcVersion, fileID)
|
fileInfoData, err = getLatestFile(modInfoData, mcVersion, fileID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fileInfoData.Dependencies) > 0 {
|
if len(fileInfoData.Dependencies) > 0 {
|
||||||
@ -218,7 +236,8 @@ func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
|||||||
cycles++
|
cycles++
|
||||||
}
|
}
|
||||||
if cycles >= maxCycles {
|
if cycles >= maxCycles {
|
||||||
return cli.NewExitError("Dependencies recurse too deeply! Try increasing maxCycles.", 1)
|
fmt.Println("Dependencies recurse too deeply! Try increasing maxCycles.")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(depsInstallable) > 0 {
|
if len(depsInstallable) > 0 {
|
||||||
@ -230,15 +249,17 @@ func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
|||||||
fmt.Print("Would you like to install them? [Y/n]: ")
|
fmt.Print("Would you like to install them? [Y/n]: ")
|
||||||
answer, err := bufio.NewReader(os.Stdin).ReadString('\n')
|
answer, err := bufio.NewReader(os.Stdin).ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
ansNormal := strings.ToLower(strings.TrimSpace(answer))
|
ansNormal := strings.ToLower(strings.TrimSpace(answer))
|
||||||
if !(len(ansNormal) > 0 && ansNormal[0] == 'n') {
|
if !(len(ansNormal) > 0 && ansNormal[0] == 'n') {
|
||||||
for _, v := range depsInstallable {
|
for _, v := range depsInstallable {
|
||||||
err = createModFile(flags, v.modInfo, v.fileInfo, &index)
|
err = createModFile(v.modInfo, v.fileInfo, &index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Printf("Dependency \"%s\" successfully installed! (%s)\n", v.modInfo.Name, v.fileInfo.FileName)
|
fmt.Printf("Dependency \"%s\" successfully installed! (%s)\n", v.modInfo.Name, v.fileInfo.FileName)
|
||||||
}
|
}
|
||||||
@ -249,27 +270,30 @@ func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = createModFile(flags, modInfoData, fileInfoData, &index)
|
err = createModFile(modInfoData, fileInfoData, &index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = index.Write()
|
err = index.Write()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = pack.UpdateIndexHash()
|
err = pack.UpdateIndexHash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = pack.Write()
|
err = pack.Write()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Mod \"%s\" successfully installed! (%s)\n", modInfoData.Name, fileInfoData.FileName)
|
fmt.Printf("Mod \"%s\" successfully installed! (%s)\n", modInfoData.Name, fileInfoData.FileName)
|
||||||
|
},
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileInfo, error) {
|
func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileInfo, error) {
|
||||||
@ -300,3 +324,7 @@ func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileIn
|
|||||||
}
|
}
|
||||||
return fileInfoData, nil
|
return fileInfoData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
curseforgeCmd.AddCommand(installCmd)
|
||||||
|
}
|
||||||
|
66
curseforge/open.go
Normal file
66
curseforge/open.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package curseforge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/comp500/packwiz/core"
|
||||||
|
"github.com/skratchdot/open-golang/open"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// openCmd represents the open command
|
||||||
|
var openCmd = &cobra.Command{
|
||||||
|
Use: "open",
|
||||||
|
// TODO: change semantics to "project" rather than "mod", as this supports texture packs and misc content as well?
|
||||||
|
Short: "Open the project page for a curseforge mod in your browser",
|
||||||
|
Aliases: []string{"doc"},
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if len(args[0]) == 0 {
|
||||||
|
fmt.Println("You must specify a mod.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Loading modpack...")
|
||||||
|
pack, err := core.LoadPack()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
index, err := pack.LoadIndex()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
resolvedMod, ok := index.FindMod(args[0])
|
||||||
|
if !ok {
|
||||||
|
// TODO: should this auto-refresh???????
|
||||||
|
fmt.Println("You don't have this mod installed.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
modData, err := core.LoadMod(resolvedMod)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
updateData, ok := modData.GetParsedUpdateData("curseforge")
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("This mod doesn't seem to be a curseforge mod!")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
cfUpdateData := updateData.(cfUpdateData)
|
||||||
|
fmt.Println("Opening browser...")
|
||||||
|
url := "https://minecraft.curseforge.com/projects/" + strconv.Itoa(cfUpdateData.ProjectID)
|
||||||
|
err = open.Start(url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Opening page failed, direct link:")
|
||||||
|
fmt.Println(url)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
curseforgeCmd.AddCommand(openCmd)
|
||||||
|
}
|
7
go.mod
7
go.mod
@ -4,18 +4,17 @@ require (
|
|||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/agnivade/levenshtein v1.0.2
|
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/davecgh/go-spew v1.1.1 // 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
|
||||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 // indirect
|
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 // indirect
|
||||||
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/mattn/go-isatty v0.0.4 // indirect
|
github.com/mattn/go-isatty v0.0.4 // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/mitchellh/mapstructure v1.1.2
|
github.com/mitchellh/mapstructure v1.1.2
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e
|
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e
|
||||||
github.com/stretchr/testify v1.2.2 // indirect
|
github.com/spf13/cobra v0.0.5
|
||||||
github.com/urfave/cli v1.20.0
|
github.com/spf13/viper v1.4.0
|
||||||
github.com/vbauerster/mpb/v4 v4.7.0
|
github.com/vbauerster/mpb/v4 v4.7.0
|
||||||
gopkg.in/dixonwille/wlog.v2 v2.0.0 // indirect
|
gopkg.in/dixonwille/wlog.v2 v2.0.0 // indirect
|
||||||
gopkg.in/dixonwille/wmenu.v4 v4.0.2
|
gopkg.in/dixonwille/wmenu.v4 v4.0.2
|
||||||
|
139
go.sum
139
go.sum
@ -1,9 +1,25 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
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 h1:xKF7WlEzoa+ZVkzBxy0ukdzI2etYiWGlTPMNTBGncKI=
|
||||||
github.com/agnivade/levenshtein v1.0.2/go.mod h1:JLvzGblJATanj48SD0YhHTEFGkWvw3ASLFWSiMIFXsE=
|
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=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
@ -12,36 +28,155 @@ github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920 h1:d/cVoZ
|
|||||||
github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||||
github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817 h1:0nsrg//Dc7xC74H/TZ5sYR8uk4UQRNjsw8zejqH5a4Q=
|
github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817 h1:0nsrg//Dc7xC74H/TZ5sYR8uk4UQRNjsw8zejqH5a4Q=
|
||||||
github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817/go.mod h1:C/+sI4IFnEpCn6VQ3GIPEp+FrQnQw+YQP3+n+GdGq7o=
|
github.com/denormal/go-gitignore v0.0.0-20180930084346-ae8ad1d07817/go.mod h1:C/+sI4IFnEpCn6VQ3GIPEp+FrQnQw+YQP3+n+GdGq7o=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 h1:7xqw01UYS+KCI25bMrPxwNYkSns2Db1ziQPpVq99FpE=
|
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 h1:7xqw01UYS+KCI25bMrPxwNYkSns2Db1ziQPpVq99FpE=
|
||||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 h1:f5gsjBiF9tRRVomCvrkGMMWI8W1f2OBFar2c5oakAP0=
|
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 h1:f5gsjBiF9tRRVomCvrkGMMWI8W1f2OBFar2c5oakAP0=
|
||||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZPbFy2P7jH5LKJ3La+0ZeknkkmrSgqb0=
|
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZPbFy2P7jH5LKJ3La+0ZeknkkmrSgqb0=
|
||||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||||
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
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/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=
|
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
|
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
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=
|
||||||
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||||
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/vbauerster/mpb/v4 v4.7.0 h1:Et+zVewxG6qmfBf4Ez+nDhLbCSh6WhZrUPHg9a6e+hw=
|
github.com/vbauerster/mpb/v4 v4.7.0 h1:Et+zVewxG6qmfBf4Ez+nDhLbCSh6WhZrUPHg9a6e+hw=
|
||||||
github.com/vbauerster/mpb/v4 v4.7.0/go.mod h1:ugxYn2kSUrY10WK5CWDUZvQxjdwKFN9K3Ja3/z6p4X0=
|
github.com/vbauerster/mpb/v4 v4.7.0/go.mod h1:ugxYn2kSUrY10WK5CWDUZvQxjdwKFN9K3Ja3/z6p4X0=
|
||||||
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872 h1:cGjJzUd8RgBw428LXP65YXni0aiGNA4Bl+ls8SmLOm8=
|
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872 h1:cGjJzUd8RgBw428LXP65YXni0aiGNA4Bl+ls8SmLOm8=
|
||||||
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/dixonwille/wlog.v2 v2.0.0 h1:TbGWtD8ahWVSihKKr+z2Dw7Cv/7IrfN6dwrcrre17pU=
|
gopkg.in/dixonwille/wlog.v2 v2.0.0 h1:TbGWtD8ahWVSihKKr+z2Dw7Cv/7IrfN6dwrcrre17pU=
|
||||||
gopkg.in/dixonwille/wlog.v2 v2.0.0/go.mod h1:JYQHRnhGPLno/iATOiGkEXoRanJXqdz9Qo6/QwfARUc=
|
gopkg.in/dixonwille/wlog.v2 v2.0.0/go.mod h1:JYQHRnhGPLno/iATOiGkEXoRanJXqdz9Qo6/QwfARUc=
|
||||||
gopkg.in/dixonwille/wmenu.v4 v4.0.2 h1:QZVHQatLr41TOvVWiNGdwGk2DYtGEljtuxyrEdR0JIQ=
|
gopkg.in/dixonwille/wmenu.v4 v4.0.2 h1:QZVHQatLr41TOvVWiNGdwGk2DYtGEljtuxyrEdR0JIQ=
|
||||||
gopkg.in/dixonwille/wmenu.v4 v4.0.2/go.mod h1:qgH60HxGljYu/uXZW8ctlQ8nIf5mhmraJ3Vsksexnqk=
|
gopkg.in/dixonwille/wmenu.v4 v4.0.2/go.mod h1:qgH60HxGljYu/uXZW8ctlQ8nIf5mhmraJ3Vsksexnqk=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
309
main.go
309
main.go
@ -1,316 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"bufio"
|
|
||||||
|
|
||||||
"github.com/comp500/packwiz/core"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
|
|
||||||
// Modules of packwiz
|
// Modules of packwiz
|
||||||
|
"github.com/comp500/packwiz/cmd"
|
||||||
_ "github.com/comp500/packwiz/curseforge"
|
_ "github.com/comp500/packwiz/curseforge"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
core.Commands = append(core.Commands, cli.Command{
|
|
||||||
Name: "remove",
|
|
||||||
Aliases: []string{"delete", "uninstall"},
|
|
||||||
Usage: "Remove a mod from the modpack",
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
return cmdDelete(core.FlagsFromContext(c), c.Args().Get(0))
|
|
||||||
},
|
|
||||||
}, cli.Command{
|
|
||||||
Name: "update",
|
|
||||||
Aliases: []string{"upgrade"},
|
|
||||||
Usage: "Update a mod (or all mods) in the modpack",
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
return cmdUpdate(core.FlagsFromContext(c), c.Args().Get(0))
|
|
||||||
},
|
|
||||||
}, cli.Command{
|
|
||||||
Name: "refresh",
|
|
||||||
Usage: "Refresh the index file",
|
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
return cmdRefresh(core.FlagsFromContext(c))
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func main() {
|
func main() {
|
||||||
app := cli.NewApp()
|
cmd.Execute()
|
||||||
app.Commands = core.Commands
|
|
||||||
app.Flags = core.CLIFlags[:]
|
|
||||||
app.HideVersion = true
|
|
||||||
app.Usage = "A command line tool for creating Minecraft modpacks."
|
|
||||||
|
|
||||||
err := app.Run(os.Args)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdDelete(flags core.Flags, mod string) error {
|
|
||||||
if len(mod) == 0 {
|
|
||||||
return cli.NewExitError("You must specify a mod.", 1)
|
|
||||||
}
|
|
||||||
fmt.Println("Loading modpack...")
|
|
||||||
pack, err := core.LoadPack(flags)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
index, err := pack.LoadIndex()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
resolvedMod, ok := index.FindMod(mod)
|
|
||||||
if !ok {
|
|
||||||
return cli.NewExitError("You don't have this mod installed.", 1)
|
|
||||||
}
|
|
||||||
err = os.Remove(resolvedMod)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
fmt.Println("Removing mod from index...")
|
|
||||||
err = index.RemoveFile(resolvedMod)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = index.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = pack.UpdateIndexHash()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = pack.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Mod %s removed successfully!", mod)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdRefresh(flags core.Flags) error {
|
|
||||||
fmt.Println("Loading modpack...")
|
|
||||||
pack, err := core.LoadPack(flags)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
index, err := pack.LoadIndex()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = index.Refresh()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = index.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = pack.UpdateIndexHash()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = pack.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
fmt.Println("Index refreshed!")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdUpdate(flags core.Flags, mod string) error {
|
|
||||||
// TODO: --check flag?
|
|
||||||
// TODO: specify multiple mods to update at once?
|
|
||||||
|
|
||||||
fmt.Println("Loading modpack...")
|
|
||||||
pack, err := core.LoadPack(flags)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
index, err := pack.LoadIndex()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
mcVersion, err := pack.GetMCVersion()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
multiple := false
|
|
||||||
var singleUpdatedName string
|
|
||||||
if len(mod) == 0 || mod == "*" {
|
|
||||||
multiple = true
|
|
||||||
|
|
||||||
updaterMap := make(map[string][]core.Mod)
|
|
||||||
fmt.Println("Reading mod files...")
|
|
||||||
for _, v := range index.GetAllMods() {
|
|
||||||
modData, err := core.LoadMod(v)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error reading mod file: %s", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
updaterFound := false
|
|
||||||
for k := range modData.Update {
|
|
||||||
slice, ok := updaterMap[k]
|
|
||||||
if !ok {
|
|
||||||
_, ok = core.Updaters[k]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
slice = []core.Mod{}
|
|
||||||
}
|
|
||||||
updaterFound = true
|
|
||||||
updaterMap[k] = append(slice, modData)
|
|
||||||
}
|
|
||||||
if !updaterFound {
|
|
||||||
fmt.Printf("A supported update system for \"%s\" cannot be found.", modData.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Checking for updates...")
|
|
||||||
updatesFound := false
|
|
||||||
updaterPointerMap := make(map[string][]*core.Mod)
|
|
||||||
updaterCachedStateMap := make(map[string][]interface{})
|
|
||||||
for k, v := range updaterMap {
|
|
||||||
checks, err := core.Updaters[k].CheckUpdate(v, mcVersion)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: do we return err code 1?
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for i, check := range checks {
|
|
||||||
if check.Error != nil {
|
|
||||||
// TODO: do we return err code 1?
|
|
||||||
// TODO: better error message?
|
|
||||||
fmt.Println(check.Error.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if check.UpdateAvailable {
|
|
||||||
if !updatesFound {
|
|
||||||
fmt.Println("Updates found:")
|
|
||||||
updatesFound = true
|
|
||||||
}
|
|
||||||
fmt.Printf("%s: %s\n", v[i].Name, check.UpdateString)
|
|
||||||
updaterPointerMap[k] = append(updaterPointerMap[k], &v[i])
|
|
||||||
updaterCachedStateMap[k] = append(updaterCachedStateMap[k], check.CachedState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !updatesFound {
|
|
||||||
fmt.Println("All mods are up to date!")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Print("Do you want to update? [Y/n]: ")
|
|
||||||
answer, err := bufio.NewReader(os.Stdin).ReadString('\n')
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
ansNormal := strings.ToLower(strings.TrimSpace(answer))
|
|
||||||
if len(ansNormal) > 0 && ansNormal[0] == 'n' {
|
|
||||||
fmt.Println("Cancelled!")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range updaterPointerMap {
|
|
||||||
err := core.Updaters[k].DoUpdate(v, updaterCachedStateMap[k])
|
|
||||||
if err != nil {
|
|
||||||
// TODO: do we return err code 1?
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, modData := range v {
|
|
||||||
format, hash, err := modData.Write()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = index.RefreshFileWithHash(modData.GetFilePath(), format, hash, true)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
modPath, ok := index.FindMod(mod)
|
|
||||||
if !ok {
|
|
||||||
return cli.NewExitError("You don't have this mod installed.", 1)
|
|
||||||
}
|
|
||||||
modData, err := core.LoadMod(modPath)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
singleUpdatedName = modData.Name
|
|
||||||
updaterFound := false
|
|
||||||
for k := range modData.Update {
|
|
||||||
updater, ok := core.Updaters[k]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
updaterFound = true
|
|
||||||
|
|
||||||
check, err := updater.CheckUpdate([]core.Mod{modData}, mcVersion)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
if len(check) != 1 {
|
|
||||||
return cli.NewExitError("Invalid update check response", 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if check[0].UpdateAvailable {
|
|
||||||
fmt.Printf("Update available: %s\n", check[0].UpdateString)
|
|
||||||
|
|
||||||
err = updater.DoUpdate([]*core.Mod{&modData}, []interface{}{check[0].CachedState})
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
format, hash, err := modData.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = index.RefreshFileWithHash(modPath, format, hash, true)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Printf("\"%s\" is already up to date!\n", modData.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if !updaterFound {
|
|
||||||
// TODO: use file name instead of Name when len(Name) == 0 in all places?
|
|
||||||
return cli.NewExitError("A supported update system for \""+modData.Name+"\" cannot be found.", 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = index.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = pack.UpdateIndexHash()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
err = pack.Write()
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
if multiple {
|
|
||||||
fmt.Println("Mods updated!")
|
|
||||||
} else {
|
|
||||||
fmt.Printf("\"%s\" updated!\n", singleUpdatedName)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user