func PrintInfoF(w io.Writer, text string, mode int, args ...interface{}) {
	PrintInfo(w, fmt.Sprintf(text, args...), mode)
}
PrintInfoF prints formatable text with a marker to easily spot it.
package util
import (
	"fmt"
	"io"
	"os"
	"path"
	"runtime"
	"strings"
)
const (
	PiInfo = iota
	PiTask
	PiResult
	PiError
	PiMildError
)
type RepoError struct {
	Update bool
	Clone  bool
	Err    error
}
func (r RepoError) Error() string {
	return r.Err.Error()
}
func FileExists(path string) bool {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}
	return true
}
func BinaryInstalled(binary string) bool {
	env := os.Getenv("PATH")
	paths := strings.Split(env, ":")
	if runtime.GOOS == "windows" {
		paths = strings.Split(env, ";")
	}
	for _, fpath := range paths {
		pathToBinary := path.Join(fpath, binary)
		if runtime.GOOS == "windows" {
			pathToBinary = path.Join(fpath, binary+".exe")
		}
		if FileExists(pathToBinary) {
			return true
		}
	}
	return false
}
func LocalRepoName(url string) string {
	parts := strings.Split(url, "/")
	possibleName := parts[len(parts)-1]
	parts = strings.Split(possibleName, ":")
	return parts[len(parts)-1]
}
func PrintInfo(w io.Writer, text string, mode int) {
	var pre string
	if w == nil {
		panic("PrintInfo call without Writer")
	}
	switch {
	case mode == PiInfo:
		pre = ""
	case mode == PiTask:
		pre = "\033[36m*\033[39m "
	case mode == PiResult:
		pre = "\033[35m==>\033[39m "
	case mode == PiError:
		pre = "\033[31mError:\033[39m "
	case mode == PiMildError:
		pre = "\033[33m==\033[39m "
	}
	line := pre + text
	fmt.Fprintf(w, "%s\n", line)
}