diff --git a/cmd/fml/fml.go b/cmd/fml/fml.go index 1e014d2..4e5df2d 100644 --- a/cmd/fml/fml.go +++ b/cmd/fml/fml.go @@ -1,48 +1,147 @@ package main import ( + "fmt" "os" + "runtime" "time" "git.burning.moe/celediel/fml/internal/modlist" "git.burning.moe/celediel/fml/internal/prompt" "github.com/charmbracelet/log" + "github.com/urfave/cli/v2" ) -// TODO: set this per os to support Windows + Mac -var modsdir string = os.Getenv("HOME") + "/.factorio/mods" -var modlistfile string = modsdir + "/mod-list.json" +type config struct { + modsdir, infile, outfile string + mods modlist.Modlist + clobber bool +} + +var cfg config + +func getModsDirFromEnv() string { + var dir string + + switch runtime.GOOS { + case "darwin": + dir = os.Getenv("HOME") + "/Library/Application Support/factorio/mods" + case "windows": + dir = os.Getenv("APPDATA") + "\\Factorio\\mods" + default: + fallthrough + case "linux": + dir = os.Getenv("HOME") + "/.factorio/mods" + } + + return dir +} func main() { - // load this from config or cli option or env or something - log.SetLevel(log.WarnLevel) - log.SetTimeFormat(time.TimeOnly) - log.SetReportCaller(true) + cfg = config{} - mods, err := modlist.ReadFromFile(modlistfile) - if err != nil { - log.Fatal(err) + app := &cli.App{ + Name: "fml", + Usage: "very simple modlist editor for factorio", + Version: "v0.0.0", + Authors: []*cli.Author{{ + Name: "Lilian Jónsdóttir", + Email: "lilian.jonsdottir@gmail.com", + }}, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "log", + Usage: "Log level", + Value: "warn", + }, + &cli.PathFlag{ + Name: "infile", + Aliases: []string{"i"}, + Required: false, + Usage: "alternative mod-list.json to read", + }, + &cli.PathFlag{ + Name: "outfile", + Aliases: []string{"o"}, + Required: false, + Usage: "alternative mod-list.json to write", + }, + &cli.BoolFlag{ + Name: "clobber", + Aliases: []string{"c"}, + Required: false, + Usage: "overwrite specified infile", + }, + }, + Before: func(ctx *cli.Context) error { + // Setup logger + if lvl, err := log.ParseLevel(ctx.String("log")); err != nil { + log.SetLevel(log.WarnLevel) + } else { + log.SetLevel(lvl) + } + log.SetReportCaller(log.GetLevel() == log.DebugLevel) + log.SetTimeFormat(time.TimeOnly) + + // Bool flags + cfg.clobber = ctx.Bool("clobber") + + // Deal with in/out file + var in = ctx.String("infile") + var out = ctx.String("outfile") + + cfg.modsdir = getModsDirFromEnv() + if in == "" { + cfg.infile = fmt.Sprintf("%s%c%s", cfg.modsdir, os.PathSeparator, "mod-list.json") + } else { + cfg.infile = in + } + + if out == "" && in != "" && !cfg.clobber { + log.Fatal("Pass --clobber or -c to overwrite the input file!") + } else if out == "" { + cfg.outfile = cfg.infile + } else if out != "" { + cfg.outfile = out + } + + return nil + }, + Action: func(ctx *cli.Context) error { + var err error + + cfg.mods, err = modlist.ReadFromFile(cfg.infile) + if err != nil { + return err + } + + err = modlist.AddModsNotInList(cfg.modsdir, &cfg.mods) + if err != nil { + return err + } + selected, err := prompt.Show(&cfg.mods) + if err != nil { + log.Fatal(err) + } + + // TODO: handle this in a better way + // TODO: list intersections or something + cfg.mods.DisableAll() + + cfg.mods.EnableMods(selected...) + + err = modlist.WriteToFile(cfg.outfile, &cfg.mods) + if err != nil { + return err + } + + log.Print("All done, bye!") + return nil + }, } - err = modlist.AddModsNotInList(modsdir, &mods) - if err != nil { - log.Fatal(err) - } - - selected, err := prompt.Show(&mods) - if err != nil { - log.Fatal(err) - } - - // TODO: handle this in a better way - // TODO: list intersections or something - mods.DisableAll() - - mods.EnableMods(selected...) - - err = modlist.WriteToFile(modlistfile, &mods) - if err != nil { + if err := app.Run(os.Args); err != nil { log.Fatal(err) } } diff --git a/go.mod b/go.mod index 1c2096d..487625e 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/charmbracelet/huh v0.3.0 github.com/charmbracelet/log v0.3.1 github.com/magefile/mage v1.15.0 + github.com/urfave/cli/v2 v2.27.1 ) require ( @@ -16,6 +17,7 @@ require ( github.com/charmbracelet/bubbletea v0.25.0 // indirect github.com/charmbracelet/lipgloss v0.9.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -26,6 +28,8 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.13.0 // indirect diff --git a/go.sum b/go.sum index c705d2d..fcd204a 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMT github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= @@ -45,8 +47,14 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=