Skip to content

Commit

Permalink
Merge pull request #272 from DopplerHQ/configure-set-stdin
Browse files Browse the repository at this point in the history
Support supplying `doppler configure set` value on stdin
  • Loading branch information
Piccirello authored Oct 25, 2021
2 parents a22b27a + 07d368f commit 8d7e3b2
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 12 deletions.
47 changes: 41 additions & 6 deletions pkg/cmd/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ limitations under the License.
package cmd

import (
"bufio"
"errors"
"fmt"
"os"
"strings"

"github.com/DopplerHQ/cli/pkg/configuration"
Expand Down Expand Up @@ -86,7 +88,7 @@ doppler configure get key otherkey`,
ValidArgsFunction: currentConfigOptionsValidArgs,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("requires at least 1 arg(s), only received 0")
return errors.New("requires at least 1 arg(s), received 0")
}

for _, arg := range args {
Expand Down Expand Up @@ -123,11 +125,20 @@ doppler configure set key=123 otherkey=456`,
ValidArgsFunction: configOptionsValidArgs,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("requires at least 1 arg(s), only received 0")
return errors.New("requires at least 1 arg(s), received 0")
}

if !strings.Contains(args[0], "=") {
if len(args) == 2 {
if len(args) == 1 {
hasData, e := utils.HasDataOnStdIn()
if e != nil {
utils.HandleError(e)
}
if !hasData {
return errors.New("Value must be suppied on stdin or as an argument")
}
return nil
} else if len(args) == 2 {
if configuration.IsValidConfigOption(args[0]) || configuration.IsTranslatableConfigOption(args[0]) {
return nil
}
Expand All @@ -139,9 +150,12 @@ doppler configure set key=123 otherkey=456`,

for _, arg := range args {
option := strings.Split(arg, "=")
if len(option) < 2 || (!configuration.IsValidConfigOption(option[0]) && !configuration.IsTranslatableConfigOption(option[0])) {
if !configuration.IsValidConfigOption(option[0]) && !configuration.IsTranslatableConfigOption(option[0]) {
return errors.New("invalid option " + option[0])
}
if len(option) < 2 {
return errors.New("option " + option[0] + " requires a value")
}
}

return nil
Expand All @@ -150,7 +164,28 @@ doppler configure set key=123 otherkey=456`,
jsonFlag := utils.OutputJSON

options := map[string]string{}
if !strings.Contains(args[0], "=") {

if len(args) == 1 && !strings.Contains(args[0], "=") {
var input []string
scanner := bufio.NewScanner(os.Stdin)
// read input from stdin
for {
if ok := scanner.Scan(); !ok {
if e := scanner.Err(); e != nil {
utils.HandleError(e, "Unable to read input from stdin")
}

break
}

s := scanner.Text()
input = append(input, s)
}

key := args[0]
value := strings.Join(input, "\n")
options[key] = value
} else if !strings.Contains(args[0], "=") {
options[args[0]] = args[1]
} else {
for _, option := range args {
Expand Down Expand Up @@ -183,7 +218,7 @@ doppler configure unset key otherkey`,
ValidArgsFunction: currentConfigOptionsValidArgs,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("requires at least 1 arg(s), only received 0")
return errors.New("requires at least 1 arg(s), received 0")
}

for _, arg := range args {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ doppler run --command "YOUR_COMMAND && YOUR_OTHER_COMMAND"`,
return errors.New("arg(s) may not be set when using --command flag")
}
} else if len(args) == 0 {
return errors.New("requires at least 1 arg(s), only received 0")
return errors.New("requires at least 1 arg(s), received 0")
}

return nil
Expand Down
8 changes: 3 additions & 5 deletions pkg/cmd/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,11 @@ func setSecrets(cmd *cobra.Command, args []string) {
// format: 'doppler secrets set KEY' (interactive)

// check for existing data on stdin
stat, e := os.Stdin.Stat()
hasData, e := utils.HasDataOnStdIn()
if e != nil {
utils.HandleError(e, "Unable to stat stdin")
utils.HandleError(e)
}

dataOnStdin := (stat.Mode() & os.ModeCharDevice) == 0
interactiveMode := !dataOnStdin
interactiveMode := !hasData
if interactiveMode {
if !canPromptUser {
utils.HandleError(errors.New("Secret value must be provided when using --no-interactive"))
Expand Down
12 changes: 12 additions & 0 deletions pkg/utils/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.
package utils

import (
"errors"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -76,3 +77,14 @@ func WriteTempFile(name string, data []byte, perm os.FileMode) (string, error) {

return tmpFileName, nil
}

func HasDataOnStdIn() (bool, error) {
stat, e := os.Stdin.Stat()
if e != nil {
LogDebugError(e)
return false, errors.New("Unable to stat stdin")
}

hasData := (stat.Mode() & os.ModeCharDevice) == 0
return hasData, nil
}
7 changes: 7 additions & 0 deletions tests/e2e/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ config="$("$DOPPLER_BINARY" configure get config --configuration=./temp-config -

beforeEach

# test set using stdin
echo 123 | "$DOPPLER_BINARY" configure set config --configuration=./temp-config --scope=/ --silent
config="$("$DOPPLER_BINARY" configure get config --configuration=./temp-config --scope=/ --json)"
[[ "$config" == '{"enclave.config":"123"}' ]] || error "ERROR: unexpected config contents after 'set' w/ stdin"

beforeEach

#
# CLI v3 compatability tests (DPLR-435)
#
Expand Down

0 comments on commit 8d7e3b2

Please sign in to comment.