From 303670e43adb43f9c8e1c6c0b3cf05bdf317c701 Mon Sep 17 00:00:00 2001 From: VetheonGames Date: Wed, 27 Mar 2024 02:11:46 -0600 Subject: [PATCH] setup basic CLI and config commands --- cmd/config.go | 82 +++++++++++++++++++++++++++++++++++++ cmd/root.go | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- main.go | 15 +++++++ 4 files changed, 207 insertions(+), 1 deletion(-) diff --git a/cmd/config.go b/cmd/config.go index e69de29..d5dcb40 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -0,0 +1,82 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "os" + "os/exec" + "path/filepath" +) + +const configDir = "/etc/PixelRidge/BackupGo" +const configFile = "config.json" + +// Config represents the application's configuration +type Config struct { + S3ConnectionInfo string `json:"s3_connection_info"` + // Add other configuration options here, all as strings or booleans +} + +// LoadConfig loads the configuration from the JSON file +func LoadConfig() (*Config, error) { + configPath := filepath.Join(configDir, configFile) + file, err := os.Open(configPath) + if err != nil { + return nil, err + } + defer file.Close() + + config := &Config{} + decoder := json.NewDecoder(file) + if err := decoder.Decode(config); err != nil { + return nil, err + } + + return config, nil +} + +// SaveConfig saves the modified configuration back to the JSON file +func SaveConfig(config *Config) error { + configPath := filepath.Join(configDir, configFile) + file, err := os.Create(configPath) + if err != nil { + return err + } + defer file.Close() + + encoder := json.NewEncoder(file) + if err := encoder.Encode(config); err != nil { + return err + } + + return nil +} + +// EditConfigOption allows editing a specific configuration option from the CLI +func EditConfigOption(optionName, newValue string) error { + config, err := LoadConfig() + if err != nil { + return err + } + + // Reflect or a simple switch can be used to match the optionName to Config fields + switch optionName { + case "s3_connection_info": + config.S3ConnectionInfo = newValue + // Add cases for other options here + default: + return fmt.Errorf("unknown configuration option: %s", optionName) + } + + return SaveConfig(config) +} + +// OpenConfigInNano opens the configuration file in the nano editor +func OpenConfigInNano() error { + configPath := filepath.Join(configDir, configFile) + cmd := exec.Command("nano", configPath) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} diff --git a/cmd/root.go b/cmd/root.go index e69de29..0b7bfd1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -0,0 +1,109 @@ +package cmd + +import ( + "flag" + "fmt" +) + +// Command represents a CLI command. +type Command struct { + Name string + Description string + FlagSet *flag.FlagSet + SubCommands map[string]*Command + Execute func(cmd *Command, args []string) +} + +// RootCmd is now defined at the package level, making it accessible from other packages. +var RootCmd = NewCommand("backup", "Main entry point for backup utility", nil) + +// NewCommand creates a new command instance. +func NewCommand(name, description string, execute func(cmd *Command, args []string)) *Command { + return &Command{ + Name: name, + Description: description, + FlagSet: flag.NewFlagSet(name, flag.ExitOnError), + SubCommands: make(map[string]*Command), + Execute: execute, + } +} + +// AddSubCommand adds a subcommand to a command. +func (c *Command) AddSubCommand(subCmd *Command) { + c.SubCommands[subCmd.Name] = subCmd +} + +// FindSubCommand looks for a subcommand by name. +func (c *Command) FindSubCommand(name string) (*Command, bool) { + subCmd, found := c.SubCommands[name] + return subCmd, found +} + +// ExecuteCommand executes the command with the provided arguments. +func ExecuteCommand(rootCmd *Command, args []string) error { + if len(args) < 1 { + fmt.Println("No command provided") + return nil + } + + cmdName := args[0] + subArgs := args[1:] + + cmd, found := rootCmd.FindSubCommand(cmdName) + if !found { + fmt.Printf("Unknown command: %s\n", cmdName) + return nil + } + + // Look for sub-subcommands if applicable. + if len(subArgs) > 0 { + subCmdName := subArgs[0] + subCmd, found := cmd.FindSubCommand(subCmdName) + if found { + // Parse flags for sub-subcommands. + subCmd.FlagSet.Parse(subArgs[1:]) + subCmd.Execute(subCmd, subCmd.FlagSet.Args()) + return nil + } + } + + // Parse flags for direct subcommands. + cmd.FlagSet.Parse(subArgs) + cmd.Execute(cmd, cmd.FlagSet.Args()) + return nil +} + +func init() { + configCmd := NewCommand("config", "Configuration management", nil) + + editCmd := NewCommand("edit", "Edit a configuration option", func(cmd *Command, args []string) { + configOption := cmd.FlagSet.Lookup("config-option").Value.String() + if configOption == "" { + fmt.Println("No config option specified") + return + } + newValue := cmd.FlagSet.Arg(0) // Assumes the new value is the first argument after flags + if newValue == "" { + fmt.Println("No new value specified for the config option") + return + } + if err := EditConfigOption(configOption, newValue); err != nil { + fmt.Println("Error editing config option:", err) + return + } + fmt.Println("Config option updated successfully") + }) + editCmd.FlagSet.String("config-option", "", "The configuration option to edit") + + openCmd := NewCommand("open", "Open the configuration in nano", func(cmd *Command, args []string) { + if err := OpenConfigInNano(); err != nil { + fmt.Println("Error opening config in nano:", err) + return + } + fmt.Println("Configuration opened in nano") + }) + + configCmd.AddSubCommand(editCmd) + configCmd.AddSubCommand(openCmd) + RootCmd.AddSubCommand(configCmd) +} diff --git a/go.mod b/go.mod index c87bc2b..1e031cc 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module BackGo +module pixelridgesoftworks.com/BackGo go 1.22.0 diff --git a/main.go b/main.go index e69de29..606d6a7 100644 --- a/main.go +++ b/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "os" + "pixelridgesoftworks.com/BackGo/cmd" +) + +func main() { + // Correctly pass RootCmd as it's already a *Command + if err := cmd.ExecuteCommand(cmd.RootCmd, os.Args[1:]); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +}