Skip to content

Commit f224b58

Browse files
committed
refactor: Use fs.FS interface instead of os file access
Replace all IO operations based on the `os` package with the ones from the abstract `fs` package and pass a `fsys` parameter down to functions that need it. Use `embed.FS` in tests. Signed-off-by: Maximilian Blatt <[email protected]>
1 parent 2686d47 commit f224b58

File tree

5 files changed

+33
-19
lines changed

5 files changed

+33
-19
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ require (
1313
github.com/google/go-cmp v0.6.0
1414
google.golang.org/protobuf v1.31.0
1515
gopkg.in/yaml.v3 v3.0.1
16-
k8s.io/api v0.28.4
1716
k8s.io/apimachinery v0.28.4
1817
sigs.k8s.io/controller-tools v0.13.0
1918
)
@@ -73,6 +72,7 @@ require (
7372
google.golang.org/grpc v1.59.0 // indirect
7473
gopkg.in/inf.v0 v0.9.1 // indirect
7574
gopkg.in/yaml.v2 v2.4.0 // indirect
75+
k8s.io/api v0.28.4 // indirect
7676
k8s.io/apiextensions-apiserver v0.28.3 // indirect
7777
k8s.io/client-go v0.28.3 // indirect
7878
k8s.io/klog/v2 v2.100.1 // indirect

go.sum

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
7575
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
7676
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
7777
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
78-
github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0=
79-
github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
8078
github.com/crossplane/crossplane-runtime v1.14.3 h1:YNGALph/UJTtQO+cJ9KGQ5NfALI5453PeE93Aqy9SWg=
8179
github.com/crossplane/crossplane-runtime v1.14.3/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
8280
github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8=
@@ -724,14 +722,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
724722
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
725723
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
726724
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
727-
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
728-
k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
729725
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
730726
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
731727
k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
732728
k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
733-
k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
734-
k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
735729
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
736730
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
737731
k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=

internal/fn/fn.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"context"
66
"encoding/base64"
77
"io"
8+
"io/fs"
9+
"os"
810

911
"dario.cat/mergo"
1012
"google.golang.org/protobuf/encoding/protojson"
@@ -29,7 +31,8 @@ import (
2931
type Function struct {
3032
fnv1beta1.UnimplementedFunctionRunnerServiceServer
3133

32-
log logging.Logger
34+
log logging.Logger
35+
fsys fs.FS
3336
}
3437

3538
// FunctionOpt can modify a Function upon creation.
@@ -40,12 +43,22 @@ func WithLogger(log logging.Logger) FunctionOpt {
4043
return func(f *Function) { f.log = log }
4144
}
4245

46+
func WithFileSystem(fsys fs.FS) FunctionOpt {
47+
return func(f *Function) { f.fsys = fsys }
48+
}
49+
4350
// NewFunction creates a new Function with the given options.
4451
func NewFunction(opts ...FunctionOpt) *Function {
4552
f := &Function{}
4653
for _, opt := range opts {
4754
opt(f)
4855
}
56+
if f.fsys == nil {
57+
// Note: Only works on Linux and Mac.
58+
// There is no reliable solution for Windows (do we even support it?)
59+
// Ref: https://github.com/golang/go/issues/44279
60+
f.fsys = os.DirFS("/")
61+
}
4962
return f
5063
}
5164

@@ -68,7 +81,7 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ
6881
return rsp, nil
6982
}
7083

71-
tg, err := NewTemplateSourceGetter(in)
84+
tg, err := NewTemplateSourceGetter(f.fsys, in)
7285
if err != nil {
7386
response.Fatal(rsp, errors.Wrap(err, "invalid function input"))
7487
return rsp, nil

internal/fn/fn_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package fn
22

33
import (
44
"context"
5+
"embed"
56
"fmt"
67
"testing"
78

@@ -38,6 +39,9 @@ var (
3839

3940
path = "testdata/templates"
4041
wrongPath = "testdata/wrong"
42+
43+
//go:embed testdata
44+
testdataFS embed.FS
4145
)
4246

4347
func TestRunFunction(t *testing.T) {
@@ -425,7 +429,7 @@ func TestRunFunction(t *testing.T) {
425429
Results: []*fnv1beta1.Result{
426430
{
427431
Severity: fnv1beta1.Severity_SEVERITY_FATAL,
428-
Message: "invalid function input: cannot read tmpl from the folder {testdata/wrong}: lstat testdata/wrong: no such file or directory",
432+
Message: "invalid function input: cannot read tmpl from the folder {testdata/wrong}: open testdata/wrong: file does not exist",
429433
},
430434
},
431435
},
@@ -587,7 +591,10 @@ func TestRunFunction(t *testing.T) {
587591

588592
for name, tc := range cases {
589593
t.Run(name, func(t *testing.T) {
590-
f := &Function{log: logging.NewNopLogger()}
594+
f := NewFunction(
595+
WithLogger(logging.NewNopLogger()),
596+
WithFileSystem(testdataFS),
597+
)
591598
rsp, err := f.RunFunction(tc.args.ctx, tc.args.req)
592599

593600
if diff := cmp.Diff(tc.want.rsp, rsp, protocmp.Transform()); diff != "" {

internal/fn/template.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package fn
22

33
import (
4-
"os"
4+
"io/fs"
55
"path/filepath"
66

77
"github.com/crossplane/function-sdk-go/errors"
@@ -18,12 +18,12 @@ type TemplateGetter interface {
1818
}
1919

2020
// NewTemplateSourceGetter returns a TemplateGetter based on the cd source
21-
func NewTemplateSourceGetter(in *v1beta1.GoTemplate) (TemplateGetter, error) {
21+
func NewTemplateSourceGetter(fsys fs.FS, in *v1beta1.GoTemplate) (TemplateGetter, error) {
2222
switch in.Source {
2323
case v1beta1.InlineSource:
2424
return newInlineSource(in)
2525
case v1beta1.FileSystemSource:
26-
return newFileSource(in)
26+
return newFileSource(fsys, in)
2727
case "":
2828
return nil, errors.Errorf("source is required")
2929
default:
@@ -62,14 +62,14 @@ func (fs *FileSource) GetTemplates() string {
6262
return fs.Template
6363
}
6464

65-
func newFileSource(in *v1beta1.GoTemplate) (*FileSource, error) {
65+
func newFileSource(fsys fs.FS, in *v1beta1.GoTemplate) (*FileSource, error) {
6666
if in.FileSystem == nil || in.FileSystem.DirPath == "" {
6767
return nil, errors.New("fileSystem.dirPath should be provided")
6868
}
6969

7070
d := in.FileSystem.DirPath
7171

72-
tmpl, err := readTemplates(d)
72+
tmpl, err := readTemplates(fsys, d)
7373
if err != nil {
7474
return nil, errors.Errorf("cannot read tmpl from the folder %s: %s", *in.FileSystem, err)
7575
}
@@ -80,10 +80,10 @@ func newFileSource(in *v1beta1.GoTemplate) (*FileSource, error) {
8080
}, nil
8181
}
8282

83-
func readTemplates(dir string) (string, error) {
83+
func readTemplates(fsys fs.FS, dir string) (string, error) {
8484
tmpl := ""
8585

86-
if err := filepath.WalkDir(dir, func(path string, dirEntry os.DirEntry, e error) error {
86+
if err := fs.WalkDir(fsys, dir, func(path string, dirEntry fs.DirEntry, e error) error {
8787
if e != nil {
8888
return e
8989
}
@@ -103,7 +103,7 @@ func readTemplates(dir string) (string, error) {
103103
return nil
104104
}
105105

106-
data, err := os.ReadFile(path)
106+
data, err := fs.ReadFile(fsys, path)
107107
if err != nil {
108108
return err
109109
}

0 commit comments

Comments
 (0)