diff --git a/.gitignore b/.gitignore index 5bc5994..fbf99fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ BACKLOG/ logs/ *.log +coverage/ dist/ \ No newline at end of file diff --git a/backup/cmd/config.go b/backup/cmd/config.go index 2920799..1e297c3 100644 --- a/backup/cmd/config.go +++ b/backup/cmd/config.go @@ -3,20 +3,14 @@ package cmd import ( "backup-rsync/backup/internal" "fmt" - "log" "github.com/spf13/cobra" - "gopkg.in/yaml.v3" ) func buildConfigCommand() *cobra.Command { var configCmd = &cobra.Command{ Use: "config", Short: "Manage configuration", - Run: func(cmd *cobra.Command, args []string) { - // Implementation for the config command - fmt.Println("Config command executed") - }, } var showVerb = &cobra.Command{ @@ -26,12 +20,7 @@ func buildConfigCommand() *cobra.Command { configPath, _ := cmd.Flags().GetString("config") cfg := internal.LoadResolvedConfig(configPath) - out, err := yaml.Marshal(cfg) - if err != nil { - log.Fatalf("Failed to marshal resolved configuration: %v", err) - } - - fmt.Printf("Resolved Configuration:\n%s\n", string(out)) + fmt.Printf("Resolved Configuration:\n%s\n", cfg) }, } diff --git a/backup/cmd/root.go b/backup/cmd/root.go index 504505c..a3523ec 100644 --- a/backup/cmd/root.go +++ b/backup/cmd/root.go @@ -1,30 +1,25 @@ -// Package cmd contains the commands for the backup-tool CLI application. package cmd import ( - "os" - "github.com/spf13/cobra" ) -// Execute adds all child commands to the root command and sets flags appropriately. -func Execute() { +func BuildRootCommand() *cobra.Command { rootCmd := &cobra.Command{ - Use: "backup-tool", + Use: "backup", Short: "A tool for managing backups", - Long: `backup-tool is a CLI tool for managing backups and configurations.`, + Long: `backup is a CLI tool for managing backups and configurations.`, } rootCmd.PersistentFlags().String("config", "config.yaml", "Path to the configuration file") - rootCmd.AddCommand(buildListCommand()) - rootCmd.AddCommand(buildRunCommand()) - rootCmd.AddCommand(buildSimulateCommand()) - rootCmd.AddCommand(buildConfigCommand()) - rootCmd.AddCommand(buildCheckCoverageCommand()) + rootCmd.AddCommand( + buildListCommand(), + buildRunCommand(), + buildSimulateCommand(), + buildConfigCommand(), + buildCheckCoverageCommand(), + ) - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } + return rootCmd } diff --git a/backup/cmd/test/root_test.go b/backup/cmd/test/root_test.go new file mode 100644 index 0000000..42746fd --- /dev/null +++ b/backup/cmd/test/root_test.go @@ -0,0 +1,37 @@ +package cmd_test + +import ( + "bytes" + "testing" + + "backup-rsync/backup/cmd" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// integration test to verify the root command and its sub-commands are set up correctly. +func TestBuildRootCommand_HelpOutput(t *testing.T) { + rootCmd := cmd.BuildRootCommand() + + // Capture the help output + buf := new(bytes.Buffer) + rootCmd.SetOut(buf) + rootCmd.SetArgs([]string{"--help"}) + err := rootCmd.Execute() + require.NoError(t, err) + + helpOutput := buf.String() + // Verify the help output contains expected content + assert.Contains(t, helpOutput, "backup is a CLI tool for managing backups and configurations.", + "Help output should contain the long description") + assert.Contains(t, helpOutput, "backup [command]", "Help output should contain usage") + assert.Contains(t, helpOutput, "--config string Path to the configuration file (default \"config.yaml\")", + "Help output should contain the persistent flag description") + + // check each sub-command is listed + subCommands := []string{"list", "run", "simulate", "config", "check-coverage"} + for _, cmdName := range subCommands { + assert.Regexp(t, "(?m)^ "+cmdName, helpOutput, "Help output should list the sub-command: "+cmdName) + } +} diff --git a/backup/internal/config.go b/backup/internal/config.go index b8966db..6df79e7 100644 --- a/backup/internal/config.go +++ b/backup/internal/config.go @@ -20,6 +20,12 @@ var ( ErrOverlappingPath = errors.New("overlapping path detected") ) +func (cfg Config) String() string { + out, _ := yaml.Marshal(cfg) + + return string(out) +} + func LoadConfig(reader io.Reader) (Config, error) { var cfg Config diff --git a/backup/internal/test/config_test.go b/backup/internal/test/config_test.go index b7356fc..2d99175 100644 --- a/backup/internal/test/config_test.go +++ b/backup/internal/test/config_test.go @@ -318,3 +318,17 @@ func TestValidatePaths_InvalidPaths(t *testing.T) { assert.EqualError(t, err, test.errorMessage) }) } + +func TestConfigString_ValidConfig(t *testing.T) { + cfg := internal.Config{ + Sources: []internal.Path{}, + Targets: []internal.Path{}, + Variables: map[string]string{}, + Jobs: []internal.Job{}, + } + + expectedOutput := "sources: []\ntargets: []\nvariables: {}\njobs: []\n" + actualOutput := cfg.String() + + assert.Equal(t, expectedOutput, actualOutput) +} diff --git a/backup/main.go b/backup/main.go index 18c8937..4777014 100644 --- a/backup/main.go +++ b/backup/main.go @@ -2,8 +2,14 @@ package main import ( "backup-rsync/backup/cmd" + "os" ) func main() { - cmd.Execute() + rootCmd := cmd.BuildRootCommand() + + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } }