package main import ( "fmt" "os" "os/exec" "runtime" "strconv" "strings" "time" "gopkg.in/yaml.v3" ) func isExist(fp string) bool { _, err := os.Stat(fp) return !os.IsNotExist(err) } func mkdir(fp string) error { return os.MkdirAll(fp, os.ModePerm) } func cloneTemplate(base string) error { _, err := exec.Command("git", "clone", "https://gitter.top/mder/template", base).Output() if err != nil { _, _ = fmt.Fprintf(os.Stderr, "get latest template failed: %v\n", err) return err } return nil } func readConfigFile() Config { configBuffer, err := os.ReadFile("config.yaml") if err != nil { panic(err) } var config Config if err := yaml.Unmarshal(configBuffer, &config); err != nil { sfault("read config file failed: %v", err) } config.Now = time.Now() return config } func readFile(fp string) []byte { if body, err := os.ReadFile(fp); err != nil { sfault("read file failed: %v", err) } else { return body } return nil } func datetimeStringToTime(datetime string) (time.Time, error) { if datetime == "" { return time.Now(), nil } var tpl = "2006-01-02 15:04:05" t, err := time.ParseInLocation(tpl, datetime, time.Local) if err != nil { return time.Now(), err } return t, nil } func mustString(i interface{}) string { s, ok := i.(string) if !ok { return "" } return s } func mustStringSlice(i interface{}) []string { var arr []string iarr, ok := i.([]interface{}) if !ok { return []string{} } for _, str := range iarr { r, ok := str.(string) if !ok { continue } arr = append(arr, r) } return arr } func int2String(i int) string { return strconv.FormatInt(int64(i), 10) } type RunInfo struct { pc uintptr line int filename string funcName string } // 获取正在运行的函数名 func runInfo() RunInfo { pc, file, line, ok := runtime.Caller(2) if !ok { return RunInfo{} } funcName := runtime.FuncForPC(pc).Name() return RunInfo{pc, line, file, funcName} } func sout(format string, args ...interface{}) { if !strings.HasSuffix(format, "\n") { format = fmt.Sprintf("%s\n", format) } _, _ = fmt.Fprintf(os.Stdout, format, args...) } func serr(format string, args ...interface{}) { var ri = runInfo() real := fmt.Sprintf(format, args...) _, _ = fmt.Fprintf(os.Stderr, "runtime: %+v\n%s\n", ri, real) } func sfault(format string, args ...interface{}) { var ri = runInfo() real := fmt.Sprintf(format, args...) _, _ = fmt.Fprintf(os.Stderr, "runtime: %+v\n%s\n", ri, real) os.Exit(1) } func slash(str string) string { if runtime.GOOS == "windows" { return strings.ReplaceAll(str, "/", "\\") } return str }