summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-04-09 21:00:23 +0700
committerShulhan <ms@kilabit.info>2023-04-09 21:00:23 +0700
commit860bac9bc6c50ffdd04b0f272f4786806adf9ce6 (patch)
treef8a5254ba6656acbf160a14ba288430f72fa5837
parentace497bd8c22c718bedd18582db4ed07780d1a44 (diff)
downloadpakakeh.go-860bac9bc6c50ffdd04b0f272f4786806adf9ce6.tar.xz
lib/os: copy lib/io#ConfirmYesNo to lib/os
The lib/io package will be deprecated in the future.
-rw-r--r--lib/os/os.go54
-rw-r--r--lib/os/os_test.go63
2 files changed, 117 insertions, 0 deletions
diff --git a/lib/os/os.go b/lib/os/os.go
index ed2c197e..53999775 100644
--- a/lib/os/os.go
+++ b/lib/os/os.go
@@ -7,6 +7,7 @@
package os
import (
+ "bufio"
"fmt"
"io"
"log"
@@ -16,6 +17,59 @@ import (
"github.com/shuLhan/share/lib/ascii"
)
+// ConfirmYesNo display a question to standard output and read for answer
+// from input Reader for simple yes "y" or no "n" answer.
+// If input Reader is nil, it will set to standard input.
+// If "defIsYes" is true and answer is empty (only new line), then it will
+// return true.
+func ConfirmYesNo(in io.Reader, msg string, defIsYes bool) bool {
+ var (
+ r *bufio.Reader
+ b, answer byte
+ err error
+ )
+
+ if in == nil {
+ r = bufio.NewReader(os.Stdin)
+ } else {
+ r = bufio.NewReader(in)
+ }
+
+ yon := "[y/N]"
+
+ if defIsYes {
+ yon = "[Y/n]"
+ }
+
+ fmt.Printf("%s %s ", msg, yon)
+
+ for {
+ b, err = r.ReadByte()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ break
+ }
+ if b == ' ' || b == '\t' {
+ continue
+ }
+ if b == '\n' {
+ break
+ }
+ if answer == 0 {
+ answer = b
+ }
+ }
+
+ if answer == 'y' || answer == 'Y' {
+ return true
+ }
+ if answer == 0 {
+ return defIsYes
+ }
+
+ return false
+}
+
// Copy file from in to out.
// If the output file is already exist, it will be truncated.
// If the file is not exist, it will created with permission set to user's
diff --git a/lib/os/os_test.go b/lib/os/os_test.go
index 2d0d7a3f..aa5337a2 100644
--- a/lib/os/os_test.go
+++ b/lib/os/os_test.go
@@ -5,8 +5,71 @@ import (
"testing"
"github.com/shuLhan/share/lib/test"
+ "github.com/shuLhan/share/lib/test/mock"
)
+func TestConfirmYesNo(t *testing.T) {
+ cases := []struct {
+ answer string
+ defIsYes bool
+ exp bool
+ }{{
+ defIsYes: true,
+ exp: true,
+ }, {
+ defIsYes: true,
+ answer: ` `,
+ exp: true,
+ }, {
+ defIsYes: true,
+ answer: ` no`,
+ exp: false,
+ }, {
+ defIsYes: true,
+ answer: ` yes`,
+ exp: true,
+ }, {
+ defIsYes: true,
+ answer: ` Ys`,
+ exp: true,
+ }, {
+ defIsYes: false,
+ exp: false,
+ }, {
+ defIsYes: false,
+ answer: ``,
+ exp: false,
+ }, {
+
+ defIsYes: false,
+ answer: ` no`,
+ exp: false,
+ }, {
+ defIsYes: false,
+ answer: ` yes`,
+ exp: true,
+ }}
+
+ in := mock.Stdin()
+
+ for _, c := range cases {
+ t.Log(c)
+
+ _, err := in.WriteString(c.answer + "\n")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ mock.ResetStdin(false)
+
+ got := ConfirmYesNo(in, `confirm`, c.defIsYes)
+
+ test.Assert(t, `answer`, c.exp, got)
+
+ mock.ResetStdin(true)
+ }
+}
+
func TestCopy(t *testing.T) {
cases := []struct {
desc string