Skip to content
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

Remove dependency on global state in generated commands #595

Merged
merged 11 commits into from
Jul 25, 2023
25 changes: 13 additions & 12 deletions .codegen/cmds-account.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@ import (
{{.SnakeName}} "github.com/databricks/cli/cmd/account/{{(.TrimPrefix "account").KebabName}}"{{end}}{{end}}{{end}}
)

var accountCmd = &cobra.Command{
Use: "account",
Short: `Databricks Account Commands`,
}

func init() {
root.RootCmd.AddCommand(accountCmd)
func New() *cobra.Command {
cmd := &cobra.Command{
Use: "account",
Short: `Databricks Account Commands`,
}

{{range .Services}}{{if .IsAccounts}}{{if not (in $excludes .KebabName) -}}
accountCmd.AddCommand({{.SnakeName}}.Cmd)
cmd.AddCommand({{.SnakeName}}.New())
{{end}}{{end}}{{end}}

// Register commands with groups
{{range .Services}}{{if .IsAccounts}}{{if not (in $excludes .KebabName) -}}
{{.SnakeName}}.Cmd.GroupID = "{{ .Package.Name }}"
{{end}}{{end}}{{end}}
// Register all groups with the parent command.
groups := Groups()
for i := range groups {
cmd.AddGroup(&groups[i])
}

return cmd
}
11 changes: 5 additions & 6 deletions .codegen/cmds-workspace.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import (
{{.SnakeName}} "github.com/databricks/cli/cmd/workspace/{{.KebabName}}"{{end}}{{end}}{{end}}
)

func init() {
{{range .Services}}{{if not .IsAccounts}}{{if not (in $excludes .KebabName) -}}
root.RootCmd.AddCommand({{.SnakeName}}.Cmd)
{{end}}{{end}}{{end}}
func All() []*cobra.Command {
var out []*cobra.Command

// Register commands with groups
{{range .Services}}{{if not .IsAccounts}}{{if not (in $excludes .KebabName) -}}
{{.SnakeName}}.Cmd.GroupID = "{{ .Package.Name }}"
out = append(out, {{.SnakeName}}.New())
{{end}}{{end}}{{end}}

return out
}
149 changes: 96 additions & 53 deletions .codegen/service.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,34 @@ import (
{{end}}

{{define "service"}}
var Cmd = &cobra.Command{
Use: "{{(.TrimPrefix "account").KebabName}}",
{{- if .Description }}
Short: `{{.Summary | without "`"}}`,
Long: `{{.Comment " " 80 | without "`"}}`,
{{- end }}
Annotations: map[string]string{
"package": "{{ .Package.Name }}",
},
{{- if .IsPrivatePreview }}
// Slice with functions to override default command behavior.
// Functions can be added from the `init()` function in manually curated files in this directory.
var cmdOverrides []func(*cobra.Command)

// This service is being previewed; hide from help output.
Hidden: true,
{{- end }}
func New() *cobra.Command {
cmd := &cobra.Command{
Use: "{{(.TrimPrefix "account").KebabName}}",
{{- if .Description }}
Short: `{{.Summary | without "`"}}`,
Long: `{{.Comment " " 80 | without "`"}}`,
{{- end }}
GroupID: "{{ .Package.Name }}",
Annotations: map[string]string{
"package": "{{ .Package.Name }}",
},
{{- if .IsPrivatePreview }}

// This service is being previewed; hide from help output.
Hidden: true,
{{- end }}
}

// Apply optional overrides to this command.
for _, fn := range cmdOverrides {
fn(cmd)
}

return cmd
}

{{- $serviceName := .KebabName -}}
Expand All @@ -44,26 +58,39 @@ var Cmd = &cobra.Command{
{{end}}
// start {{.KebabName}} command

{{- $useJsonForAllFields := or .IsJsonOnly (and .Request (or (not .Request.IsAllRequiredFieldsPrimitive) .Request.HasRequiredNonBodyField)) -}}
{{- $needJsonFlag := or $useJsonForAllFields (and .Request (not .Request.IsOnlyPrimitiveFields)) -}}
{{- if .Request}}
var {{.CamelName}}Req {{.Service.Package.Name}}.{{.Request.PascalName}}
{{- if $needJsonFlag}}
var {{.CamelName}}Json flags.JsonFlag
{{- end}}
{{end}}
{{if .Wait}}var {{.CamelName}}SkipWait bool
var {{.CamelName}}Timeout time.Duration{{end}}
// Slice with functions to override default command behavior.
// Functions can be added from the `init()` function in manually curated files in this directory.
var {{.CamelName}}Overrides []func(
*cobra.Command,
{{- if .Request }}
*{{.Service.Package.Name}}.{{.Request.PascalName}},
{{- end }}
)

func new{{.PascalName}}() *cobra.Command {
cmd := &cobra.Command{}

{{- $useJsonForAllFields := or .IsJsonOnly (and .Request (or (not .Request.IsAllRequiredFieldsPrimitive) .Request.HasRequiredNonBodyField)) -}}
{{- $needJsonFlag := or $useJsonForAllFields (and .Request (not .Request.IsOnlyPrimitiveFields)) -}}

{{- if .Request}}

var {{.CamelName}}Req {{.Service.Package.Name}}.{{.Request.PascalName}}
{{- if $needJsonFlag}}
var {{.CamelName}}Json flags.JsonFlag
{{- end}}
{{- end}}

{{if .Wait}}var {{.CamelName}}SkipWait bool
var {{.CamelName}}Timeout time.Duration{{end}}

func init() {
Cmd.AddCommand({{.CamelName}}Cmd)
{{if .Wait}}
{{.CamelName}}Cmd.Flags().BoolVar(&{{.CamelName}}SkipWait, "no-wait", {{.CamelName}}SkipWait, `do not wait to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`)
{{.CamelName}}Cmd.Flags().DurationVar(&{{.CamelName}}Timeout, "timeout", {{.Wait.Timeout}}*time.Minute, `maximum amount of time to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`)
cmd.Flags().BoolVar(&{{.CamelName}}SkipWait, "no-wait", {{.CamelName}}SkipWait, `do not wait to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`)
cmd.Flags().DurationVar(&{{.CamelName}}Timeout, "timeout", {{.Wait.Timeout}}*time.Minute, `maximum amount of time to reach {{range $i, $e := .Wait.Success}}{{if $i}} or {{end}}{{.Content}}{{end}} state`)
{{end -}}
{{if .Request}}// TODO: short flags
{{- if $needJsonFlag}}
{{.CamelName}}Cmd.Flags().Var(&{{.CamelName}}Json, "json", `either inline JSON string or @path/to/file.json with request body`)
cmd.Flags().Var(&{{.CamelName}}Json, "json", `either inline JSON string or @path/to/file.json with request body`)
{{- end}}
{{$method := .}}
{{ if not .IsJsonOnly }}
Expand All @@ -74,48 +101,50 @@ func init() {
{{else if .Entity.ArrayValue }}// TODO: array: {{.Name}}
{{else if .Entity.MapValue }}// TODO: map via StringToStringVar: {{.Name}}
{{else if .Entity.IsEmpty }}// TODO: output-only field
{{else if .Entity.Enum }}{{$method.CamelName}}Cmd.Flags().Var(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", `{{.Summary | without "`"}}`)
{{else}}{{$method.CamelName}}Cmd.Flags().{{template "arg-type" .Entity}}(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", {{$method.CamelName}}Req.{{.PascalName}}, `{{.Summary | without "`"}}`)
{{else if .Entity.Enum }}cmd.Flags().Var(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", `{{.Summary | without "`"}}`)
{{else}}cmd.Flags().{{template "arg-type" .Entity}}(&{{$method.CamelName}}Req.{{.PascalName}}, "{{.KebabName}}", {{$method.CamelName}}Req.{{.PascalName}}, `{{.Summary | without "`"}}`)
{{end}}
{{- end -}}
{{- end}}
{{- end}}
{{end}}
}
{{- $excludeFromPrompts := list "workspace get-status" -}}
{{- $fullCommandName := (print $serviceName " " .KebabName) -}}
{{- $noPrompt := or .IsCrudCreate (in $excludeFromPrompts $fullCommandName) }}

{{ $hasPosArgs := and .Request (or .Request.IsAllRequiredFieldsPrimitive (eq .PascalName "RunNow")) -}}
{{- $hasSinglePosArg := and $hasPosArgs (eq 1 (len .Request.RequiredFields)) -}}
{{- $serviceHasNamedIdMap := and (and .Service.List .Service.List.NamedIdMap) (not (eq .PascalName "List")) -}}
{{- $hasIdPrompt := and (not $noPrompt) (and $hasSinglePosArg $serviceHasNamedIdMap) -}}
{{- $wait := and .Wait (and (not .IsCrudRead) (not (eq .SnakeName "get_run"))) -}}
{{- $hasRequiredArgs := and (not $hasIdPrompt) $hasPosArgs -}}
var {{.CamelName}}Cmd = &cobra.Command{
Use: "{{.KebabName}}{{if $hasPosArgs}}{{range .Request.RequiredFields}} {{.ConstantName}}{{end}}{{end}}",

{{- $excludeFromPrompts := list "workspace get-status" -}}
{{- $fullCommandName := (print $serviceName " " .KebabName) -}}
{{- $noPrompt := or .IsCrudCreate (in $excludeFromPrompts $fullCommandName) }}

{{- $hasPosArgs := and .Request (or .Request.IsAllRequiredFieldsPrimitive (eq .PascalName "RunNow")) -}}
{{- $hasSinglePosArg := and $hasPosArgs (eq 1 (len .Request.RequiredFields)) -}}
{{- $serviceHasNamedIdMap := and (and .Service.List .Service.List.NamedIdMap) (not (eq .PascalName "List")) -}}
{{- $hasIdPrompt := and (not $noPrompt) (and $hasSinglePosArg $serviceHasNamedIdMap) -}}
{{- $wait := and .Wait (and (not .IsCrudRead) (not (eq .SnakeName "get_run"))) -}}
{{- $hasRequiredArgs := and (not $hasIdPrompt) $hasPosArgs -}}

cmd.Use = "{{.KebabName}}{{if $hasPosArgs}}{{range .Request.RequiredFields}} {{.ConstantName}}{{end}}{{end}}"
{{- if .Description }}
Short: `{{.Summary | without "`"}}`,
Long: `{{.Comment " " 80 | without "`"}}`,
cmd.Short = `{{.Summary | without "`"}}`
cmd.Long = `{{.Comment " " 80 | without "`"}}`
{{- end }}
{{- if .IsPrivatePreview }}

// This command is being previewed; hide from help output.
Hidden: true,
cmd.Hidden = true
{{- end }}

Annotations: map[string]string{},{{if $hasRequiredArgs }}
Args: func(cmd *cobra.Command, args []string) error {
cmd.Annotations = make(map[string]string)
{{if $hasRequiredArgs }}
cmd.Args = func(cmd *cobra.Command, args []string) error {
check := cobra.ExactArgs({{len .Request.RequiredFields}})
{{- if $useJsonForAllFields }}
if cmd.Flags().Changed("json") {
check = cobra.ExactArgs(0)
}
{{- end }}
return check(cmd, args)
},{{end}}
PreRunE: root.Must{{if .Service.IsAccounts}}Account{{else}}Workspace{{end}}Client,
RunE: func(cmd *cobra.Command, args []string) (err error) {
}
{{end}}
cmd.PreRunE = root.Must{{if .Service.IsAccounts}}Account{{else}}Workspace{{end}}Client
cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
ctx := cmd.Context()
{{if .Service.IsAccounts}}a := root.AccountClient(ctx){{else}}w := root.WorkspaceClient(ctx){{end}}
{{- if .Request }}
Expand Down Expand Up @@ -204,10 +233,24 @@ var {{.CamelName}}Cmd = &cobra.Command{
{{- else -}}
{{template "method-call" .}}
{{end -}}
},
}

// Disable completions since they are not applicable.
// Can be overridden by manual implementation in `override.go`.
ValidArgsFunction: cobra.NoFileCompletions,
cmd.ValidArgsFunction = cobra.NoFileCompletions

// Apply optional overrides to this command.
for _, fn := range {{.CamelName}}Overrides {
fn(cmd{{if .Request}}, &{{.CamelName}}Req{{end}})
}

return cmd
}

func init() {
cmdOverrides = append(cmdOverrides, func(cmd *cobra.Command) {
cmd.AddCommand(new{{.PascalName}}())
})
}
{{end}}
// end service {{.Name}}{{end}}
Expand Down
Loading