From ac5c8417d25237372a8aef85f90fefeb05da1765 Mon Sep 17 00:00:00 2001 From: Sam Alba Date: Wed, 31 Mar 2021 16:32:48 -0700 Subject: [PATCH] cmd: implemented query to be close to cue eval Signed-off-by: Sam Alba --- cmd/dagger/cmd/common/common.go | 7 ++- cmd/dagger/cmd/query.go | 85 +++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/cmd/dagger/cmd/common/common.go b/cmd/dagger/cmd/common/common.go index 51cdfa59..2aeb7fe0 100644 --- a/cmd/dagger/cmd/common/common.go +++ b/cmd/dagger/cmd/common/common.go @@ -65,9 +65,12 @@ func DeploymentUp(ctx context.Context, deployment *dagger.Deployment) { if err != nil { lg.Fatal().Err(err).Msg("unable to create client") } - output, err := c.Up(ctx, deployment) + output, err := c.Do(ctx, deployment, func(ctx context.Context, deployment *dagger.Deployment, s dagger.Solver) error { + log.Ctx(ctx).Debug().Msg("bringing deployment up") + return deployment.Up(ctx, s, nil) + }) if err != nil { - lg.Fatal().Err(err).Msg("failed to compute") + lg.Fatal().Err(err).Msg("failed to up deployment") } fmt.Println(output.JSON()) } diff --git a/cmd/dagger/cmd/query.go b/cmd/dagger/cmd/query.go index a0a7502c..ac267496 100644 --- a/cmd/dagger/cmd/query.go +++ b/cmd/dagger/cmd/query.go @@ -3,18 +3,20 @@ package cmd import ( "fmt" + "cuelang.org/go/cue" "dagger.io/go/cmd/dagger/cmd/common" "dagger.io/go/cmd/dagger/logger" "dagger.io/go/dagger" + "dagger.io/go/dagger/compiler" "github.com/spf13/cobra" "github.com/spf13/viper" ) var queryCmd = &cobra.Command{ - Use: "query [EXPR] [flags]", + Use: "query [TARGET] [flags]", Short: "Query the contents of a deployment", - Args: cobra.ExactArgs(1), + Args: cobra.MaximumNArgs(1), PreRun: func(cmd *cobra.Command, args []string) { // Fix Viper bug for duplicate flags: // https://github.com/spf13/viper/issues/233 @@ -26,6 +28,8 @@ var queryCmd = &cobra.Command{ lg := logger.New() ctx := lg.WithContext(cmd.Context()) + cueOpts := parseQueryFlags() + store, err := dagger.DefaultStore() if err != nil { lg.Fatal().Err(err).Msg("failed to load store") @@ -33,31 +37,74 @@ var queryCmd = &cobra.Command{ deployment := common.GetCurrentDeployment(ctx, store) - expr := args[0] + lg = lg.With(). + Str("deploymentName", deployment.Name()). + Str("deploymentId", deployment.ID()). + Logger() - out, err := deployment.Query(ctx, expr, nil) - if err != nil { - lg. - Fatal(). - Err(err). - Str("deploymentName", deployment.Name()). - Str("deploymentId", deployment.ID()). - Msg("failed to query deployment") + cuePath := cue.MakePath() + if len(args) > 0 { + cuePath = cue.ParsePath(args[0]) } - fmt.Println(out) - // TODO: Implement options: --no-*, --format, --revision + c, err := dagger.NewClient(ctx, "") + if err != nil { + lg.Fatal().Err(err).Msg("unable to create client") + } + output, err := c.Do(ctx, deployment, nil) + if err != nil { + lg.Fatal().Err(err).Msg("failed to query deployment") + } + cueVal := output.LookupPath(cuePath) + + if viper.GetBool("concrete") { + if err := cueVal.IsConcreteR(); err != nil { + lg.Fatal().Err(compiler.Err(err)).Msg("not concrete") + } + } + + out, err := cueVal.Source(cueOpts...) + if err != nil { + lg.Fatal().Err(err).Msg("failed to lookup source") + } + + output.IsConcreteR() + fmt.Println(string(out)) }, } -func init() { - queryCmd.Flags().String("revision", "latest", "Query a specific version of the deployment") - queryCmd.Flags().StringP("format", "f", "", "Output format (json|yaml|cue|text|env)") +func parseQueryFlags() []cue.Option { + opts := []cue.Option{ + cue.Definitions(true), + } - queryCmd.Flags().BoolP("--no-input", "I", false, "Exclude inputs from query") - queryCmd.Flags().BoolP("--no-output", "O", false, "Exclude outputs from query") - queryCmd.Flags().BoolP("--no-plan", "P", false, "Exclude outputs from query") + if viper.GetBool("concrete") { + opts = append(opts, cue.Concrete(true)) + } + + if viper.GetBool("show-optional") { + opts = append(opts, cue.Optional(true)) + } + + if viper.GetBool("show-attributes") { + opts = append(opts, cue.Attributes(true)) + } + + return opts +} + +func init() { + queryCmd.Flags().BoolP("concrete", "c", false, "Require the evaluation to be concrete") + queryCmd.Flags().BoolP("show-optional", "O", false, "Display optional fields") + queryCmd.Flags().BoolP("show-attributes", "A", false, "Display field attributes") + + // FIXME: implement the flags below + // queryCmd.Flags().String("revision", "latest", "Query a specific version of the deployment") + // queryCmd.Flags().StringP("format", "f", "", "Output format (json|yaml|cue|text|env)") + // queryCmd.Flags().BoolP("no-input", "I", false, "Exclude inputs from query") + // queryCmd.Flags().BoolP("no-output", "O", false, "Exclude outputs from query") + // queryCmd.Flags().BoolP("no-plan", "P", false, "Exclude outputs from query") if err := viper.BindPFlags(queryCmd.Flags()); err != nil { panic(err)