Move bundle loading functions to top level (#181)

We intend to let non-bundle commands use bundle configuration for their
operating context (workspace, auth, default cluster, etc).

As such, all commands must first try to load a bundle configuration.
If there is no bundle they can fall back on taking their operating
context from command line flags and the environment.

This is on top of #180.
This commit is contained in:
Pieter Noordhuis 2023-01-27 17:05:57 +01:00 committed by GitHub
parent 9a1d908f79
commit 6737af4b06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 60 deletions

View File

@ -4,14 +4,14 @@ import (
"fmt" "fmt"
"github.com/databricks/bricks/bundle" "github.com/databricks/bricks/bundle"
parent "github.com/databricks/bricks/cmd/bundle" "github.com/databricks/bricks/cmd/root"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var whoamiCmd = &cobra.Command{ var whoamiCmd = &cobra.Command{
Use: "whoami", Use: "whoami",
PreRunE: parent.ConfigureBundle, PreRunE: root.MustConfigureBundle,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
w := bundle.Get(ctx).WorkspaceClient() w := bundle.Get(ctx).WorkspaceClient()

View File

@ -3,6 +3,7 @@ package bundle
import ( import (
"github.com/databricks/bricks/bundle" "github.com/databricks/bricks/bundle"
"github.com/databricks/bricks/bundle/phases" "github.com/databricks/bricks/bundle/phases"
"github.com/databricks/bricks/cmd/root"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -10,7 +11,7 @@ var deployCmd = &cobra.Command{
Use: "deploy", Use: "deploy",
Short: "Deploy bundle", Short: "Deploy bundle",
PreRunE: ConfigureBundle, PreRunE: root.MustConfigureBundle,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
b := bundle.Get(cmd.Context()) b := bundle.Get(cmd.Context())
return bundle.Apply(cmd.Context(), b, []bundle.Mutator{ return bundle.Apply(cmd.Context(), b, []bundle.Mutator{

View File

@ -1,24 +0,0 @@
package bundle
import (
"os"
"github.com/spf13/cobra"
)
const envName = "DATABRICKS_BUNDLE_ENV"
// getEnvironment returns the name of the environment to operate in.
func getEnvironment(cmd *cobra.Command) (value string) {
// The command line flag takes precedence.
flag := cmd.Flag("environment")
if flag != nil {
value = flag.Value.String()
if value != "" {
return
}
}
// If it's not set, use the environment variable.
return os.Getenv(envName)
}

View File

@ -1,8 +1,6 @@
package bundle package bundle
import ( import (
"github.com/databricks/bricks/bundle"
"github.com/databricks/bricks/bundle/config/mutator"
"github.com/databricks/bricks/cmd/root" "github.com/databricks/bricks/cmd/root"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -13,39 +11,10 @@ var rootCmd = &cobra.Command{
Short: "Databricks Application Bundles", Short: "Databricks Application Bundles",
} }
// ConfigureBundle loads the bundle configuration
// and configures it on the command's context.
func ConfigureBundle(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
b, err := bundle.MustLoad()
if err != nil {
return err
}
ms := mutator.DefaultMutators()
env := getEnvironment(cmd)
if env == "" {
ms = append(ms, mutator.SelectDefaultEnvironment())
} else {
ms = append(ms, mutator.SelectEnvironment(env))
}
err = bundle.Apply(ctx, b, ms)
if err != nil {
return err
}
cmd.SetContext(bundle.Context(ctx, b))
return nil
}
func AddCommand(cmd *cobra.Command) { func AddCommand(cmd *cobra.Command) {
rootCmd.AddCommand(cmd) rootCmd.AddCommand(cmd)
} }
func init() { func init() {
// All bundle commands take an "environment" parameter.
rootCmd.PersistentFlags().StringP("environment", "e", "", "Environment to use")
// Add to top level root.
root.RootCmd.AddCommand(rootCmd) root.RootCmd.AddCommand(rootCmd)
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/databricks/bricks/bundle/deploy/terraform" "github.com/databricks/bricks/bundle/deploy/terraform"
"github.com/databricks/bricks/bundle/phases" "github.com/databricks/bricks/bundle/phases"
"github.com/databricks/bricks/bundle/run" "github.com/databricks/bricks/bundle/run"
"github.com/databricks/bricks/cmd/root"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -15,7 +16,7 @@ var runCmd = &cobra.Command{
Short: "Run a workload (e.g. a job or a pipeline)", Short: "Run a workload (e.g. a job or a pipeline)",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
PreRunE: ConfigureBundle, PreRunE: root.MustConfigureBundle,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
b := bundle.Get(cmd.Context()) b := bundle.Get(cmd.Context())
err := bundle.Apply(cmd.Context(), b, []bundle.Mutator{ err := bundle.Apply(cmd.Context(), b, []bundle.Mutator{

View File

@ -5,6 +5,7 @@ import (
"github.com/databricks/bricks/bundle" "github.com/databricks/bricks/bundle"
"github.com/databricks/bricks/bundle/phases" "github.com/databricks/bricks/bundle/phases"
"github.com/databricks/bricks/cmd/root"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -12,7 +13,7 @@ var validateCmd = &cobra.Command{
Use: "validate", Use: "validate",
Short: "Validate configuration", Short: "Validate configuration",
PreRunE: ConfigureBundle, PreRunE: root.MustConfigureBundle,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
b := bundle.Get(cmd.Context()) b := bundle.Get(cmd.Context())
err := bundle.Apply(cmd.Context(), b, []bundle.Mutator{ err := bundle.Apply(cmd.Context(), b, []bundle.Mutator{

72
cmd/root/bundle.go Normal file
View File

@ -0,0 +1,72 @@
package root
import (
"os"
"github.com/databricks/bricks/bundle"
"github.com/databricks/bricks/bundle/config/mutator"
"github.com/spf13/cobra"
)
const envName = "DATABRICKS_BUNDLE_ENV"
// getEnvironment returns the name of the environment to operate in.
func getEnvironment(cmd *cobra.Command) (value string) {
// The command line flag takes precedence.
flag := cmd.Flag("environment")
if flag != nil {
value = flag.Value.String()
if value != "" {
return
}
}
// If it's not set, use the environment variable.
return os.Getenv(envName)
}
// configureBundle loads the bundle configuration and configures it on the command's context.
func configureBundle(cmd *cobra.Command, args []string, load func() (*bundle.Bundle, error)) error {
b, err := load()
if err != nil {
return err
}
// No bundle is fine in case of `TryConfigureBundle`.
if b == nil {
return nil
}
ms := mutator.DefaultMutators()
env := getEnvironment(cmd)
if env == "" {
ms = append(ms, mutator.SelectDefaultEnvironment())
} else {
ms = append(ms, mutator.SelectEnvironment(env))
}
ctx := cmd.Context()
err = bundle.Apply(ctx, b, ms)
if err != nil {
return err
}
cmd.SetContext(bundle.Context(ctx, b))
return nil
}
// MustConfigureBundle configures a bundle on the command context.
func MustConfigureBundle(cmd *cobra.Command, args []string) error {
return configureBundle(cmd, args, bundle.MustLoad)
}
// TryConfigureBundle configures a bundle on the command context
// if there is one, but doesn't fail if there isn't one.
func TryConfigureBundle(cmd *cobra.Command, args []string) error {
return configureBundle(cmd, args, bundle.TryLoad)
}
func init() {
// To operate in the context of a bundle, all commands must take an "environment" parameter.
RootCmd.PersistentFlags().StringP("environment", "e", "", "bundle environment to use (if applicable)")
}