Skip to content

Commit

Permalink
Update/refactor utility functions
Browse files Browse the repository at this point in the history
- Replace 'containsString' function with slices.Contains.
- Move 'confirm' function to util package.
  • Loading branch information
tjmoore4 authored and benjaminjb committed Nov 13, 2023
1 parent d1535cd commit c42bd99
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 52 deletions.
10 changes: 0 additions & 10 deletions internal/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,3 @@ postgresclusters/hippo deleted`)

return cmd
}

// containsString returns true if slice contains element
func containsString(slice []string, element string) bool {
for _, elem := range slice {
if elem == element {
return true
}
}
return false
}
40 changes: 0 additions & 40 deletions internal/cmd/delete_test.go

This file was deleted.

5 changes: 3 additions & 2 deletions internal/cmd/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/utils/strings/slices"
"sigs.k8s.io/yaml"

"github.com/crunchydata/postgres-operator-client/internal"
Expand Down Expand Up @@ -353,7 +354,7 @@ func showUser(config *internal.Config, args []string, showSensitive bool) (strin
for i := 0; confirmed == nil && i < 10; i++ {
// retry 10 times or until a confirmation is given or denied,
// whichever comes first
confirmed = confirm(os.Stdin, os.Stdout)
confirmed = util.Confirm(os.Stdin, os.Stdout)
}

if confirmed == nil || !*confirmed {
Expand Down Expand Up @@ -420,7 +421,7 @@ func userData(fields []string, list *corev1.SecretList) (string, error) {
if err != nil {
return output, err
}
if containsString(fields, k) {
if slices.Contains(fields, k) {
output += fmt.Sprintf(" %s: %s\n", strings.ToUpper(k), string(d))
}
}
Expand Down
55 changes: 55 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2021 - 2023 Crunchy Data Solutions, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package util

import (
"bufio"
"fmt"
"io"

"k8s.io/utils/strings/slices"
)

// Confirm uses a Scanner to parse user input. A user must type in "yes" or "no"
// and then press enter. It has fuzzy matching, so "y", "Y", "yes", "YES",
// and "Yes" all count as confirmations and return 'true'. Similarly, "n", "N",
// "no", "No", "NO" all deny confirmation and return 'false'. If the input is not
// recognized, nil is returned.
func Confirm(reader io.Reader, writer io.Writer) *bool {
var response string
var boolVar bool

scanner := bufio.NewScanner(reader)
if scanner.Scan() {
response = scanner.Text()
}

if scanner.Err() != nil || response == "" {
fmt.Fprint(writer, "Please type yes or no and then press enter: ")
return nil
}

yesResponses := []string{"y", "Y", "yes", "Yes", "YES"}
noResponses := []string{"n", "N", "no", "No", "NO"}
if slices.Contains(yesResponses, response) {
boolVar = true
return &boolVar
} else if slices.Contains(noResponses, response) {
return &boolVar
} else {
fmt.Fprint(writer, "Please type yes or no and then press enter: ")
return nil
}
}
66 changes: 66 additions & 0 deletions internal/util/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2021 - 2023 Crunchy Data Solutions, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package util

import (
"bytes"
"io"
"strings"
"testing"

"gotest.tools/v3/assert"
)

func TestConfirmDelete(t *testing.T) {

testsCases := []struct {
input string
invalidResponse bool
confirmed bool
}{
{"abc", true, false}, // invalid
{"", true, false}, // invalid
{"y", false, true},
{"Y", false, true},
{"yes", false, true},
{"Yes", false, true},
{"YES", false, true},
{"n", false, false},
{"N", false, false},
{"no", false, false},
{"No", false, false},
{"NO", false, false},
{"yep", true, false}, // invalid
{"nope", true, false}, // invalid
}

for _, tc := range testsCases {
t.Run("input is "+tc.input, func(t *testing.T) {
var reader io.Reader = strings.NewReader(tc.input)
var writer bytes.Buffer
confirmed := Confirm(reader, &writer)
if tc.invalidResponse {
assert.Assert(t, confirmed == nil)
response, err := writer.ReadString(':')
assert.NilError(t, err)
assert.Equal(t, response, "Please type yes or no and then press enter:")

} else {
assert.Assert(t, confirmed != nil)
assert.Assert(t, *confirmed == tc.confirmed)
}
})
}
}

0 comments on commit c42bd99

Please sign in to comment.