You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gosuv/utils.go

108 lines
2.5 KiB

package main
import (
"errors"
"fmt"
"os"
"runtime"
"time"
log "github.com/sirupsen/logrus"
)
var ErrGoTimeout = errors.New("GoTimeoutFunc")
func GoFunc(f func() error) chan error {
ch := make(chan error)
go func() {
ch <- f()
}()
return ch
}
func GoTimeoutFunc(timeout time.Duration, f func() error) chan error {
ch := make(chan error)
go func() {
var err error
select {
case err = <-GoFunc(f):
ch <- err
case <-time.After(timeout):
log.Debugf("timeout: %v", f)
ch <- ErrGoTimeout
}
}()
return ch
}
func GoTimeout(f func() error, timeout time.Duration) (err error) {
done := make(chan bool)
go func() {
err = f()
done <- true
}()
select {
case <-time.After(timeout):
return ErrGoTimeout
case <-done:
return
}
}
func IsDir(dir string) bool {
fi, err := os.Stat(dir)
return err == nil && fi.IsDir()
}
func UserHomeDir() string {
if runtime.GOOS == "windows" {
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
if home == "" {
home = os.Getenv("USERPROFILE")
}
return home
}
return os.Getenv("HOME")
}
// askForConfirmation uses Scanln 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. If the input is not recognized, it will ask again. The function does not return
// until it gets a valid response from the user. Typically, you should use fmt to print out a question
// before calling askForConfirmation. E.g. fmt.Println("WARNING: Are you sure? (yes/no)")
func askForConfirmation() bool {
var response string
_, err := fmt.Scanln(&response)
if err != nil {
log.Fatal(err)
}
okayResponses := []string{"y", "Y", "yes", "Yes", "YES"}
nokayResponses := []string{"n", "N", "no", "No", "NO"}
if containsString(okayResponses, response) {
return true
} else if containsString(nokayResponses, response) {
return false
} else {
fmt.Println("Please type yes or no and then press enter:")
return askForConfirmation()
}
}
// You might want to put the following two functions in a separate utility package.
// posString returns the first index of element in slice.
// If slice does not contain element, returns -1.
func posString(slice []string, element string) int {
for index, elem := range slice {
if elem == element {
return index
}
}
return -1
}
// containsString returns true iff slice contains element
func containsString(slice []string, element string) bool {
return !(posString(slice, element) == -1)
}