@@ -8,11 +8,10 @@ import (
8
8
"golang.org/x/xerrors"
9
9
)
10
10
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.
11
+ // overlayFS allows you to "join" together multiple fs.FS. Files in any specific
12
+ // overlay will only be accessible if their path starts with the base path
13
+ // provided for the overlay. eg. An overlay at the path .terraform/modules
14
+ // should contain files with paths inside the .terraform/modules folder.
16
15
type overlayFS struct {
17
16
baseFS fs.FS
18
17
overlays []Overlay
@@ -23,64 +22,50 @@ type Overlay struct {
23
22
fs.FS
24
23
}
25
24
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
-
25
+ func NewOverlayFS (baseFS fs.FS , overlays []Overlay ) fs.FS {
37
26
return overlayFS {
38
27
baseFS : baseFS ,
39
28
overlays : overlays ,
40
- }, nil
29
+ }
41
30
}
42
31
43
32
func (f overlayFS ) Open (p string ) (fs.File , error ) {
33
+ target := f .baseFS
44
34
for _ , overlay := range f .overlays {
45
35
if strings .HasPrefix (path .Clean (p ), overlay .Path ) {
46
- return overlay .FS .Open (p )
36
+ target = overlay .FS
37
+ break
47
38
}
48
39
}
49
- return f . baseFS .Open (p )
40
+ return target .Open (p )
50
41
}
51
42
52
43
func (f overlayFS ) ReadDir (p string ) ([]fs.DirEntry , error ) {
44
+ target := f .baseFS
53
45
for _ , overlay := range f .overlays {
54
46
if strings .HasPrefix (path .Clean (p ), overlay .Path ) {
55
- //nolint:forcetypeassert
56
- return overlay . FS .(fs. ReadDirFS ). ReadDir ( p )
47
+ target = overlay . FS
48
+ break
57
49
}
58
50
}
59
- //nolint:forcetypeassert
60
- return f .baseFS .(fs.ReadDirFS ).ReadDir (p )
51
+ it , ok := target .(fs.ReadDirFS )
52
+ if ! ok {
53
+ return nil , xerrors .New ("provided fs.FS does not implement fs.ReadDirFS" )
54
+ }
55
+ return it .ReadDir (p )
61
56
}
62
57
63
58
func (f overlayFS ) ReadFile (p string ) ([]byte , error ) {
59
+ target := f .baseFS
64
60
for _ , overlay := range f .overlays {
65
61
if strings .HasPrefix (path .Clean (p ), overlay .Path ) {
66
- //nolint:forcetypeassert
67
- return overlay . FS .(fs. ReadFileFS ). ReadFile ( p )
62
+ target = overlay . FS
63
+ break
68
64
}
69
65
}
70
- //nolint:forcetypeassert
71
- return f .baseFS .(fs.ReadFileFS ).ReadFile (p )
72
- }
73
-
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 )
66
+ it , ok := target .(fs.ReadFileFS )
82
67
if ! ok {
83
- return xerrors .New ("overlayFS does not implement ReadFileFS" )
68
+ return nil , xerrors .New ("provided fs.FS does not implement fs. ReadFileFS" )
84
69
}
85
- return nil
70
+ return it . ReadFile ( p )
86
71
}
0 commit comments