package configui import ( "encoding/json" "errors" "log" "os" "os/exec" "runtime" "sync" ) var UNIX_SHELL = "bash" var WIN_SHELL = "cmd" type File struct { Path string `json:"path"` Alias string `json:"name"` Action string `json:"action"` RO bool `json:"ro"` // used for parsing post data Data string `json:"data"` lock sync.RWMutex `json:"-"` } func (f *File) Read() ([]byte, error) { f.lock.RLock() defer f.lock.RUnlock() data, err := os.ReadFile(f.Path) if err != nil { log.Println(err) return nil, err } return data, nil } func (f *File) Write(data []byte) error { if f.RO { return errors.New("this file has readonly set") } f.lock.Lock() defer f.lock.Unlock() info, err := os.Stat(f.Path) if err != nil { return err } return os.WriteFile(f.Path, data, info.Mode()) } func (f *File) Do() (string, error) { if f.Action == "" { return "", nil } cmd := exec.Command(UNIX_SHELL, "-c", f.Action) if runtime.GOOS == "windows" { cmd = exec.Command(WIN_SHELL, "/c", f.Action) } out, err := cmd.CombinedOutput() if err != nil { return "", err } return string(out), nil } func ReadConfig(confstr string) ([]File, error) { conf := []File{} err := json.Unmarshal([]byte(confstr), &conf) if err != nil { return nil, err } for i := range conf { if conf[i].Alias == "" { conf[i].Alias = conf[i].Path } } return conf, nil } func GetFileMap(files []File) map[string]*File { fileMap := map[string]*File{} for i := range files { fileMap[files[i].Alias] = &files[i] } return fileMap }