diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index a513778b..05e84a3c 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -3,6 +3,9 @@ - Improve evaluation performance and memory footprint. [#392](https://github.com/pulumi/esc/pull/392) +- Prompt for the value if the value arg is not passed. + [#394](https://github.com/pulumi/esc/pull/394) + ### Bug Fixes ### Breaking changes diff --git a/cmd/esc/cli/env_set.go b/cmd/esc/cli/env_set.go index df3a1717..0b94ed0d 100644 --- a/cmd/esc/cli/env_set.go +++ b/cmd/esc/cli/env_set.go @@ -5,14 +5,18 @@ package cli import ( "context" "fmt" + "io" + "os" "regexp" "strconv" "github.com/ccojocar/zxcvbn-go" "github.com/spf13/cobra" + "golang.org/x/term" "gopkg.in/yaml.v3" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil" "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" ) @@ -44,9 +48,6 @@ func newEnvSetCmd(env *envCommand) *cobra.Command { if ref.version != "" { return fmt.Errorf("the set command does not accept versions") } - if len(args) < 2 { - return fmt.Errorf("expected a path and a value") - } path, err := resource.ParsePropertyPath(args[0]) if err != nil { @@ -56,8 +57,33 @@ func newEnvSetCmd(env *envCommand) *cobra.Command { return fmt.Errorf("path must contain at least one element") } + var value string + switch { + case len(args) == 2: + value = args[1] + //nolint:gosec // os.Stdin.Fd() == 0: uintptr -> int conversion is always safe + case !term.IsTerminal(int(os.Stdin.Fd())): + b, readerr := io.ReadAll(os.Stdin) + if readerr != nil { + return readerr + } + value = cmdutil.RemoveTrailingNewline(string(b)) + case !cmdutil.Interactive(): + return fmt.Errorf("value must be specified in non-interactive mode") + case secret: + value, err = cmdutil.ReadConsoleNoEcho("value") + if err != nil { + return err + } + default: + value, err = cmdutil.ReadConsole("value") + if err != nil { + return err + } + } + var yamlValue yaml.Node - if err := yaml.Unmarshal([]byte(args[1]), &yamlValue); err != nil { + if err := yaml.Unmarshal([]byte(value), &yamlValue); err != nil { return fmt.Errorf("invalid value: %w", err) } if len(yamlValue.Content) == 0 { diff --git a/cmd/esc/cli/testdata/env-set-secret.yaml b/cmd/esc/cli/testdata/env-set-secret.yaml index 581c4f9a..a67c904c 100644 --- a/cmd/esc/cli/testdata/env-set-secret.yaml +++ b/cmd/esc/cli/testdata/env-set-secret.yaml @@ -16,6 +16,8 @@ run: | esc env get default/test esc env set default/test password true --secret esc env get default/test + echo 'mysecret' | esc env set default/test password --secret + esc env get default/test --show-secrets esc env set default/test password '[]' --secret || echo OK stdout: | > esc env init default/test @@ -166,6 +168,22 @@ stdout: | ``` + > esc env set default/test password --secret + > esc env get default/test --show-secrets + # Value + ```json + { + "password": "mysecret" + } + ``` + # Definition + ```yaml + values: + password: + fn::secret: mysecret + + ``` + > esc env set default/test password [] --secret stderr: | > esc env init default/test @@ -186,5 +204,7 @@ stderr: | > esc env get default/test > esc env set default/test password true --secret > esc env get default/test + > esc env set default/test password --secret + > esc env get default/test --show-secrets > esc env set default/test password [] --secret test:3:21: secret values must be string literals