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) }