diff options
| author | Shulhan <ms@kilabit.info> | 2023-04-09 21:00:23 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-04-09 21:00:23 +0700 |
| commit | 860bac9bc6c50ffdd04b0f272f4786806adf9ce6 (patch) | |
| tree | f8a5254ba6656acbf160a14ba288430f72fa5837 | |
| parent | ace497bd8c22c718bedd18582db4ed07780d1a44 (diff) | |
| download | pakakeh.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.go | 54 | ||||
| -rw-r--r-- | lib/os/os_test.go | 63 |
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 |
