From d5efa65d21034bb914993c08facddf0fcd0ec447 Mon Sep 17 00:00:00 2001 From: Jon Gallant <2163001+jongio@users.noreply.github.com> Date: Fri, 3 May 2024 17:00:02 +0000 Subject: [PATCH 1/5] Test aks --- cli/azd/internal/repository/detect_confirm_apphost.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/internal/repository/detect_confirm_apphost.go b/cli/azd/internal/repository/detect_confirm_apphost.go index ad227e0dfa3..c724de68903 100644 --- a/cli/azd/internal/repository/detect_confirm_apphost.go +++ b/cli/azd/internal/repository/detect_confirm_apphost.go @@ -80,7 +80,7 @@ func (d *detectConfirmAppHost) render(ctx context.Context) error { d.console.Message( ctx, "azd will generate the files necessary to host your app on Azure using "+color.MagentaString( - "Azure Container Apps", + "Azure Kubernetes Service", )+".\n", ) From c93b95d55428bdb0bb0ca1973bd6376d71a9bf18 Mon Sep 17 00:00:00 2001 From: Jon Gallant <2163001+jongio@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:46:36 +0000 Subject: [PATCH 2/5] Add get-value --- cli/azd/cmd/env.go | 107 ++++++++++++++++++ .../testdata/TestUsage-azd-env-get-value.snap | 19 ++++ cli/azd/cmd/testdata/TestUsage-azd-env.snap | 1 + 3 files changed, 127 insertions(+) create mode 100644 cli/azd/cmd/testdata/TestUsage-azd-env-get-value.snap diff --git a/cli/azd/cmd/env.go b/cli/azd/cmd/env.go index fe8d9beb4e4..49427abc24e 100644 --- a/cli/azd/cmd/env.go +++ b/cli/azd/cmd/env.go @@ -79,6 +79,12 @@ func envActions(root *actions.ActionDescriptor) *actions.ActionDescriptor { DefaultFormat: output.EnvVarsFormat, }) + group.Add("get-value", &actions.ActionDescriptorOptions{ + Command: newEnvGetValueCmd(), + FlagsResolver: newEnvGetValueFlags, + ActionResolver: newEnvGetValueAction, + }) + return group } @@ -592,6 +598,107 @@ func (eg *envGetValuesAction) Run(ctx context.Context) (*actions.ActionResult, e return nil, eg.formatter.Format(env.Dotenv(), eg.writer, nil) } +func newEnvGetValueFlags(cmd *cobra.Command, global *internal.GlobalCommandOptions) *envGetValueFlags { + flags := &envGetValueFlags{} + flags.Bind(cmd.Flags(), global) + + return flags +} + +func newEnvGetValueCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-value ", + Short: "Get specific environment value.", + } + cmd.Args = cobra.MaximumNArgs(1) + + return cmd +} + +type envGetValueFlags struct { + internal.EnvFlag + global *internal.GlobalCommandOptions +} + +func (eg *envGetValueFlags) Bind(local *pflag.FlagSet, global *internal.GlobalCommandOptions) { + eg.EnvFlag.Bind(local, global) + eg.global = global +} + +type envGetValueAction struct { + azdCtx *azdcontext.AzdContext + console input.Console + envManager environment.Manager + formatter output.Formatter + writer io.Writer + flags *envGetValueFlags + args []string +} + +func newEnvGetValueAction( + azdCtx *azdcontext.AzdContext, + envManager environment.Manager, + console input.Console, + formatter output.Formatter, + writer io.Writer, + flags *envGetValueFlags, + args []string, + +) actions.Action { + return &envGetValueAction{ + azdCtx: azdCtx, + console: console, + envManager: envManager, + formatter: formatter, + writer: writer, + flags: flags, + args: args, + } +} + +func (eg *envGetValueAction) Run(ctx context.Context) (*actions.ActionResult, error) { + if len(eg.args) < 1 { + return nil, fmt.Errorf("no key name provided") + } + + keyName := eg.args[0] + + name, err := eg.azdCtx.GetDefaultEnvironmentName() + if err != nil { + return nil, err + } + // Note: if there is not an environment yet, GetDefaultEnvironmentName() returns empty string (not error) + // and later, when envManager.Get() is called with the empty string, azd returns an error. + // But if there is already an environment (default to be selected), azd must honor the --environment flag + // over the default environment. + if eg.flags.EnvironmentName != "" { + name = eg.flags.EnvironmentName + } + env, err := eg.envManager.Get(ctx, name) + if errors.Is(err, environment.ErrNotFound) { + return nil, fmt.Errorf( + `environment '%s' does not exist. You can create it with "azd env new %s"`, + name, + name, + ) + } else if err != nil { + return nil, fmt.Errorf("ensuring environment exists: %w", err) + } + + values := env.Dotenv() + keyValue, exists := values[keyName] + if !exists { + return nil, fmt.Errorf("key '%s' not found in the environment values", keyName) + } + + // Directly write the key value to the writer + if _, err := fmt.Fprintln(eg.writer, keyValue); err != nil { + return nil, fmt.Errorf("writing key value: %w", err) + } + + return nil, nil +} + func getCmdEnvHelpDescription(*cobra.Command) string { return generateCmdHelpDescription( "Manage your application environments. With this command group, you can create a new environment or get, set,"+ diff --git a/cli/azd/cmd/testdata/TestUsage-azd-env-get-value.snap b/cli/azd/cmd/testdata/TestUsage-azd-env-get-value.snap new file mode 100644 index 00000000000..5bc02856194 --- /dev/null +++ b/cli/azd/cmd/testdata/TestUsage-azd-env-get-value.snap @@ -0,0 +1,19 @@ + +Get specific environment value. + +Usage + azd env get-value [flags] + +Flags + --docs : Opens the documentation for azd env get-value in your web browser. + -e, --environment string : The name of the environment to use. + -h, --help : Gets help for get-value. + +Global Flags + -C, --cwd string : Sets the current working directory. + --debug : Enables debugging and diagnostics logging. + --no-prompt : Accepts the default value instead of prompting, or it fails if there is no default. + +Find a bug? Want to let us know how we're doing? Fill out this brief survey: https://aka.ms/azure-dev/hats. + + diff --git a/cli/azd/cmd/testdata/TestUsage-azd-env.snap b/cli/azd/cmd/testdata/TestUsage-azd-env.snap index 9949c306b0c..18a3a3fed47 100644 --- a/cli/azd/cmd/testdata/TestUsage-azd-env.snap +++ b/cli/azd/cmd/testdata/TestUsage-azd-env.snap @@ -10,6 +10,7 @@ Usage azd env [command] Available Commands + get-value : Get specific environment value. get-values : Get all environment values. list : List environments. new : Create a new environment and set it as the default. From aeada73c9256df88468bcc401b3639b9b109d26f Mon Sep 17 00:00:00 2001 From: Jon Gallant <2163001+jongio@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:47:32 +0000 Subject: [PATCH 3/5] Undo aks string --- cli/azd/internal/repository/detect_confirm_apphost.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/internal/repository/detect_confirm_apphost.go b/cli/azd/internal/repository/detect_confirm_apphost.go index c724de68903..ad227e0dfa3 100644 --- a/cli/azd/internal/repository/detect_confirm_apphost.go +++ b/cli/azd/internal/repository/detect_confirm_apphost.go @@ -80,7 +80,7 @@ func (d *detectConfirmAppHost) render(ctx context.Context) error { d.console.Message( ctx, "azd will generate the files necessary to host your app on Azure using "+color.MagentaString( - "Azure Kubernetes Service", + "Azure Container Apps", )+".\n", ) From 85a0d0ac70c42f38291e0842e19f66d811906a6e Mon Sep 17 00:00:00 2001 From: Jon Gallant <2163001+jongio@users.noreply.github.com> Date: Mon, 8 Jul 2024 20:04:11 +0000 Subject: [PATCH 4/5] Remove formatter --- cli/azd/cmd/env.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cli/azd/cmd/env.go b/cli/azd/cmd/env.go index 49427abc24e..d9883e32d27 100644 --- a/cli/azd/cmd/env.go +++ b/cli/azd/cmd/env.go @@ -629,7 +629,6 @@ type envGetValueAction struct { azdCtx *azdcontext.AzdContext console input.Console envManager environment.Manager - formatter output.Formatter writer io.Writer flags *envGetValueFlags args []string @@ -639,7 +638,6 @@ func newEnvGetValueAction( azdCtx *azdcontext.AzdContext, envManager environment.Manager, console input.Console, - formatter output.Formatter, writer io.Writer, flags *envGetValueFlags, args []string, @@ -649,7 +647,6 @@ func newEnvGetValueAction( azdCtx: azdCtx, console: console, envManager: envManager, - formatter: formatter, writer: writer, flags: flags, args: args, From caf2b084fd98acfa77d10088490939f4b89b36e5 Mon Sep 17 00:00:00 2001 From: Jon Gallant <2163001+jongio@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:48:44 +0000 Subject: [PATCH 5/5] Add tests --- cli/azd/test/functional/env_test.go | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/cli/azd/test/functional/env_test.go b/cli/azd/test/functional/env_test.go index dd92aa36eef..ebff94a1ab9 100644 --- a/cli/azd/test/functional/env_test.go +++ b/cli/azd/test/functional/env_test.go @@ -260,6 +260,59 @@ func Test_CLI_Env_Values_MultipleEnvironments(t *testing.T) { require.Equal(t, values["envName2"], envName2) } +func Test_CLI_Env_GetValue(t *testing.T) { + ctx, cancel := newTestContext(t) + defer cancel() + + dir := tempDirWithDiagnostics(t) + t.Logf("DIR: %s", dir) + + cli := azdcli.NewCLI(t) + cli.WorkingDirectory = dir + + err := copySample(dir, "storage") + require.NoError(t, err, "failed expanding sample") + + // Create an environment + envName := randomEnvName() + envNew(ctx, t, cli, envName, false) + + // Set key1 + envSetValue(ctx, t, cli, "key1", "value1") + + // Get key1 value + value := envGetValue(ctx, t, cli, "key1") + require.Equal(t, "value1", value) + + // Set key2 + envSetValue(ctx, t, cli, "key2", "value2") + + // Get key2 value + value = envGetValue(ctx, t, cli, "key2") + require.Equal(t, "value2", value) + + // Modify key1 + envSetValue(ctx, t, cli, "key1", "modified1") + + // Get modified key1 value + value = envGetValue(ctx, t, cli, "key1") + require.Equal(t, "modified1", value) + + // Test non-existent key + res, err := cli.RunCommand(ctx, "env", "get-value", "non_existent_key") + require.Error(t, err) + require.Contains(t, res.Stdout, "key 'non_existent_key' not found in the environment values") +} + +func envGetValue(ctx context.Context, t *testing.T, cli *azdcli.CLI, key string) string { + args := []string{"env", "get-value", key} + + result, err := cli.RunCommand(ctx, args...) + require.NoError(t, err) + + return strings.TrimSpace(result.Stdout) +} + func requireIsDefault(t *testing.T, list []contracts.EnvListEnvironment, envName string) { for _, env := range list { if env.Name == envName {