From 17221855cc129d75dd22a425de46ff07d4e47467 Mon Sep 17 00:00:00 2001 From: Marc Cataford Date: Sat, 28 Sep 2024 21:47:48 -0400 Subject: [PATCH] feat: add explicit flag / arg definitions --- cli/build.go | 46 ++++++++++++++++++++++++--------------- cli/build_test.go | 37 +++++++++++++++++++++++++++++++ cli/cli.go | 18 +++++++-------- cli/start_service.go | 37 +++++++++++++++++++++---------- cli/start_service_test.go | 37 +++++++++++++++++++++++++++++++ cli/stop_service.go | 26 ++++++++++++++++------ cli/stop_service_test.go | 17 +++++++++++++++ main.go | 5 ++++- 8 files changed, 177 insertions(+), 46 deletions(-) create mode 100644 cli/build_test.go create mode 100644 cli/start_service_test.go create mode 100644 cli/stop_service_test.go diff --git a/cli/build.go b/cli/build.go index b0134e2..e28f992 100644 --- a/cli/build.go +++ b/cli/build.go @@ -1,31 +1,43 @@ package cli import ( + "fmt" "github.com/spf13/cobra" "log" podman "spud/podman" service_definition "spud/service_definition" ) -var build = &cobra.Command{ - Use: "build", - Short: "Build service images.", - Run: func(cmd *cobra.Command, args []string) { - pathProvided := args[0] - def, err := service_definition.GetServiceDefinitionFromFile(pathProvided) +func getBuildCommand() *cobra.Command { + build := &cobra.Command{ + Use: "build", + Short: "Build service images.", + RunE: func(cmd *cobra.Command, args []string) error { + pathProvided, err := cmd.PersistentFlags().GetString("definition") - if err != nil { - log.Fatal(err) - } + if err != nil { + return fmt.Errorf("%+v", err) + } + def, err := service_definition.GetServiceDefinitionFromFile(pathProvided) - imagesToBuild := def.Build.Images + if err != nil { + return fmt.Errorf("Failed to read service definition from file: %+v", err) + } - if len(imagesToBuild) == 0 { - log.Print("No images defined - nothing to build!") - } + imagesToBuild := def.Build.Images + + if len(imagesToBuild) == 0 { + log.Print("No images defined - nothing to build!") + } + + for _, imageDef := range imagesToBuild { + podman.Build(imageDef) + } + return nil + }, + } + build.PersistentFlags().StringP("definition", "d", "./service.yml", "Path to the service definition to use.") + + return build - for _, imageDef := range imagesToBuild { - podman.Build(imageDef) - } - }, } diff --git a/cli/build_test.go b/cli/build_test.go new file mode 100644 index 0000000..dbb5c57 --- /dev/null +++ b/cli/build_test.go @@ -0,0 +1,37 @@ +package cli + +import ( + "github.com/spf13/cobra" + "testing" +) + +func TestCliBuildServiceDefinitionPathMustExist(t *testing.T) { + cli := GetCli() + + cli.SetArgs([]string{"build", "-d", "./not-a-file.yml"}) + + outcome := cli.Execute() + + if outcome == nil { + t.Errorf("Expected error, got nil.") + } +} + +func TestCliBuildDefaultsServiceDefinitionPath(t *testing.T) { + cli := GetCli() + + cli.SetArgs([]string{"build"}) + + startCommand, _, _ := cli.Find([]string{"build"}) + + startCommand.RunE = func(cmd *cobra.Command, args []string) error { + actual, _ := cmd.PersistentFlags().GetString("definition") + if actual != "./service.yml" { + t.Errorf("Unexpected default value for 'definition' / 'd' arg: %s", actual) + } + + return nil + } + + cli.Execute() +} diff --git a/cli/cli.go b/cli/cli.go index 8ce360a..bef0816 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -5,15 +5,6 @@ import ( "github.com/spf13/cobra" ) -var allCommands = []*cobra.Command{ - // cli/start_service.go - start, - // cli/stop_service.go - stop, - // cli/build.go - build, -} - // Creates the root of the CLI, with all available commands // added to it. func GetCli() *cobra.Command { @@ -22,6 +13,15 @@ func GetCli() *cobra.Command { Short: "A not-entirely-terrible-way to manage self-hosted services.", } + allCommands := []*cobra.Command{ + // cli/start_service.go + getStartCommand(), + // cli/stop_service.go + getStopCommand(), + // cli/build.go + getBuildCommand(), + } + for _, command := range allCommands { cli.AddCommand(command) } diff --git a/cli/start_service.go b/cli/start_service.go index 42619cf..df47157 100644 --- a/cli/start_service.go +++ b/cli/start_service.go @@ -5,23 +5,36 @@ package cli import ( + "fmt" "github.com/spf13/cobra" - "log" service "spud/service" service_definition "spud/service_definition" ) -var start = &cobra.Command{ - Use: "start", - Short: "Creates or updates a service based on the provided definition.", - Run: func(cmd *cobra.Command, args []string) { - pathProvided := args[0] - def, err := service_definition.GetServiceDefinitionFromFile(pathProvided) +func getStartCommand() *cobra.Command { + start := &cobra.Command{ + Use: "start", + Short: "Creates or updates a service based on the provided definition.", + RunE: func(cmd *cobra.Command, args []string) error { + pathProvided, err := cmd.PersistentFlags().GetString("definition") - if err != nil { - log.Fatal(err) - } + if err != nil { + return fmt.Errorf("%+v", err) + } - service.CreateService(def) - }, + def, err := service_definition.GetServiceDefinitionFromFile(pathProvided) + + if err != nil { + return fmt.Errorf("Failed to read service definition from file: %+v", err) + } + + service.CreateService(def) + + return nil + }, + } + + start.PersistentFlags().StringP("definition", "d", "./service.yml", "Path to the service definition to use.") + + return start } diff --git a/cli/start_service_test.go b/cli/start_service_test.go new file mode 100644 index 0000000..5d2f6aa --- /dev/null +++ b/cli/start_service_test.go @@ -0,0 +1,37 @@ +package cli + +import ( + "github.com/spf13/cobra" + "testing" +) + +func TestCliStartServiceDefinitionPathMustExist(t *testing.T) { + cli := GetCli() + + cli.SetArgs([]string{"start", "-d", "./not-a-file.yml"}) + + outcome := cli.Execute() + + if outcome == nil { + t.Errorf("Expected error, got nil.") + } +} + +func TestCliStartDefaultsServiceDefinitionPath(t *testing.T) { + cli := GetCli() + + cli.SetArgs([]string{"start"}) + + startCommand, _, _ := cli.Find([]string{"start"}) + + startCommand.RunE = func(cmd *cobra.Command, args []string) error { + actual, _ := cmd.PersistentFlags().GetString("definition") + if actual != "./service.yml" { + t.Errorf("Unexpected default value for 'definition' / 'd' arg: %s", actual) + } + + return nil + } + + cli.Execute() +} diff --git a/cli/stop_service.go b/cli/stop_service.go index 5686553..d68fb04 100644 --- a/cli/stop_service.go +++ b/cli/stop_service.go @@ -4,15 +4,27 @@ package cli import ( + "fmt" "github.com/spf13/cobra" service "spud/service" ) -var stop = &cobra.Command{ - Use: "stop", - Short: "Stops a running service and all of its containers.", - Run: func(cmd *cobra.Command, args []string) { - serviceName := args[0] - service.StopService(serviceName) - }, +func getStopCommand() *cobra.Command { + stop := &cobra.Command{ + Use: "stop [service-name]", + Short: "Stops a running service and all of its containers.", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return fmt.Errorf("Must specify a service using '--service'") + } + + serviceName := args[0] + + service.StopService(serviceName) + + return nil + }, + } + + return stop } diff --git a/cli/stop_service_test.go b/cli/stop_service_test.go new file mode 100644 index 0000000..0dbf321 --- /dev/null +++ b/cli/stop_service_test.go @@ -0,0 +1,17 @@ +package cli + +import ( + "testing" +) + +func TestCliStopRequiresAServiceName(t *testing.T) { + cli := GetCli() + + cli.SetArgs([]string{"stop"}) + + outcome := cli.Execute() + + if outcome == nil { + t.Error("Expected error, got nil.") + } +} diff --git a/main.go b/main.go index c0cf245..8f8958c 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main import ( + "os" cli "spud/cli" ) func main() { - cli.GetCli().Execute() + if err := cli.GetCli().Execute(); err != nil { + os.Exit(1) + } }