// Copyright 2024 Matthew Rich . All rights reserved. package tempdir import ( "os" "path/filepath" "strings" "fmt" "io/fs" "log/slog" "io" ) type Path string func (t *Path) ValidPath() bool { if filepath.IsAbs(string(*t)) && strings.HasPrefix(string(*t), os.TempDir()) && len(*t) > 1 { return true } return false } func (t *Path) Create() (err error) { if t.ValidPath() && t.Exists() { return } slog.Info("tempdir.Create()", "path", string(*t)) var TempDir string TempDir, err = os.MkdirTemp("", string(*t)) if err != nil || TempDir == "" { err = fmt.Errorf("%w: Failed creating temp dir %s", err, TempDir) } *t = Path(TempDir) return } func (t *Path) Remove() { slog.Info("tempdir.Remove()", "path", *t) if t.ValidPath() { os.RemoveAll(string(*t)) } } func (t *Path) Open(name string) (r io.ReadCloser, err error) { path := t.FilePath(name) r, err = os.Open(path) return } func (t *Path) CreateFileFromReader(name string, r io.Reader) (path string, err error) { path = filepath.Join(string(*t), name) _, statErr := os.Stat(path) if os.IsNotExist(statErr) { if file, createErr := os.Create(path); createErr == nil { defer file.Close() buf := make([]byte, 32*1024) _, err = io.CopyBuffer(file, r, buf) } else { err = createErr } } return } func (t *Path) CreateFile(name string, content string) (err error) { path := filepath.Join(string(*t), name) _, statErr := os.Stat(path) if os.IsNotExist(statErr) { if file, createErr := os.Create(path); createErr == nil { defer file.Close() _, err = file.Write([]byte(content)) } else { err = createErr } } return } func (t *Path) FileExists(name string) bool { path := t.FilePath(name) _, statErr := os.Stat(path) return ! os.IsNotExist(statErr) } func (t *Path) Exists() (bool) { _, statErr := os.Stat(string(*t)) return ! os.IsNotExist(statErr) } func (t *Path) FilePath(name string) string { return filepath.Join(string(*t), name) } func (t *Path) URIPath(name string) string { return fmt.Sprintf("file://%s", t.FilePath(name)) } func (t *Path) Mkdir(name string, mode os.FileMode) (err error) { var path string if path, err = filepath.Abs(filepath.Join(string(*t), name)); err == nil { if ! (*Path)(&path).ValidPath() { return fmt.Errorf("Invalid path %s of %s", path, *t) } _, statErr := os.Stat(path) if os.IsNotExist(statErr) { err = os.Mkdir(path, mode) } } return } func (t *Path) DirFS() fs.FS { if t.ValidPath() { return os.DirFS(string(*t)) } return nil }