aboutsummaryrefslogtreecommitdiffstats
path: root/internal/wfs/wfs.go
blob: bcdca0001e8cfc13062677745aeb8f03de60542e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package wfs

import (
	"io"
	"io/fs"
	"path"
)

type ReadLinkFS interface {
	fs.FS

	ReadLink(string) (string, error)
	Lstat(string) (fs.FileInfo, error)
}

func ReadLink(fsys fs.FS, name string) (string, error) {
	sym, ok := fsys.(ReadLinkFS)
	if !ok {
		return "", &fs.PathError{Op: "readlink", Path: name, Err: fs.ErrInvalid}
	}
	return sym.ReadLink(name)
}

func Lstat(fsys fs.FS, name string) (fs.FileInfo, error) {
	sym, ok := fsys.(ReadLinkFS)
	if !ok {
		return fs.Stat(fsys, name)
	}
	return sym.Lstat(name)
}

type FS interface {
	fs.FS

	Create(string, fs.FileMode) (io.WriteCloser, error)
	Remove(string) error
	Mkdir(string) error
	Symlink(string, string) error
	Chmod(string, fs.FileMode) error
}

type MkdirModeFS interface {
	FS

	MkdirMode(string, fs.FileMode) error
}

func MkdirMode(fsys FS, name string, mode fs.FileMode) error {
	if fsys, ok := fsys.(MkdirModeFS); ok {
		return fsys.MkdirMode(name, mode)
	}
	if err := fsys.Mkdir(name); err != nil {
		return err
	}
	return fsys.Chmod(name, mode)
}

func removeDir(fsys FS, dir string) error {
	entries, err := fs.ReadDir(fsys, dir)
	if err != nil {
		return err
	}
	for _, f := range entries {
		name := path.Join(dir, f.Name())
		if f.IsDir() {
			err = removeDir(fsys, name)
		} else {
			err = fsys.Remove(name)
		}
		if err != nil {
			return err
		}
	}
	return fsys.Remove(dir)
}

func RemoveAll(fsys FS, path string) error {
	stat, err := Lstat(fsys, path)
	if err != nil {
		return err
	}
	if stat.IsDir() {
		return removeDir(fsys, path)
	}
	return fsys.Remove(path)
}