@@ -4,15 +4,12 @@ import (
4
4
"io/fs"
5
5
"path"
6
6
"strings"
7
-
8
- "golang.org/x/xerrors"
9
7
)
10
8
11
- // overlayFS allows you to "join" together the template files tar file fs.FS
12
- // with the Terraform modules tar file fs.FS. We could potentially turn this
13
- // into something more parameterized/configurable, but the requirements here are
14
- // a _bit_ odd, because every file in the modulesFS includes the
15
- // .terraform/modules/ folder at the beginning of it's path.
9
+ // overlayFS allows you to "join" together multiple fs.FS. Files in any specific
10
+ // overlay will only be accessible if their path starts with the base path
11
+ // provided for the overlay. eg. An overlay at the path .terraform/modules
12
+ // should contain files with paths inside the .terraform/modules folder.
16
13
type overlayFS struct {
17
14
baseFS fs.FS
18
15
overlays []Overlay
@@ -23,64 +20,32 @@ type Overlay struct {
23
20
fs.FS
24
21
}
25
22
26
- func NewOverlayFS (baseFS fs.FS , overlays []Overlay ) (fs.FS , error ) {
27
- if err := valid (baseFS ); err != nil {
28
- return nil , xerrors .Errorf ("baseFS: %w" , err )
29
- }
30
-
31
- for _ , overlay := range overlays {
32
- if err := valid (overlay .FS ); err != nil {
33
- return nil , xerrors .Errorf ("overlayFS: %w" , err )
34
- }
35
- }
36
-
23
+ func NewOverlayFS (baseFS fs.FS , overlays []Overlay ) fs.FS {
37
24
return overlayFS {
38
25
baseFS : baseFS ,
39
26
overlays : overlays ,
40
- }, nil
27
+ }
41
28
}
42
29
43
- func (f overlayFS ) Open (p string ) (fs.File , error ) {
30
+ func (f overlayFS ) target (p string ) fs.FS {
31
+ target := f .baseFS
44
32
for _ , overlay := range f .overlays {
45
33
if strings .HasPrefix (path .Clean (p ), overlay .Path ) {
46
- return overlay .FS .Open (p )
34
+ target = overlay .FS
35
+ break
47
36
}
48
37
}
49
- return f . baseFS . Open ( p )
38
+ return target
50
39
}
51
40
52
- func (f overlayFS ) ReadDir (p string ) ([]fs.DirEntry , error ) {
53
- for _ , overlay := range f .overlays {
54
- if strings .HasPrefix (path .Clean (p ), overlay .Path ) {
55
- //nolint:forcetypeassert
56
- return overlay .FS .(fs.ReadDirFS ).ReadDir (p )
57
- }
58
- }
59
- //nolint:forcetypeassert
60
- return f .baseFS .(fs.ReadDirFS ).ReadDir (p )
41
+ func (f overlayFS ) Open (p string ) (fs.File , error ) {
42
+ return f .target (p ).Open (p )
61
43
}
62
44
63
- func (f overlayFS ) ReadFile (p string ) ([]byte , error ) {
64
- for _ , overlay := range f .overlays {
65
- if strings .HasPrefix (path .Clean (p ), overlay .Path ) {
66
- //nolint:forcetypeassert
67
- return overlay .FS .(fs.ReadFileFS ).ReadFile (p )
68
- }
69
- }
70
- //nolint:forcetypeassert
71
- return f .baseFS .(fs.ReadFileFS ).ReadFile (p )
45
+ func (f overlayFS ) ReadDir (p string ) ([]fs.DirEntry , error ) {
46
+ return fs .ReadDir (f .target (p ), p )
72
47
}
73
48
74
- // valid checks that the fs.FS implements the required interfaces.
75
- // The fs.FS interface is not sufficient.
76
- func valid (fsys fs.FS ) error {
77
- _ , ok := fsys .(fs.ReadDirFS )
78
- if ! ok {
79
- return xerrors .New ("overlayFS does not implement ReadDirFS" )
80
- }
81
- _ , ok = fsys .(fs.ReadFileFS )
82
- if ! ok {
83
- return xerrors .New ("overlayFS does not implement ReadFileFS" )
84
- }
85
- return nil
49
+ func (f overlayFS ) ReadFile (p string ) ([]byte , error ) {
50
+ return fs .ReadFile (f .target (p ), p )
86
51
}
0 commit comments