Skip to content

Some refactoring on leo subcommands #664

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package cmd

import (
"time"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"terraform-provider-iterative/task/common"
)

// BaseOptions specify base flags for commands that interact with
// cloud deployments.
type BaseOptions struct {
Region string
Provider string
Verbose bool
}

// defaultCloud specifies default timeouts.
var defaultCloud = common.Cloud{
Timeouts: common.Timeouts{
Create: 15 * time.Minute,
Read: 3 * time.Minute,
Update: 3 * time.Minute,
Delete: 15 * time.Minute,
},
}

// SetFlags sets base option flags on the provided flagset.
func (o *BaseOptions) SetFlags(f *pflag.FlagSet) {
f.StringVar(&o.Provider, "cloud", "", "cloud provider")
f.StringVar(&o.Region, "region", "us-east", "cloud region")
f.BoolVar(&o.Verbose, "verbose", false, "verbose output")
cobra.CheckErr(cobra.MarkFlagRequired(f, "cloud"))
}

// GetCloud parses cloud-specific options and returns a cloud structure.
func (o *BaseOptions) GetCloud() *common.Cloud {
cloud := defaultCloud
cloud.Provider = common.Provider(o.Provider)
cloud.Region = common.Region(o.Region)
return &cloud
}

// ConfigureLogging configures logging and sets the log level.
func (o *BaseOptions) ConfigureLogging() {
logrus.SetLevel(logrus.InfoLevel)
if o.Verbose {
logrus.SetLevel(logrus.DebugLevel)
}

logrus.SetFormatter(&logrus.TextFormatter{
ForceColors: true,
DisableTimestamp: true,
})
}
Comment on lines +1 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message in a botte for myself: lots of good stuff here, don't let them disappear forever


// Initialize processes the options, the function can be used with `cobra.OnInitialize`.
func (o *BaseOptions) Initialize() {

}
21 changes: 14 additions & 7 deletions cmd/create/create.go → cmd/create.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package create
package cmd

import (
"context"
Expand All @@ -14,7 +14,9 @@ import (
"terraform-provider-iterative/task/common"
)

type Options struct {
type createCmd struct {
BaseOptions BaseOptions

Environment map[string]string
Image string
Machine string
Expand All @@ -30,18 +32,22 @@ type Options struct {
Workdir string
}

func New(cloud *common.Cloud) *cobra.Command {
o := Options{}
func newCreateCmd() *cobra.Command {
o := createCmd{}

cmd := &cobra.Command{
Use: "create [command...]",
Short: "Create a task",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd, args, cloud)
PreRunE: func(cmd *cobra.Command, args []string) error {
o.BaseOptions.ConfigureLogging()
return nil
},
RunE: o.Run,
}

o.BaseOptions.SetFlags(cmd.Flags())

cmd.Flags().StringToStringVar(&o.Environment, "environment", map[string]string{}, "environment variables")
cmd.Flags().StringVar(&o.Image, "image", "ubuntu", "machine image")
cmd.Flags().StringVar(&o.Machine, "machine", "m", "machine type")
Expand All @@ -60,7 +66,8 @@ func New(cloud *common.Cloud) *cobra.Command {
return cmd
}

func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) error {
func (o *createCmd) Run(cmd *cobra.Command, args []string) error {
cloud := o.BaseOptions.GetCloud()
variables := make(map[string]*string)
for name, value := range o.Environment {
name = strings.ToUpper(name)
Expand Down
28 changes: 17 additions & 11 deletions cmd/delete/delete.go → cmd/destroy.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package delete
package cmd

import (
"context"
Expand All @@ -9,31 +9,37 @@ import (
"terraform-provider-iterative/task/common"
)

type Options struct {
Workdir string
Output string
type destroyCmd struct {
BaseOptions BaseOptions
Workdir string
Output string
}

func New(cloud *common.Cloud) *cobra.Command {
o := Options{}
func newDestroyCmd() *cobra.Command {
o := destroyCmd{}

cmd := &cobra.Command{
Use: "delete <name>",
Short: "Delete a task",
Use: "destroy <name>",
Short: "Destroy a task and all associated resources.",
Long: ``,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd, args, cloud)
PreRunE: func(cmd *cobra.Command, args []string) error {
o.BaseOptions.ConfigureLogging()
return nil
},
RunE: o.Run,
}

o.BaseOptions.SetFlags(cmd.Flags())

cmd.Flags().StringVar(&o.Output, "output", "", "output directory, relative to workdir")
cmd.Flags().StringVar(&o.Workdir, "workdir", ".", "working directory")

return cmd
}

func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) error {
func (o *destroyCmd) Run(cmd *cobra.Command, args []string) error {
cloud := o.BaseOptions.GetCloud()
cfg := common.Task{
Environment: common.Environment{
Directory: o.Workdir,
Expand Down
21 changes: 13 additions & 8 deletions cmd/list/list.go → cmd/list.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package list
package cmd

import (
"context"
Expand All @@ -7,28 +7,33 @@ import (
"github.com/spf13/cobra"

"terraform-provider-iterative/task"
"terraform-provider-iterative/task/common"
)

type Options struct {
type listCmd struct {
BaseOptions BaseOptions
}

func New(cloud *common.Cloud) *cobra.Command {
o := Options{}
func newListCmd() *cobra.Command {
o := listCmd{}

cmd := &cobra.Command{
Use: "list",
Short: "List tasks",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd, args, cloud)
PreRunE: func(cmd *cobra.Command, args []string) error {
o.BaseOptions.ConfigureLogging()
return nil
},
RunE: o.Run,
}

o.BaseOptions.SetFlags(cmd.Flags())

return cmd
}

func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) error {
func (o *listCmd) Run(cmd *cobra.Command, args []string) error {
cloud := o.BaseOptions.GetCloud()
ctx, cancel := context.WithTimeout(context.Background(), cloud.Timeouts.Read)
defer cancel()

Expand Down
73 changes: 17 additions & 56 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,13 @@ import (
"fmt"
"os"
"strings"
"time"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"

"terraform-provider-iterative/task/common"

"terraform-provider-iterative/cmd/create"
"terraform-provider-iterative/cmd/delete"
"terraform-provider-iterative/cmd/list"
"terraform-provider-iterative/cmd/read"
"terraform-provider-iterative/cmd/stop"
)

type Options struct {
Region string
Provider string
Verbose bool
common.Cloud
}

func Execute() {
cmd := New()
err := cmd.Execute()
Expand All @@ -36,52 +20,30 @@ func Execute() {
}

func New() *cobra.Command {
o := Options{
Cloud: common.Cloud{
Timeouts: common.Timeouts{
Create: 15 * time.Minute,
Read: 3 * time.Minute,
Update: 3 * time.Minute,
Delete: 15 * time.Minute,
},
},
}

cmd := &cobra.Command{
Use: "task",
Short: "Run code in the cloud",
Long: `Task is a command-line tool that allows
data scientists to run code in the cloud.`,
}

cmd.AddCommand(create.New(&o.Cloud))
cmd.AddCommand(delete.New(&o.Cloud))
cmd.AddCommand(list.New(&o.Cloud))
cmd.AddCommand(read.New(&o.Cloud))
cmd.AddCommand(stop.New(&o.Cloud))

cmd.PersistentFlags().StringVar(&o.Provider, "cloud", "", "cloud provider")
cmd.PersistentFlags().BoolVar(&o.Verbose, "verbose", false, "verbose output")
cmd.PersistentFlags().StringVar(&o.Region, "region", "us-east", "cloud region")
cobra.CheckErr(cmd.MarkPersistentFlagRequired("cloud"))

cobra.OnInitialize(func() {
logrus.SetLevel(logrus.InfoLevel)
if o.Verbose {
logrus.SetLevel(logrus.DebugLevel)
}
cmd.AddCommand(newCreateCmd())
cmd.AddCommand(newDestroyCmd())
cmd.AddCommand(newListCmd())
cmd.AddCommand(newStatusCmd())
cmd.AddCommand(newStopCmd())

logrus.SetFormatter(&logrus.TextFormatter{
ForceColors: true,
DisableTimestamp: true,
})
cobra.CheckErr(parseConfigFile)

o.Cloud.Provider = common.Provider(o.Provider)
o.Cloud.Region = common.Region(o.Region)
})
return cmd
}

func parseConfigFile(cmd *cobra.Command) error {
cwd, err := os.Getwd()
cobra.CheckErr(err)
if err != nil {
return err
}

viper.AddConfigPath(cwd)
viper.SetConfigType("hcl")
viper.SetConfigName("main.tf")
Expand Down Expand Up @@ -146,10 +108,10 @@ func New() *cobra.Command {
}
}

for _, cmd := range append(cmd.Commands(), cmd) {
for _, command := range append(cmd.Commands(), cmd) {
for _, flagSet := range []*pflag.FlagSet{
cmd.PersistentFlags(),
cmd.Flags(),
command.PersistentFlags(),
command.Flags(),
} {
cobra.CheckErr(viper.BindPFlags(flagSet))
flagSet.VisitAll(func(f *pflag.Flag) {
Expand All @@ -166,6 +128,5 @@ func New() *cobra.Command {
})
}
}

return cmd
return nil
}
Loading