From bd0528ac3a5842ee704f4c487539efd2cc8bad09 Mon Sep 17 00:00:00 2001 From: Bird Date: Tue, 16 Aug 2022 13:06:09 +0800 Subject: [PATCH] refactor: replace `interface` with `function type` Signed-off-by: Bird --- pkg/util/file/{github.go => git.go} | 0 pkg/util/file/git_test.go | 94 +++++++++++++++++++++++++++++ pkg/util/file/render_test.go | 87 -------------------------- pkg/util/template/getter.go | 38 ++++-------- pkg/util/template/processor.go | 22 ++----- pkg/util/template/render.go | 16 ++--- pkg/util/template/renderer.go | 28 ++++----- 7 files changed, 126 insertions(+), 159 deletions(-) rename pkg/util/file/{github.go => git.go} (100%) create mode 100644 pkg/util/file/git_test.go diff --git a/pkg/util/file/github.go b/pkg/util/file/git.go similarity index 100% rename from pkg/util/file/github.go rename to pkg/util/file/git.go diff --git a/pkg/util/file/git_test.go b/pkg/util/file/git_test.go new file mode 100644 index 000000000..686268d4b --- /dev/null +++ b/pkg/util/file/git_test.go @@ -0,0 +1,94 @@ +package file + +import ( + "os" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("renderGitRepoDir func", func() { + var ( + vars map[string]interface{} + srcPath, contentDir, rawContent, tplContent, renderdContent string + ) + + createFile := func(filePath, content string) { + f, err := os.Create(filePath) + Expect(err).Error().ShouldNot(HaveOccurred()) + defer f.Close() + err = os.WriteFile(filePath, []byte(content), 0755) + Expect(err).Error().ShouldNot(HaveOccurred()) + } + createDir := func(dirPath string) { + err := os.Mkdir(dirPath, 0755) + Expect(err).Error().ShouldNot(HaveOccurred()) + } + BeforeEach(func() { + rawContent = "This is a file without template variable" + tplContent = ` + metadata: + name: "[[ .App.Name ]]" + namespace: "[[ .App.NameSpace ]]"` + renderdContent = ` + metadata: + name: "test" + namespace: "test_namespace"` + + }) + + When("srcPath is not exist", func() { + BeforeEach(func() { + srcPath = "not_exist_path" + }) + It("should return err", func() { + _, err := renderGitRepoDir("test", srcPath, vars) + Expect(err).Error().Should(HaveOccurred()) + }) + }) + When("all config is right", func() { + BeforeEach(func() { + contentDir = "content" + vars = map[string]interface{}{ + "App": map[string]interface{}{ + "Name": "test", + "NameSpace": "test_namespace", + }, + } + srcPath = GinkgoT().TempDir() + gitPath := filepath.Join(srcPath, ".git") + createDir(gitPath) + createFile(filepath.Join(gitPath, "gitFile"), tplContent) + createFile(filepath.Join(srcPath, "README.md"), "") + contentDirPath := filepath.Join(srcPath, contentDir) + createDir(contentDirPath) + createFile(filepath.Join(contentDirPath, "test.yaml.tpl"), tplContent) + createFile(filepath.Join(contentDirPath, "raw.txt"), rawContent) + }) + It("should render all dir", func() { + dstPath, err := renderGitRepoDir("test", srcPath, vars) + Expect(err).Error().ShouldNot(HaveOccurred()) + files, err := os.ReadDir(dstPath) + Expect(err).Error().ShouldNot(HaveOccurred()) + // test README.md dir is not copied + Expect(len(files)).Should(Equal(2)) + // test git dir files should not copied + gitDirFiles, err := os.ReadDir(filepath.Join(dstPath, ".git")) + Expect(err).Error().ShouldNot(HaveOccurred()) + Expect(len(gitDirFiles)).Should(Equal(0)) + // test content dir files is copied + contentDirLoc := filepath.Join(dstPath, contentDir) + contentFiles, err := os.ReadDir(contentDirLoc) + Expect(err).Error().ShouldNot(HaveOccurred()) + Expect(len(contentFiles)).Should(Equal(2)) + // test file content + tplFileContent, err := os.ReadFile(filepath.Join(contentDirLoc, "test.yaml")) + Expect(err).Error().ShouldNot(HaveOccurred()) + Expect(string(tplFileContent)).Should(Equal(renderdContent)) + rawFileContent, err := os.ReadFile(filepath.Join(contentDirLoc, "raw.txt")) + Expect(err).Error().ShouldNot(HaveOccurred()) + Expect(string(rawFileContent)).Should(Equal(rawContent)) + }) + }) +}) diff --git a/pkg/util/file/render_test.go b/pkg/util/file/render_test.go index 293744c54..e735505cb 100644 --- a/pkg/util/file/render_test.go +++ b/pkg/util/file/render_test.go @@ -2,8 +2,6 @@ package file import ( "fmt" - "os" - "path/filepath" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -40,88 +38,3 @@ var _ = Describe("replaceAppNameInPathStr func", func() { }) }) }) - -var _ = Describe("renderGitRepoDir func", func() { - var ( - vars map[string]interface{} - srcPath, contentDir, rawContent, tplContent, renderdContent string - ) - - createFile := func(filePath, content string) { - f, err := os.Create(filePath) - Expect(err).Error().ShouldNot(HaveOccurred()) - defer f.Close() - err = os.WriteFile(filePath, []byte(content), 0755) - Expect(err).Error().ShouldNot(HaveOccurred()) - } - createDir := func(dirPath string) { - err := os.Mkdir(dirPath, 0755) - Expect(err).Error().ShouldNot(HaveOccurred()) - } - BeforeEach(func() { - rawContent = "This is a file without template variable" - tplContent = ` - metadata: - name: "[[ .App.Name ]]" - namespace: "[[ .App.NameSpace ]]"` - renderdContent = ` - metadata: - name: "test" - namespace: "test_namespace"` - - }) - - When("srcPath is not exist", func() { - BeforeEach(func() { - srcPath = "not_exist_path" - }) - It("should return err", func() { - _, err := renderGitRepoDir("test", srcPath, vars) - Expect(err).Error().Should(HaveOccurred()) - }) - }) - When("all config is right", func() { - BeforeEach(func() { - contentDir = "content" - vars = map[string]interface{}{ - "App": map[string]interface{}{ - "Name": "test", - "NameSpace": "test_namespace", - }, - } - srcPath = GinkgoT().TempDir() - gitPath := filepath.Join(srcPath, ".git") - createDir(gitPath) - createFile(filepath.Join(gitPath, "gitFile"), tplContent) - createFile(filepath.Join(srcPath, "README.md"), "") - contentDirPath := filepath.Join(srcPath, contentDir) - createDir(contentDirPath) - createFile(filepath.Join(contentDirPath, "test.yaml.tpl"), tplContent) - createFile(filepath.Join(contentDirPath, "raw.txt"), rawContent) - }) - It("should render all dir", func() { - dstPath, err := renderGitRepoDir("test", srcPath, vars) - Expect(err).Error().ShouldNot(HaveOccurred()) - files, err := os.ReadDir(dstPath) - Expect(err).Error().ShouldNot(HaveOccurred()) - // test README.md dir is not copied - Expect(len(files)).Should(Equal(2)) - // test git dir files should not copied - gitDirFiles, err := os.ReadDir(filepath.Join(dstPath, ".git")) - Expect(err).Error().ShouldNot(HaveOccurred()) - Expect(len(gitDirFiles)).Should(Equal(0)) - // test content dir files is copied - contentDirLoc := filepath.Join(dstPath, contentDir) - contentFiles, err := os.ReadDir(contentDirLoc) - Expect(err).Error().ShouldNot(HaveOccurred()) - Expect(len(contentFiles)).Should(Equal(2)) - // test file content - tplFileContent, err := os.ReadFile(filepath.Join(contentDirLoc, "test.yaml")) - Expect(err).Error().ShouldNot(HaveOccurred()) - Expect(string(tplFileContent)).Should(Equal(renderdContent)) - rawFileContent, err := os.ReadFile(filepath.Join(contentDirLoc, "raw.txt")) - Expect(err).Error().ShouldNot(HaveOccurred()) - Expect(string(rawFileContent)).Should(Equal(rawContent)) - }) - }) -}) diff --git a/pkg/util/template/getter.go b/pkg/util/template/getter.go index 9ab9719d5..a6a0a0de0 100644 --- a/pkg/util/template/getter.go +++ b/pkg/util/template/getter.go @@ -12,15 +12,21 @@ import ( // Getters func FromLocalFile(filepath string) ContentGetter { - return &localGetter{filepath: filepath} + return func() ([]byte, error) { + return os.ReadFile(filepath) + } } func FromContent(content string) ContentGetter { - return &contentGetter{content: content} + return func() ([]byte, error) { + return []byte(content), nil + } } func FromURL(url string) ContentGetter { - return &urlGetter{url: url} + return func() ([]byte, error) { + return getContentFromURL(url) + } } // Quick Calls @@ -37,30 +43,8 @@ func (r *render) FromURL(url string) *rendererWithGetter { return r.SetContentGetter(FromURL(url)) } -// Getters definition - -type localGetter struct { - filepath string -} - -func (g *localGetter) GetContent() ([]byte, error) { - return os.ReadFile(g.filepath) -} - -type contentGetter struct { - content string -} - -func (g *contentGetter) GetContent() ([]byte, error) { - return []byte(g.content), nil -} - -type urlGetter struct { - url string -} - -func (g *urlGetter) GetContent() ([]byte, error) { - resp, err := http.Get(g.url) +func getContentFromURL(url string) ([]byte, error) { + resp, err := http.Get(url) defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { diff --git a/pkg/util/template/processor.go b/pkg/util/template/processor.go index 658876e9b..cb23d60ee 100644 --- a/pkg/util/template/processor.go +++ b/pkg/util/template/processor.go @@ -13,24 +13,14 @@ func AddDotForVariablesInConfig(s string) string { return r.ReplaceAllString(s, "[[ .") } -type dotProcessor struct{} - -func (p *dotProcessor) Process(bytes []byte) ([]byte, error) { - return []byte(AddDotForVariablesInConfig(string(bytes))), nil -} - func AddDotForVariablesInConfigProcessor() Processor { - return &dotProcessor{} + return func(bytes []byte) ([]byte, error) { + return []byte(AddDotForVariablesInConfig(string(bytes))), nil + } } -type processorFuncWrapper struct { - f func([]byte) ([]byte, error) -} - -func (p *processorFuncWrapper) Process(bytes []byte) ([]byte, error) { - return p.f(bytes) -} +// Quick Calls -func NewProcessorFuncWrapper(f func([]byte) ([]byte, error)) Processor { - return &processorFuncWrapper{f: f} +func (r *rendererWithGetter) AddDotForVariablesInConfigProcessor() *rendererWithGetter { + return r.AddProcessor(AddDotForVariablesInConfigProcessor()) } diff --git a/pkg/util/template/render.go b/pkg/util/template/render.go index e02205621..b3b5559a7 100644 --- a/pkg/util/template/render.go +++ b/pkg/util/template/render.go @@ -47,18 +47,10 @@ func RenderForFile(name, tplFileName, dstFileName string, variable any) error { return os.WriteFile(dstFileName, []byte(renderedStr), 0644) } -type defaultRender struct { - templateName string - vars any - funcMaps []template.FuncMap -} - -func (r *defaultRender) Render(src []byte) (string, error) { - return Render(r.templateName, string(src), r.vars, r.funcMaps...) -} - -func DefaultRender(templateName string, vars any, funcMaps ...template.FuncMap) RenderInf { - return &defaultRender{templateName: templateName, vars: vars, funcMaps: funcMaps} +func DefaultRender(templateName string, vars any, funcMaps ...template.FuncMap) RenderFunc { + return func(src []byte) (string, error) { + return Render(templateName, string(src), vars, funcMaps...) + } } // Quick Calls diff --git a/pkg/util/template/renderer.go b/pkg/util/template/renderer.go index 15e4f5cd2..7710e8d9f 100644 --- a/pkg/util/template/renderer.go +++ b/pkg/util/template/renderer.go @@ -2,19 +2,13 @@ package template type ( // ContentGetter gets content from any source - ContentGetter interface { - GetContent() ([]byte, error) - } + ContentGetter func() ([]byte, error) // Processor process content before render - Processor interface { - Process([]byte) ([]byte, error) - } + Processor func([]byte) ([]byte, error) - // RenderInf render content to string - RenderInf interface { - Render([]byte) (string, error) - } + // RenderFunc render content to string + RenderFunc func([]byte) (string, error) ) type ( @@ -38,7 +32,7 @@ type ( rendererWithRender struct { getter ContentGetter // mandatory processors []Processor // optional - render RenderInf // mandatory + render RenderFunc // mandatory } ) @@ -59,7 +53,7 @@ func (r *rendererWithGetter) AddProcessor(processor Processor) *rendererWithGett } } -func (r *rendererWithGetter) SetRender(render RenderInf) *rendererWithRender { +func (r *rendererWithGetter) SetRender(render RenderFunc) *rendererWithRender { return &rendererWithRender{ getter: r.getter, processors: r.processors, @@ -70,34 +64,34 @@ func (r *rendererWithGetter) SetRender(render RenderInf) *rendererWithRender { // Render gets the content, process the content, render and returns the result string func (c *rendererWithRender) Render() (string, error) { // 1. get content - content, err := c.getter.GetContent() + content, err := c.getter() if err != nil { return "", err } // 2. process content for _, processor := range c.processors { - content, err = processor.Process(content) + content, err = processor(content) if err != nil { return "", err } } // 3. render content - return c.render.Render(content) + return c.render(content) } // String returns the string directly, without rendering func (c *rendererWithGetter) String() (string, error) { // 1. get content - content, err := c.getter.GetContent() + content, err := c.getter() if err != nil { return "", err } // 2. process content for _, processor := range c.processors { - content, err = processor.Process(content) + content, err = processor(content) if err != nil { return "", err }