ficsit-cli-flake/cmd/root.go

183 lines
5.9 KiB
Go
Raw Normal View History

2021-11-05 21:42:49 +00:00
package cmd
import (
"fmt"
"log/slog"
2021-12-02 04:00:33 +00:00
"os"
"path/filepath"
2022-04-14 01:27:39 +00:00
"runtime"
2021-12-02 04:00:33 +00:00
"time"
"github.com/lmittmann/tint"
2021-11-05 21:42:49 +00:00
"github.com/pterm/pterm"
slogmulti "github.com/samber/slog-multi"
2022-06-22 22:24:35 +00:00
"github.com/spf13/cobra"
"github.com/spf13/viper"
2022-06-08 20:56:32 +00:00
"github.com/satisfactorymodding/ficsit-cli/cmd/installation"
"github.com/satisfactorymodding/ficsit-cli/cmd/mod"
"github.com/satisfactorymodding/ficsit-cli/cmd/profile"
2022-10-14 16:11:16 +00:00
"github.com/satisfactorymodding/ficsit-cli/cmd/smr"
2021-11-05 21:42:49 +00:00
)
2022-06-08 20:56:32 +00:00
var RootCmd = &cobra.Command{
2021-11-05 21:42:49 +00:00
Use: "ficsit",
Short: "cli mod manager for satisfactory",
2021-12-02 04:00:33 +00:00
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
2021-11-05 21:42:49 +00:00
viper.SetConfigName("config")
viper.AddConfigPath(".")
viper.SetEnvPrefix("ficsit")
viper.AutomaticEnv()
_ = viper.ReadInConfig()
handlers := make([]slog.Handler, 0)
2021-11-05 21:42:49 +00:00
if viper.GetBool("pretty") {
pterm.EnableStyling()
2021-12-02 04:00:33 +00:00
} else {
pterm.DisableStyling()
}
const (
ansiReset = "\033[0m"
ansiBold = "\033[1m"
ansiWhite = "\033[38m"
ansiBrightMagenta = "\033[95m"
)
level := slog.LevelInfo
if err := (&level).UnmarshalText([]byte(viper.GetString("log"))); err != nil {
return fmt.Errorf("failed parsing level: %w", err)
}
2021-12-02 04:00:33 +00:00
if !viper.GetBool("quiet") {
handlers = append(handlers, tint.NewHandler(os.Stdout, &tint.Options{
Level: level,
AddSource: true,
TimeFormat: time.RFC3339Nano,
ReplaceAttr: func(groups []string, attr slog.Attr) slog.Attr {
if attr.Key == slog.LevelKey {
level := attr.Value.Any().(slog.Level)
if level == slog.LevelDebug {
attr.Value = slog.StringValue(ansiBrightMagenta + "DBG" + ansiReset)
}
} else if attr.Key == slog.MessageKey {
attr.Value = slog.StringValue(ansiBold + ansiWhite + fmt.Sprint(attr.Value.Any()) + ansiReset)
}
return attr
},
}))
2021-11-05 21:42:49 +00:00
}
2021-12-02 04:00:33 +00:00
if viper.GetString("log-file") != "" {
2022-10-14 16:11:16 +00:00
logFile, err := os.OpenFile(viper.GetString("log-file"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o777)
2021-12-02 04:00:33 +00:00
if err != nil {
return fmt.Errorf("failed to open log file: %w", err)
2021-12-02 04:00:33 +00:00
}
handlers = append(handlers, slog.NewJSONHandler(logFile, &slog.HandlerOptions{}))
2021-12-02 04:00:33 +00:00
}
slog.SetDefault(slog.New(
slogmulti.Fanout(handlers...),
))
2021-12-02 04:00:33 +00:00
return nil
2021-11-05 21:42:49 +00:00
},
}
2022-06-06 23:55:26 +00:00
func Execute(version string, commit string) {
2021-11-05 21:42:49 +00:00
// Execute tea as default
2022-06-08 20:56:32 +00:00
cmd, _, err := RootCmd.Find(os.Args[1:])
2021-12-02 04:00:33 +00:00
2021-12-04 18:02:05 +00:00
// Allow opening via explorer
cobra.MousetrapHelpText = ""
2021-12-02 04:00:33 +00:00
cli := len(os.Args) >= 2 && os.Args[1] == "cli"
if (len(os.Args) <= 1 || (os.Args[1] != "help" && os.Args[1] != "--help" && os.Args[1] != "-h")) && (err != nil || cmd == RootCmd) {
2021-12-02 04:00:33 +00:00
args := append([]string{"cli"}, os.Args[1:]...)
2022-06-08 20:56:32 +00:00
RootCmd.SetArgs(args)
2021-12-02 04:00:33 +00:00
cli = true
}
// Always be quiet in CLI mode
if cli {
viper.Set("quiet", true)
2021-11-05 21:42:49 +00:00
}
2022-06-06 23:55:26 +00:00
viper.Set("version", version)
viper.Set("commit", commit)
2022-06-08 20:56:32 +00:00
if err := RootCmd.Execute(); err != nil {
slog.Error(err.Error())
os.Exit(1)
2021-11-05 21:42:49 +00:00
}
}
func init() {
2022-06-08 20:56:32 +00:00
RootCmd.AddCommand(cliCmd)
RootCmd.AddCommand(applyCmd)
RootCmd.AddCommand(versionCmd)
RootCmd.AddCommand(searchCmd)
RootCmd.AddCommand(profile.Cmd)
RootCmd.AddCommand(installation.Cmd)
RootCmd.AddCommand(mod.Cmd)
2022-10-14 16:11:16 +00:00
RootCmd.AddCommand(smr.Cmd)
2022-06-08 20:56:32 +00:00
2022-04-14 01:27:39 +00:00
var baseLocalDir string
switch runtime.GOOS {
case "windows":
baseLocalDir = os.Getenv("APPDATA")
case "linux":
2022-06-05 01:56:46 +00:00
baseLocalDir = filepath.Join(os.Getenv("HOME"), ".local", "share")
2022-04-14 01:27:39 +00:00
default:
panic("unsupported platform: " + runtime.GOOS)
}
viper.Set("base-local-dir", baseLocalDir)
2021-11-05 21:42:49 +00:00
baseCacheDir, err := os.UserCacheDir()
if err != nil {
panic(err)
}
2022-06-08 20:56:32 +00:00
RootCmd.PersistentFlags().String("log", "info", "The log level to output")
RootCmd.PersistentFlags().String("log-file", "", "File to output logs to")
RootCmd.PersistentFlags().Bool("quiet", false, "Do not log anything to console")
RootCmd.PersistentFlags().Bool("pretty", true, "Whether to render pretty terminal output")
2021-11-05 21:42:49 +00:00
2022-06-08 20:56:32 +00:00
RootCmd.PersistentFlags().Bool("dry-run", false, "Dry-run. Do not save any changes")
2021-12-02 04:00:33 +00:00
2022-06-08 20:56:32 +00:00
RootCmd.PersistentFlags().String("cache-dir", filepath.Clean(filepath.Join(baseCacheDir, "ficsit")), "The cache directory")
RootCmd.PersistentFlags().String("local-dir", filepath.Clean(filepath.Join(baseLocalDir, "ficsit")), "The local directory")
RootCmd.PersistentFlags().String("profiles-file", "profiles.json", "The profiles file")
RootCmd.PersistentFlags().String("installations-file", "installations.json", "The installations file")
2021-12-02 04:00:33 +00:00
2022-06-08 20:56:32 +00:00
RootCmd.PersistentFlags().String("api-base", "https://api.ficsit.app", "URL for API")
RootCmd.PersistentFlags().String("graphql-api", "/v2/query", "Path for GraphQL API")
2022-10-14 16:11:16 +00:00
RootCmd.PersistentFlags().String("api-key", "", "API key to use when sending requests")
2021-11-05 21:42:49 +00:00
RootCmd.PersistentFlags().Bool("offline", false, "Whether to only use local data")
RootCmd.PersistentFlags().Int("concurrent-downloads", 5, "Maximum number of concurrent downloads")
2022-06-08 20:56:32 +00:00
_ = viper.BindPFlag("log", RootCmd.PersistentFlags().Lookup("log"))
_ = viper.BindPFlag("log-file", RootCmd.PersistentFlags().Lookup("log-file"))
_ = viper.BindPFlag("quiet", RootCmd.PersistentFlags().Lookup("quiet"))
_ = viper.BindPFlag("pretty", RootCmd.PersistentFlags().Lookup("pretty"))
2021-11-05 21:42:49 +00:00
2022-06-08 20:56:32 +00:00
_ = viper.BindPFlag("dry-run", RootCmd.PersistentFlags().Lookup("dry-run"))
2021-12-02 04:00:33 +00:00
2022-06-08 20:56:32 +00:00
_ = viper.BindPFlag("cache-dir", RootCmd.PersistentFlags().Lookup("cache-dir"))
_ = viper.BindPFlag("local-dir", RootCmd.PersistentFlags().Lookup("local-dir"))
_ = viper.BindPFlag("profiles-file", RootCmd.PersistentFlags().Lookup("profiles-file"))
_ = viper.BindPFlag("installations-file", RootCmd.PersistentFlags().Lookup("installations-file"))
2021-12-02 04:00:33 +00:00
2022-06-08 20:56:32 +00:00
_ = viper.BindPFlag("api-base", RootCmd.PersistentFlags().Lookup("api-base"))
_ = viper.BindPFlag("graphql-api", RootCmd.PersistentFlags().Lookup("graphql-api"))
2022-10-14 16:11:16 +00:00
_ = viper.BindPFlag("api-key", RootCmd.PersistentFlags().Lookup("api-key"))
_ = viper.BindPFlag("offline", RootCmd.PersistentFlags().Lookup("offline"))
_ = viper.BindPFlag("concurrent-downloads", RootCmd.PersistentFlags().Lookup("concurrent-downloads"))
2021-11-05 21:42:49 +00:00
}