114 lines
3.6 KiB
Go
114 lines
3.6 KiB
Go
// ======================================================================================= go toolbox (mwx'2026)
|
|
//
|
|
// What gvm actually uses. The toolbox this came from carries a good deal more —
|
|
// base62 encoders, a mysql row reader, viper and gjson wrappers, an ip-range
|
|
// access check — and none of it was ever called here. Carried along, it was three
|
|
// dependencies and a page of code that nothing exercised and no test covered,
|
|
// including one access check that had never been wired up and would have panicked
|
|
// on the first malformed entry in its list. It is gone; the toolbox it belongs to
|
|
// still has it.
|
|
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"math/big"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
"github.com/AlecAivazis/survey/v2/terminal"
|
|
)
|
|
|
|
func Yesno(msg string, def bool, overwrite bool) bool { // -------------------------- AlecAivazis/survey: yes/no
|
|
|
|
if overwrite {
|
|
return true
|
|
}
|
|
|
|
var err error
|
|
tmp := ""
|
|
if def {
|
|
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"Yes", "No"}}, &tmp)
|
|
} else {
|
|
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"No", "Yes"}}, &tmp)
|
|
}
|
|
|
|
if err != nil {
|
|
if err == terminal.InterruptErr {
|
|
P(Crb("Interrupted."))
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
if tmp == "Yes" {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
func Inputpw(msg string) string { // ---------------------------------------- AlecAivazis/survey: input password
|
|
tmp := ""
|
|
err := survey.AskOne(&survey.Password{Message: msg}, &tmp)
|
|
if err != nil {
|
|
if err == terminal.InterruptErr {
|
|
P(Crb("Interrupted."))
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
return tmp
|
|
}
|
|
|
|
func GETid(n int) string { // --------------------------------------------------------- get base36 random string
|
|
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
ret := make([]byte, n)
|
|
for i := 0; i < n; i++ {
|
|
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
|
ret[i] = letters[num.Int64()]
|
|
}
|
|
return string(ret)
|
|
}
|
|
|
|
func Atoi(s string) int { // ------------------------------------------------------------------------------ atoi
|
|
i, err := strconv.Atoi(s)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return i
|
|
}
|
|
|
|
func Itoa(i int) string { // ------------------------------------------------------------------------------ itoa
|
|
return strconv.Itoa(i)
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------ print simple
|
|
|
|
func P(a ...any) (n int, err error) { return fmt.Fprintln(os.Stdout, a...) }
|
|
func PN(a ...any) (n int, err error) { return fmt.Fprint(os.Stdout, a...) }
|
|
func PF(format string, a ...any) (n int, err error) { return fmt.Fprintf(os.Stdout, format, a...) }
|
|
func SF(format string, a ...any) string { return fmt.Sprintf(format, a...) }
|
|
|
|
func PE(msg ...string) (n int, err error) {
|
|
if len(msg) == 2 {
|
|
return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Crb("ERROR"), Cwb(msg[0]), msg[1])
|
|
}
|
|
return fmt.Fprintf(os.Stdout, "%s: %s\n", Crb("ERROR"), Cwb(msg[0]))
|
|
}
|
|
func PO(msg ...string) (n int, err error) {
|
|
if len(msg) == 2 {
|
|
return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Cgb("OK"), Cwb(msg[0]), msg[1])
|
|
}
|
|
return fmt.Fprintf(os.Stdout, "%s: %s\n", Cgb("OK"), Cwb(msg[0]))
|
|
}
|
|
|
|
// errf is fmt.Errorf under a shorter name, to go with the P/PF/SF family.
|
|
func errf(format string, a ...any) error { return fmt.Errorf(format, a...) }
|
|
|
|
// -------------------------------------------------------------------------------------------- string functions
|
|
|
|
func SR(str string, n int) string { return strings.Repeat(str, n) }
|
|
|
|
// ========================================================================================================= END
|