setup basic CLI and config commands
This commit is contained in:
parent
37e96b5005
commit
303670e43a
|
@ -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()
|
||||||
|
}
|
109
cmd/root.go
109
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)
|
||||||
|
}
|
2
go.mod
2
go.mod
|
@ -1,3 +1,3 @@
|
||||||
module BackGo
|
module pixelridgesoftworks.com/BackGo
|
||||||
|
|
||||||
go 1.22.0
|
go 1.22.0
|
||||||
|
|
15
main.go
15
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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user