feat(input): Full refacto of the user input system
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
29
helpers/input/bool.go
Normal file
29
helpers/input/bool.go
Normal file
@ -0,0 +1,29 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// YesOrNo ask user for a yes or no reply and try until we get a possible answer.
|
||||
func YesOrNo() bool {
|
||||
|
||||
value := Ask(true, func(in string) (string, error) {
|
||||
lUserInput := strings.ToLower(in)
|
||||
|
||||
for _, positiveAnswer := range []string{"yes", "y", "1", "true"} {
|
||||
if lUserInput == positiveAnswer {
|
||||
return "y", nil
|
||||
}
|
||||
}
|
||||
for _, negativeAnswer := range []string{"no", "n", "0", "false"} {
|
||||
if lUserInput == negativeAnswer {
|
||||
return "n", nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("expecting a yes or no answer, try again")
|
||||
})
|
||||
|
||||
return value == "y"
|
||||
}
|
40
helpers/input/input.go
Normal file
40
helpers/input/input.go
Normal file
@ -0,0 +1,40 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Validator represent signature of the input validation function.
|
||||
type Validator func(in string) (string, error)
|
||||
|
||||
// Ask will ask user for an input and check validity with provided fn function.
|
||||
func Ask(mandatory bool, fn Validator) string {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for {
|
||||
|
||||
scanner.Scan()
|
||||
userInput := scanner.Text()
|
||||
|
||||
if userInput == "" {
|
||||
|
||||
if mandatory {
|
||||
log.Warn("Empty input, try again")
|
||||
continue
|
||||
}
|
||||
|
||||
return userInput
|
||||
}
|
||||
|
||||
value, err := fn(userInput)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf("%s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
}
|
51
helpers/input/other.go
Normal file
51
helpers/input/other.go
Normal file
@ -0,0 +1,51 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.home.m-and-m.ovh/mderasse/gouick/helpers"
|
||||
"git.home.m-and-m.ovh/mderasse/gouick/models"
|
||||
)
|
||||
|
||||
// Path ask user for a path string and try until we get a possible answer.
|
||||
func Path(mandatory bool) string {
|
||||
|
||||
value := Ask(mandatory, func(in string) (string, error) {
|
||||
|
||||
path := filepath.Clean(in)
|
||||
|
||||
_, err := helpers.CheckAndCreateDir(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("please try again")
|
||||
}
|
||||
|
||||
return path, nil
|
||||
})
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
// APITypeName ask user for a string that is a valid API Type name and try until we get a possible answer.
|
||||
func APITypeName(mandatory bool) models.APITypeName {
|
||||
|
||||
possibleAPITypes := make([]string, 0)
|
||||
for _, apiType := range models.GetListOfAPITypeName() {
|
||||
possibleAPITypes = append(possibleAPITypes, string(apiType))
|
||||
}
|
||||
|
||||
value := Ask(mandatory, func(in string) (string, error) {
|
||||
|
||||
apiTypeName, err := models.NewAPITypeNameFromInput(in)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid API type (possible values: %s)", strings.Join(possibleAPITypes, ", "))
|
||||
}
|
||||
|
||||
return string(apiTypeName), nil
|
||||
})
|
||||
|
||||
apiTypeName, _ := models.NewAPITypeName(value)
|
||||
|
||||
return apiTypeName
|
||||
}
|
66
helpers/input/string.go
Normal file
66
helpers/input/string.go
Normal file
@ -0,0 +1,66 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/mail"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
// RegexAlphanumerical is a basic alphanumerical regex to be use in RegexInput function.
|
||||
RegexAlphanumerical = regexp.MustCompile(`^[a-zA-Z0-9\-\_]*$`)
|
||||
// RegexAlphanumericalAndSpace is a basic alphanumerical regex with space as an additionnal valid character to be use in RegexInput function.
|
||||
RegexAlphanumericalAndSpace = regexp.MustCompile(`^[a-zA-Z0-9\-\_\s]*$`)
|
||||
)
|
||||
|
||||
// Regex permit to ask user for an input and check that it match the given regex rule.
|
||||
// if not user will see the errMsg and be asked for another input.
|
||||
func Regex(mandatory bool, regex *regexp.Regexp, errMsg string) string {
|
||||
|
||||
value := Ask(mandatory, func(in string) (string, error) {
|
||||
|
||||
if !regex.MatchString(in) {
|
||||
return "", fmt.Errorf("%s", errMsg)
|
||||
}
|
||||
|
||||
return in, nil
|
||||
})
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
// Alphanumerical will ask user for an input respecting the RegexAlphanumerical.
|
||||
func Alphanumerical(mandatory bool) string {
|
||||
return Regex(mandatory, RegexAlphanumerical, "Please use a-z, A-Z, 0-9, - and _ characters only.")
|
||||
}
|
||||
|
||||
// AlphanumericalAndSpace will ask user for an input respecting the RegexAlphanumericalAndSpace.
|
||||
func AlphanumericalAndSpace(mandatory bool) string {
|
||||
return Regex(mandatory, RegexAlphanumericalAndSpace, "Please use a-z, A-Z, 0-9, -, _ and space characters only.")
|
||||
}
|
||||
|
||||
// String permit to ask user for any kind of string.
|
||||
func String(mandatory bool) string {
|
||||
|
||||
value := Ask(mandatory, func(in string) (string, error) {
|
||||
return in, nil
|
||||
})
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
// Mail permit to ask user for an email address.
|
||||
func Mail(mandatory bool) string {
|
||||
|
||||
value := Ask(mandatory, func(in string) (string, error) {
|
||||
|
||||
_, err := mail.ParseAddress(in)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("expecting a valid mail address, please try again")
|
||||
}
|
||||
|
||||
return in, nil
|
||||
})
|
||||
|
||||
return value
|
||||
}
|
Reference in New Issue
Block a user