From e9aad417acf556180a85c4a9b6174e64e521307b Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Sun, 8 Oct 2023 14:21:59 +0800 Subject: [PATCH 01/17] feat: redesign recurse dump --- tool/trimmer/main.go | 32 ++++++++----------- .../test_cases/tests/dir/dir2/test.thrift | 2 ++ .../tests/dir/dir3/dir4/another.thrift | 16 ++++++++++ 3 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index b955fda0..75bd3575 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -117,16 +117,7 @@ func main() { println("output-dir should be set outside of -r base-dir to avoid overlay") os.Exit(2) } - createDirTree(a.Recurse, a.OutputFile) recurseDump(ast, a.Recurse, a.OutputFile) - relativePath, err := filepath.Rel(a.Recurse, a.IDL) - if err != nil { - println("-r input err, range should cover all the target IDLs;", err.Error()) - os.Exit(2) - } - outputFileUrl := filepath.Join(a.OutputFile, relativePath) - check(writeStringToFile(outputFileUrl, idl)) - removeEmptyDir(a.OutputFile) } else { check(writeStringToFile(a.OutputFile, idl)) } @@ -139,16 +130,21 @@ func recurseDump(ast *parser.Thrift, sourceDir, outDir string) { if ast == nil { return } + out, err := dump.DumpIDL(ast) + check(err) + relativeUrl, err := filepath.Rel(sourceDir, ast.Filename) + if err != nil { + println("-r input err, range should cover all the target IDLs;", err.Error()) + os.Exit(2) + } + outputFileUrl := filepath.Join(outDir, relativeUrl) + err = os.MkdirAll(filepath.Dir(outputFileUrl), os.ModePerm) + if err != nil { + println("mkdir", filepath.Dir(outputFileUrl), "error:", err.Error()) + os.Exit(2) + } + check(writeStringToFile(outputFileUrl, out)) for _, includes := range ast.Includes { - out, err := dump.DumpIDL(includes.Reference) - check(err) - relativeUrl, err := filepath.Rel(sourceDir, includes.Reference.Filename) - if err != nil { - println("-r input err, range should cover all the target IDLs;", err.Error()) - os.Exit(2) - } - outputFileUrl := filepath.Join(outDir, relativeUrl) - check(writeStringToFile(outputFileUrl, out)) recurseDump(includes.Reference, sourceDir, outDir) } } diff --git a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift index a7359c51..c5017d7c 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift +++ b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift @@ -13,8 +13,10 @@ // limitations under the License. include "../../../sample1.thrift" +include "../dir3/dir4/another.thrift" // @preserve struct TestStruct{ 1: sample1.Person person + 2: another.AnotherStruct another } \ No newline at end of file diff --git a/tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift b/tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift new file mode 100644 index 00000000..20aff287 --- /dev/null +++ b/tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift @@ -0,0 +1,16 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +struct AnotherStruct{ +} \ No newline at end of file From 9cf7b788bb265e93efb851e6bb8d55c5829475f5 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 9 Oct 2023 20:49:10 +0800 Subject: [PATCH 02/17] feat: add yaml-config support for trimmer --- generator/golang/backend.go | 3 +- tool/trimmer/args.go | 4 +- tool/trimmer/dirTree.go | 81 ------------------- tool/trimmer/dirTree_test.go | 58 ------------- tool/trimmer/main.go | 11 +++ .../test_cases/tests/dir/dir2/test.thrift | 6 ++ .../tests/dir/dir2/trim_config.yaml | 17 ++++ tool/trimmer/trim/config.go | 48 +++++++++++ 8 files changed, 86 insertions(+), 142 deletions(-) delete mode 100644 tool/trimmer/dirTree.go delete mode 100644 tool/trimmer/dirTree_test.go create mode 100644 tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml create mode 100644 tool/trimmer/trim/config.go diff --git a/generator/golang/backend.go b/generator/golang/backend.go index d96e843d..15b6cbbd 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -86,7 +86,8 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.log = log g.prepareUtilities() if g.utils.Features().TrimIDL { - err := trim.TrimAST(req.AST, nil, false) + cfg := trim.ParseYamlConfig(filepath.Dir(req.AST.Filename)) + err := trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) if err != nil { g.log.Warn("trim error:", err.Error()) } diff --git a/tool/trimmer/args.go b/tool/trimmer/args.go index eee0f637..ca3cea05 100644 --- a/tool/trimmer/args.go +++ b/tool/trimmer/args.go @@ -63,8 +63,8 @@ func (a *Arguments) BuildFlags() *flag.FlagSet { f.Var(&a.Methods, "m", "") f.Var(&a.Methods, "method", "") - f.StringVar(&a.Preserve, "p", "true", "") - f.StringVar(&a.Preserve, "preserve", "true", "") + f.StringVar(&a.Preserve, "p", "", "") + f.StringVar(&a.Preserve, "preserve", "", "") f.Usage = help return f diff --git a/tool/trimmer/dirTree.go b/tool/trimmer/dirTree.go deleted file mode 100644 index c7c39683..00000000 --- a/tool/trimmer/dirTree.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2023 CloudWeGo Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "errors" - "fmt" - "os" - "path/filepath" -) - -// create directory-tree before dump -func createDirTree(sourceDir, destinationDir string) { - err := filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - if path[len(sourceDir)-1] != filepath.Separator { - path = path + string(filepath.Separator) - } - newDir := filepath.Join(destinationDir, path[len(sourceDir):]) - err := os.MkdirAll(newDir, os.ModePerm) - if err != nil { - return errors.New("create dir tree error:" + err.Error()) - } - } - return nil - }) - if err != nil { - fmt.Printf("manage output error: %v\n", err) - os.Exit(2) - } -} - -// remove empty directory of output dir-tree -func removeEmptyDir(source string) { - files, err := os.ReadDir(source) - if err != nil { - return - } - for _, file := range files { - if file.IsDir() { - removeEmptyDir(source + string(filepath.Separator) + file.Name()) - } - } - empty, err := isDirectoryEmpty(source) - if empty || err != nil { - _ = os.RemoveAll(source) - } -} - -func isDirectoryEmpty(path string) (bool, error) { - dir, err := os.Open(path) - if err != nil { - return false, err - } - defer dir.Close() - - _, err = dir.Readdirnames(1) - if err == nil { - return false, nil - } - - if errors.Is(err, os.ErrNotExist) { - return true, nil - } - return false, err -} diff --git a/tool/trimmer/dirTree_test.go b/tool/trimmer/dirTree_test.go deleted file mode 100644 index d856a7a4..00000000 --- a/tool/trimmer/dirTree_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2023 CloudWeGo Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "os" - "path/filepath" - "testing" - - "github.com/cloudwego/thriftgo/pkg/test" -) - -func TestDirTree(t *testing.T) { - _ = os.RemoveAll("trimmer_test") - createDirTree("test_cases", "trimmer_test") - fileCount, dirCount, err := countFilesAndSubdirectories("trimmer_test") - test.Assert(t, err == nil) - test.Assert(t, fileCount == 0) - test.Assert(t, dirCount == 3) - removeEmptyDir("trimmer_test") - _, err = os.ReadDir("trimmer_test") - test.Assert(t, err != nil) -} - -func countFilesAndSubdirectories(dirPath string) (int, int, error) { - var fileCount, dirCount int - files, err := os.ReadDir(dirPath) - if err != nil { - return 0, 0, err - } - for _, file := range files { - if file.IsDir() { - dirCount++ - subDirPath := filepath.Join(dirPath, file.Name()) - subFileCount, subDirCount, err := countFilesAndSubdirectories(subDirPath) - if err != nil { - return 0, 0, err - } - fileCount += subFileCount - dirCount += subDirCount - } else { - fileCount++ - } - } - return fileCount, dirCount, nil -} diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index 75bd3575..85f69f66 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -73,6 +73,17 @@ func main() { check(err) check(semantic.ResolveSymbols(ast)) + // try parse yaml config + cfg := trim.ParseYamlConfig(filepath.Dir(a.IDL)) + if cfg != nil { + if len(a.Methods) == 0 && len(cfg.Methods) > 0 { + a.Methods = cfg.Methods + } + if a.Preserve == "" && !(*cfg.Preserve) { + preserve = false + } + } + // trim ast check(trim.TrimAST(ast, a.Methods, !preserve)) diff --git a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift index c5017d7c..56ff1303 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift +++ b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift @@ -19,4 +19,10 @@ include "../dir3/dir4/another.thrift" struct TestStruct{ 1: sample1.Person person 2: another.AnotherStruct another +} + +service TestService{ + void func1() + another.AnotherStruct func2() + void func3() } \ No newline at end of file diff --git a/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml new file mode 100644 index 00000000..1b0dcbe1 --- /dev/null +++ b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml @@ -0,0 +1,17 @@ +# Copyright 2023 CloudWeGo Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +methods: + - "TestService.func1" + - "TestService.func3" +preserve: false \ No newline at end of file diff --git a/tool/trimmer/trim/config.go b/tool/trimmer/trim/config.go new file mode 100644 index 00000000..af1085f4 --- /dev/null +++ b/tool/trimmer/trim/config.go @@ -0,0 +1,48 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trim + +import ( + "fmt" + "gopkg.in/yaml.v3" + "os" + "path/filepath" +) + +var DefaultYamlFileName = "trim_config.yaml" + +type YamlArguments struct { + Methods []string `yaml:"methods,omitempty"` + Preserve *bool `yaml:"preserve,omitempty"` +} + +func ParseYamlConfig(path string) *YamlArguments { + cfg := YamlArguments{} + dataBytes, err := os.ReadFile(filepath.Join(path, DefaultYamlFileName)) + if err != nil { + return nil + } + fmt.Println("using trim config:", filepath.Join(path, DefaultYamlFileName)) + err = yaml.Unmarshal(dataBytes, &cfg) + if err != nil { + fmt.Println("unmarshal yaml config fail:", err) + return nil + } + if cfg.Preserve == nil { + t := true + cfg.Preserve = &t + } + return &cfg +} From 44da22e7500c76e3f40eed2a865e4019304d11ce Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 9 Oct 2023 20:49:10 +0800 Subject: [PATCH 03/17] feat: add yaml-config support for trimmer --- tool/trimmer/trim/config.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tool/trimmer/trim/config.go b/tool/trimmer/trim/config.go index af1085f4..61a34606 100644 --- a/tool/trimmer/trim/config.go +++ b/tool/trimmer/trim/config.go @@ -16,9 +16,10 @@ package trim import ( "fmt" - "gopkg.in/yaml.v3" "os" "path/filepath" + + "gopkg.in/yaml.v3" ) var DefaultYamlFileName = "trim_config.yaml" From 7a29ca0ebdd360fd5142960fefe533dcd1c004db Mon Sep 17 00:00:00 2001 From: tk_sky <63036400+tksky1@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:33:02 +0800 Subject: [PATCH 04/17] fix: fix typedef with reference get-type-fail issue for trimmer tool (#133) --- tool/trimmer/test_cases/sample1.thrift | 4 +- tool/trimmer/test_cases/sample1b.thrift | 4 ++ tool/trimmer/trim/mark.go | 68 ++++++++++++++----------- tool/trimmer/trim/trimmer_test.go | 2 +- 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/tool/trimmer/test_cases/sample1.thrift b/tool/trimmer/test_cases/sample1.thrift index a80ee282..20ab422f 100644 --- a/tool/trimmer/test_cases/sample1.thrift +++ b/tool/trimmer/test_cases/sample1.thrift @@ -44,6 +44,8 @@ test7 typedef Gender(key="v") MyGender (key = "1", key = "2", key2 = "v2") typedef MyGender MyAnotherGender +typedef sample1b.AnotherException samlpe1bAnotherException +typedef sample1b.NotDirectInclude notDirectInclude typedef i32 a // out enum"ZZ" @@ -113,7 +115,7 @@ service ProjectService { service CompanyService { Company getCompany(1: string id) - void addCompany(1: Company company) throws(1: sample1b.AnotherException exc) + void addCompany(1: Company company) throws(1: samlpe1bAnotherException exc) void updateCompany(1: string id, 2: Company company) list getDepartments(1: string company_id) void anotherUselessMethod(1: MaybeUseless useless) diff --git a/tool/trimmer/test_cases/sample1b.thrift b/tool/trimmer/test_cases/sample1b.thrift index c032ff18..4678cffa 100644 --- a/tool/trimmer/test_cases/sample1b.thrift +++ b/tool/trimmer/test_cases/sample1b.thrift @@ -47,5 +47,9 @@ exception AnotherException{ 1: i32 abc } +exception NotDirectInclude{ + +} + const i32 DEFAULT_CODE = 3000; const string trash_string = "trash!" diff --git a/tool/trimmer/trim/mark.go b/tool/trimmer/trim/mark.go index 5c7bc48e..a660850f 100644 --- a/tool/trimmer/trim/mark.go +++ b/tool/trimmer/trim/mark.go @@ -27,33 +27,7 @@ func (t *Trimmer) markAST(ast *parser.Thrift) { t.markService(service, ast, ast.Filename) } - for _, constant := range ast.Constants { - t.markType(constant.Type, ast, ast.Filename) - } - - for _, typedef := range ast.Typedefs { - t.markTypeDef(typedef.Type, ast, ast.Filename) - } - - if !t.forceTrimming { - for _, str := range ast.Structs { - if !t.marks[ast.Filename][str] && t.checkPreserve(str) { - t.markStructLike(str, ast, ast.Filename) - } - } - - for _, str := range ast.Unions { - if !t.marks[ast.Filename][str] && t.checkPreserve(str) { - t.markStructLike(str, ast, ast.Filename) - } - } - - for _, str := range ast.Exceptions { - if !t.marks[ast.Filename][str] && t.checkPreserve(str) { - t.markStructLike(str, ast, ast.Filename) - } - } - } + t.markKeptParts(ast, ast.Filename) } func (t *Trimmer) markService(svc *parser.Service, ast *parser.Thrift, filename string) { @@ -89,6 +63,7 @@ func (t *Trimmer) markService(svc *parser.Service, ast *parser.Thrift, filename if svc.Reference != nil { theInclude := ast.Includes[svc.Reference.Index] t.marks[filename][theInclude] = true + t.markKeptParts(theInclude.Reference, filename) for _, service := range theInclude.Reference.Services { if service.Name == svc.Reference.Name { t.markService(service, theInclude.Reference, filename) @@ -129,6 +104,7 @@ func (t *Trimmer) markType(theType *parser.Type, ast *parser.Thrift, filename st // if referenced, redirect to included ast baseAST = ast.Includes[theType.Reference.Index].Reference t.marks[filename][ast.Includes[theType.Reference.Index]] = true + t.markKeptParts(ast.Includes[theType.Reference.Index].Reference, filename) } if theType.IsTypedef != nil { @@ -186,10 +162,10 @@ func (t *Trimmer) markTypeDef(theType *parser.Type, ast *parser.Thrift, filename return } - for _, typedef := range ast.Typedefs { + for i, typedef := range ast.Typedefs { if typedef.Alias == theType.Name { - if !t.marks[filename][typedef] { - t.marks[filename][typedef] = true + if !t.marks[filename][ast.Typedefs[i]] { + t.marks[filename][ast.Typedefs[i]] = true t.markType(typedef.Type, ast, filename) } return @@ -197,6 +173,37 @@ func (t *Trimmer) markTypeDef(theType *parser.Type, ast *parser.Thrift, filename } } +func (t *Trimmer) markKeptParts(ast *parser.Thrift, filename string) { + for _, constant := range ast.Constants { + t.markType(constant.Type, ast, filename) + } + + for _, typedef := range ast.Typedefs { + t.marks[filename][typedef] = true + t.markType(typedef.Type, ast, filename) + } + + if !t.forceTrimming { + for _, str := range ast.Structs { + if !t.marks[filename][str] && t.checkPreserve(str) { + t.markStructLike(str, ast, filename) + } + } + + for _, str := range ast.Unions { + if !t.marks[filename][str] && t.checkPreserve(str) { + t.markStructLike(str, ast, filename) + } + } + + for _, str := range ast.Exceptions { + if !t.marks[filename][str] && t.checkPreserve(str) { + t.markStructLike(str, ast, filename) + } + } + } +} + // for -m, trace the extends and find specified method to base on func (t *Trimmer) traceExtendMethod(father, svc *parser.Service, ast *parser.Thrift, filename string) (ret bool) { for _, function := range svc.Functions { @@ -237,6 +244,7 @@ func (t *Trimmer) traceExtendMethod(father, svc *parser.Service, ast *parser.Thr t.marks[filename][svc] = true if svc.Reference != nil { t.marks[filename][ast.Includes[svc.Reference.Index]] = true + t.markKeptParts(ast.Includes[svc.Reference.Index].Reference, filename) } } return ret diff --git a/tool/trimmer/trim/trimmer_test.go b/tool/trimmer/trim/trimmer_test.go index d7f6187f..53e7b2fb 100644 --- a/tool/trimmer/trim/trimmer_test.go +++ b/tool/trimmer/trim/trimmer_test.go @@ -49,7 +49,7 @@ func testSingleFile(t *testing.T) { test.Assert(t, len(ast.Structs) == 6) test.Assert(t, len(ast.Includes) == 1) - test.Assert(t, len(ast.Typedefs) == 3) + test.Assert(t, len(ast.Typedefs) == 5) test.Assert(t, len(ast.Namespaces) == 1) test.Assert(t, len(ast.Includes[0].Reference.Structs) == 2) test.Assert(t, len(ast.Includes[0].Reference.Constants) == 2) From 2d48987d3f8557e40cd3a4ef939c0d114e47f9ac Mon Sep 17 00:00:00 2001 From: tk_sky <63036400+tksky1@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:33:42 +0800 Subject: [PATCH 05/17] fix: hot-fix #133 trimmer typedef reference (#134) --- tool/trimmer/trim/mark.go | 24 +++++++++++++++--------- tool/trimmer/trim/pre-process.go | 24 ++++++++++++++++++++++++ tool/trimmer/trim/traversal.go | 1 + 3 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 tool/trimmer/trim/pre-process.go diff --git a/tool/trimmer/trim/mark.go b/tool/trimmer/trim/mark.go index a660850f..55adbb1a 100644 --- a/tool/trimmer/trim/mark.go +++ b/tool/trimmer/trim/mark.go @@ -23,11 +23,12 @@ import ( // mark the used part of ast func (t *Trimmer) markAST(ast *parser.Thrift) { t.marks[ast.Filename] = make(map[interface{}]bool) + t.preProcess(ast, ast.Filename) for _, service := range ast.Services { t.markService(service, ast, ast.Filename) } - t.markKeptParts(ast, ast.Filename) + t.markKeptPart(ast, ast.Filename) } func (t *Trimmer) markService(svc *parser.Service, ast *parser.Thrift, filename string) { @@ -62,8 +63,7 @@ func (t *Trimmer) markService(svc *parser.Service, ast *parser.Thrift, filename // handle extension if svc.Reference != nil { theInclude := ast.Includes[svc.Reference.Index] - t.marks[filename][theInclude] = true - t.markKeptParts(theInclude.Reference, filename) + t.markInclude(ast.Includes[svc.Reference.Index], filename) for _, service := range theInclude.Reference.Services { if service.Name == svc.Reference.Name { t.markService(service, theInclude.Reference, filename) @@ -103,8 +103,7 @@ func (t *Trimmer) markType(theType *parser.Type, ast *parser.Thrift, filename st if theType.Reference != nil { // if referenced, redirect to included ast baseAST = ast.Includes[theType.Reference.Index].Reference - t.marks[filename][ast.Includes[theType.Reference.Index]] = true - t.markKeptParts(ast.Includes[theType.Reference.Index].Reference, filename) + t.markInclude(ast.Includes[theType.Reference.Index], filename) } if theType.IsTypedef != nil { @@ -173,13 +172,21 @@ func (t *Trimmer) markTypeDef(theType *parser.Type, ast *parser.Thrift, filename } } -func (t *Trimmer) markKeptParts(ast *parser.Thrift, filename string) { +func (t *Trimmer) markInclude(include *parser.Include, filename string) { + include.Reference.Name2Category = nil + if t.marks[filename][include] { + return + } + t.marks[filename][include] = true + // t.markKeptPart(include.Reference, filename) +} + +func (t *Trimmer) markKeptPart(ast *parser.Thrift, filename string) { for _, constant := range ast.Constants { t.markType(constant.Type, ast, filename) } for _, typedef := range ast.Typedefs { - t.marks[filename][typedef] = true t.markType(typedef.Type, ast, filename) } @@ -243,8 +250,7 @@ func (t *Trimmer) traceExtendMethod(father, svc *parser.Service, ast *parser.Thr if ret { t.marks[filename][svc] = true if svc.Reference != nil { - t.marks[filename][ast.Includes[svc.Reference.Index]] = true - t.markKeptParts(ast.Includes[svc.Reference.Index].Reference, filename) + t.markInclude(ast.Includes[svc.Reference.Index], filename) } } return ret diff --git a/tool/trimmer/trim/pre-process.go b/tool/trimmer/trim/pre-process.go new file mode 100644 index 00000000..0a9ceab1 --- /dev/null +++ b/tool/trimmer/trim/pre-process.go @@ -0,0 +1,24 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trim + +import "github.com/cloudwego/thriftgo/parser" + +func (t *Trimmer) preProcess(ast *parser.Thrift, filename string) { + t.markKeptPart(ast, filename) + for _, include := range ast.Includes { + t.preProcess(include.Reference, filename) + } +} diff --git a/tool/trimmer/trim/traversal.go b/tool/trimmer/trim/traversal.go index e945e8f7..dcd0518b 100644 --- a/tool/trimmer/trim/traversal.go +++ b/tool/trimmer/trim/traversal.go @@ -70,4 +70,5 @@ func (t *Trimmer) traversal(ast *parser.Thrift, filename string) { } } ast.Services = listService + ast.Name2Category = nil } From 70f029687e13e2b3312716b9d47613979ddc8ef3 Mon Sep 17 00:00:00 2001 From: Li2CO3 Date: Wed, 18 Oct 2023 20:04:58 +0800 Subject: [PATCH 06/17] fix: fix include semantic check for trimmer (#135) --- .../test_cases/test_include/example.thrift | 24 +++++++++++++++ .../test_cases/test_include/test.thrift | 26 +++++++++++++++++ tool/trimmer/trim/traversal.go | 3 ++ tool/trimmer/trim/trimmer.go | 1 - tool/trimmer/trim/trimmer_test.go | 29 +++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tool/trimmer/test_cases/test_include/example.thrift create mode 100644 tool/trimmer/test_cases/test_include/test.thrift diff --git a/tool/trimmer/test_cases/test_include/example.thrift b/tool/trimmer/test_cases/test_include/example.thrift new file mode 100644 index 00000000..e10d837f --- /dev/null +++ b/tool/trimmer/test_cases/test_include/example.thrift @@ -0,0 +1,24 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +namespace go a + +include "test.thrift" + +struct E{ + 1: required test.TestStruct a +} + + diff --git a/tool/trimmer/test_cases/test_include/test.thrift b/tool/trimmer/test_cases/test_include/test.thrift new file mode 100644 index 00000000..6013bbe0 --- /dev/null +++ b/tool/trimmer/test_cases/test_include/test.thrift @@ -0,0 +1,26 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace go c + +struct TestStruct{ + // hello + 1:required string hello + 2:required string id +} + +enum GenderEnum{ + MALE + FEMALE +} diff --git a/tool/trimmer/trim/traversal.go b/tool/trimmer/trim/traversal.go index dcd0518b..ddba0cf8 100644 --- a/tool/trimmer/trim/traversal.go +++ b/tool/trimmer/trim/traversal.go @@ -71,4 +71,7 @@ func (t *Trimmer) traversal(ast *parser.Thrift, filename string) { } ast.Services = listService ast.Name2Category = nil + for _, inc := range ast.Includes { + inc.Used = nil + } } diff --git a/tool/trimmer/trim/trimmer.go b/tool/trimmer/trim/trimmer.go index bd4ee050..54087466 100644 --- a/tool/trimmer/trim/trimmer.go +++ b/tool/trimmer/trim/trimmer.go @@ -61,7 +61,6 @@ func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool) error } trimmer.markAST(ast) trimmer.traversal(ast, ast.Filename) - ast.Name2Category = nil if path := parser.CircleDetect(ast); len(path) > 0 { check(fmt.Errorf("found include circle:\n\t%s", path)) } diff --git a/tool/trimmer/trim/trimmer_test.go b/tool/trimmer/trim/trimmer_test.go index 53e7b2fb..e6a17ea6 100644 --- a/tool/trimmer/trim/trimmer_test.go +++ b/tool/trimmer/trim/trimmer_test.go @@ -56,3 +56,32 @@ func testSingleFile(t *testing.T) { test.Assert(t, len(ast.Includes[0].Reference.Services) == 1) test.Assert(t, len(ast.Includes[0].Reference.Namespaces) == 1) } + +func TestInclude(t *testing.T) { + trimmer, err := newTrimmer(nil, "") + test.Assert(t, err == nil, err) + filename := filepath.Join("..", "test_cases/test_include", "example.thrift") + ast, err := parser.ParseFile(filename, []string{"test_cases/test_include"}, true) + check(err) + if path := parser.CircleDetect(ast); len(path) > 0 { + check(fmt.Errorf("found include circle:\n\t%s", path)) + } + checker := semantic.NewChecker(semantic.Options{FixWarnings: true}) + _, err = checker.CheckAll(ast) + check(err) + check(semantic.ResolveSymbols(ast)) + trimmer.asts[filename] = ast + trimmer.markAST(ast) + trimmer.traversal(ast, ast.Filename) + if path := parser.CircleDetect(ast); len(path) > 0 { + check(fmt.Errorf("found include circle:\n\t%s", path)) + } + checker = semantic.NewChecker(semantic.Options{FixWarnings: true}) + _, err = checker.CheckAll(ast) + check(err) + check(semantic.ResolveSymbols(ast)) + + test.Assert(t, len(ast.Structs) == 0) + test.Assert(t, len(ast.Includes) == 1) + test.Assert(t, ast.Includes[0].Used == nil) +} From 9261d468ce8c0b63d8c09057630c9aebdae1afee Mon Sep 17 00:00:00 2001 From: tk_sky <63036400+tksky1@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:21:06 +0800 Subject: [PATCH 07/17] chore: expand @preserve regexp for trimmer (#136) --- tool/trimmer/test_cases/sample1.thrift | 7 +++++++ tool/trimmer/trim/trimmer.go | 2 +- tool/trimmer/trim/trimmer_test.go | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tool/trimmer/test_cases/sample1.thrift b/tool/trimmer/test_cases/sample1.thrift index 20ab422f..8c790839 100644 --- a/tool/trimmer/test_cases/sample1.thrift +++ b/tool/trimmer/test_cases/sample1.thrift @@ -100,6 +100,13 @@ struct Simple { // should not appear struct MaybeUseless{ } +// some comments +# @preServe +// some others +struct preserved{ + +} + service EmployeeService extends sample1b.GetPerson { Employee getEmployee(1: string id) void addEmployee(1: Employee employee) diff --git a/tool/trimmer/trim/trimmer.go b/tool/trimmer/trim/trimmer.go index 54087466..39a143f2 100644 --- a/tool/trimmer/trim/trimmer.go +++ b/tool/trimmer/trim/trimmer.go @@ -113,7 +113,7 @@ func newTrimmer(files []string, outDir string) (*Trimmer, error) { } trimmer.asts = make(map[string]*parser.Thrift) trimmer.marks = make(map[string]map[interface{}]bool) - pattern := `^[\s]*(\/\/|#)[\s]*@preserve[\s]*$` + pattern := `(?m)^[\s]*(\/\/|#)[\s]*@preserve[\s]*$` trimmer.preserveRegex = regexp.MustCompile(pattern) return trimmer, nil } diff --git a/tool/trimmer/trim/trimmer_test.go b/tool/trimmer/trim/trimmer_test.go index e6a17ea6..5687a2d1 100644 --- a/tool/trimmer/trim/trimmer_test.go +++ b/tool/trimmer/trim/trimmer_test.go @@ -47,7 +47,7 @@ func testSingleFile(t *testing.T) { trimmer.markAST(ast) trimmer.traversal(ast, ast.Filename) - test.Assert(t, len(ast.Structs) == 6) + test.Assert(t, len(ast.Structs) == 7) test.Assert(t, len(ast.Includes) == 1) test.Assert(t, len(ast.Typedefs) == 5) test.Assert(t, len(ast.Namespaces) == 1) From fa9e16aa194c3b1328a03bcf63d3667075b85b42 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 9 Oct 2023 20:49:10 +0800 Subject: [PATCH 08/17] feat: add yaml-config support for trimmer --- generator/golang/backend.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index 15b6cbbd..5499ab01 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -87,7 +87,13 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.prepareUtilities() if g.utils.Features().TrimIDL { cfg := trim.ParseYamlConfig(filepath.Dir(req.AST.Filename)) - err := trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) + var err error + if cfg == nil { + err = trim.TrimAST(req.AST, nil, false) + } else { + err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) + } + if err != nil { g.log.Warn("trim error:", err.Error()) } From 00196dcfece14003b43c46673a505b96f57614a8 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Fri, 20 Oct 2023 13:06:54 +0800 Subject: [PATCH 09/17] chore: set trimmer yaml path to WD --- generator/golang/backend.go | 4 +++- tool/trimmer/main.go | 16 +++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index 5499ab01..460ef9e9 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -17,6 +17,7 @@ package golang import ( "fmt" "go/format" + "os" "path/filepath" "strings" "text/template" @@ -86,7 +87,8 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.log = log g.prepareUtilities() if g.utils.Features().TrimIDL { - cfg := trim.ParseYamlConfig(filepath.Dir(req.AST.Filename)) + wd, _ := os.Getwd() + cfg := trim.ParseYamlConfig(wd) var err error if cfg == nil { err = trim.TrimAST(req.AST, nil, false) diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index 85f69f66..38100d7b 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -74,13 +74,15 @@ func main() { check(semantic.ResolveSymbols(ast)) // try parse yaml config - cfg := trim.ParseYamlConfig(filepath.Dir(a.IDL)) - if cfg != nil { - if len(a.Methods) == 0 && len(cfg.Methods) > 0 { - a.Methods = cfg.Methods - } - if a.Preserve == "" && !(*cfg.Preserve) { - preserve = false + if wd, err := os.Getwd(); err == nil { + cfg := trim.ParseYamlConfig(wd) + if cfg != nil { + if len(a.Methods) == 0 && len(cfg.Methods) > 0 { + a.Methods = cfg.Methods + } + if a.Preserve == "" && !(*cfg.Preserve) { + preserve = false + } } } From f9048eefea4eefbb279c4d23cab6c3a0f107c743 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 23 Oct 2023 20:21:31 +0800 Subject: [PATCH 10/17] feat: support preserve-structs for yaml-config of trimmer tool --- generator/golang/backend.go | 4 ++-- tool/trimmer/main.go | 4 +++- tool/trimmer/test_cases/tests/dir/dir2/test.thrift | 3 +++ .../test_cases/tests/dir/dir2/trim_config.yaml | 4 +++- tool/trimmer/trim/config.go | 5 +++-- tool/trimmer/trim/mark.go | 5 +++++ tool/trimmer/trim/traversal.go | 4 ++-- tool/trimmer/trim/trimmer.go | 12 +++++++----- 8 files changed, 28 insertions(+), 13 deletions(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index 460ef9e9..f6e3a328 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -91,9 +91,9 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R cfg := trim.ParseYamlConfig(wd) var err error if cfg == nil { - err = trim.TrimAST(req.AST, nil, false) + err = trim.TrimAST(req.AST, nil, false, nil) } else { - err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) + err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve, cfg.PreservedStructs) } if err != nil { diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index 38100d7b..b79ef37a 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -74,6 +74,7 @@ func main() { check(semantic.ResolveSymbols(ast)) // try parse yaml config + var preservedStructs []string if wd, err := os.Getwd(); err == nil { cfg := trim.ParseYamlConfig(wd) if cfg != nil { @@ -83,11 +84,12 @@ func main() { if a.Preserve == "" && !(*cfg.Preserve) { preserve = false } + preservedStructs = cfg.PreservedStructs } } // trim ast - check(trim.TrimAST(ast, a.Methods, !preserve)) + check(trim.TrimAST(ast, a.Methods, !preserve, preservedStructs)) // dump the trimmed ast to idl idl, err := dump.DumpIDL(ast) diff --git a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift index 56ff1303..804cb5d8 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift +++ b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift @@ -25,4 +25,7 @@ service TestService{ void func1() another.AnotherStruct func2() void func3() +} + +union useless{ } \ No newline at end of file diff --git a/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml index 1b0dcbe1..f65338b1 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml +++ b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml @@ -14,4 +14,6 @@ methods: - "TestService.func1" - "TestService.func3" -preserve: false \ No newline at end of file +preserve: true +preserved_structs: + - "useless" \ No newline at end of file diff --git a/tool/trimmer/trim/config.go b/tool/trimmer/trim/config.go index 61a34606..28786bab 100644 --- a/tool/trimmer/trim/config.go +++ b/tool/trimmer/trim/config.go @@ -25,8 +25,9 @@ import ( var DefaultYamlFileName = "trim_config.yaml" type YamlArguments struct { - Methods []string `yaml:"methods,omitempty"` - Preserve *bool `yaml:"preserve,omitempty"` + Methods []string `yaml:"methods,omitempty"` + Preserve *bool `yaml:"preserve,omitempty"` + PreservedStructs []string `yaml:"preserved_structs,omitempty"` } func ParseYamlConfig(path string) *YamlArguments { diff --git a/tool/trimmer/trim/mark.go b/tool/trimmer/trim/mark.go index 55adbb1a..8bd5e903 100644 --- a/tool/trimmer/trim/mark.go +++ b/tool/trimmer/trim/mark.go @@ -261,5 +261,10 @@ func (t *Trimmer) checkPreserve(theStruct *parser.StructLike) bool { if t.forceTrimming { return false } + for _, name := range t.preservedStructs { + if name == theStruct.Name { + return true + } + } return t.preserveRegex.MatchString(strings.ToLower(theStruct.ReservedComments)) } diff --git a/tool/trimmer/trim/traversal.go b/tool/trimmer/trim/traversal.go index ddba0cf8..bc4441e0 100644 --- a/tool/trimmer/trim/traversal.go +++ b/tool/trimmer/trim/traversal.go @@ -40,7 +40,7 @@ func (t *Trimmer) traversal(ast *parser.Thrift, filename string) { var listUnion []*parser.StructLike for i := range ast.Unions { - if t.marks[filename][ast.Unions[i]] { + if t.marks[filename][ast.Unions[i]] || t.checkPreserve(ast.Unions[i]) { listUnion = append(listUnion, ast.Unions[i]) } } @@ -48,7 +48,7 @@ func (t *Trimmer) traversal(ast *parser.Thrift, filename string) { var listException []*parser.StructLike for i := range ast.Exceptions { - if t.marks[filename][ast.Exceptions[i]] { + if t.marks[filename][ast.Exceptions[i]] || t.checkPreserve(ast.Exceptions[i]) { listException = append(listException, ast.Exceptions[i]) } } diff --git a/tool/trimmer/trim/trimmer.go b/tool/trimmer/trim/trimmer.go index 39a143f2..1bee9d7c 100644 --- a/tool/trimmer/trim/trimmer.go +++ b/tool/trimmer/trim/trimmer.go @@ -32,14 +32,15 @@ type Trimmer struct { marks map[string]map[interface{}]bool outDir string // use -m - trimMethods []string - trimMethodValid []bool - preserveRegex *regexp.Regexp - forceTrimming bool + trimMethods []string + trimMethodValid []bool + preserveRegex *regexp.Regexp + forceTrimming bool + preservedStructs []string } // TrimAST trim the single AST, pass method names if -m specified -func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool) error { +func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool, preservedStructs []string) error { trimmer, err := newTrimmer(nil, "") if err != nil { return err @@ -59,6 +60,7 @@ func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool) error } } } + trimmer.preservedStructs = preservedStructs trimmer.markAST(ast) trimmer.traversal(ast, ast.Filename) if path := parser.CircleDetect(ast); len(path) > 0 { From eaadce55875e9dc4355ca5266d44548f21bae3e0 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Sun, 8 Oct 2023 14:21:59 +0800 Subject: [PATCH 11/17] feat: redesign recurse dump --- tool/trimmer/main.go | 32 ++++++++----------- .../test_cases/tests/dir/dir2/test.thrift | 2 ++ .../tests/dir/dir3/dir4/another.thrift | 16 ++++++++++ 3 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index b955fda0..75bd3575 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -117,16 +117,7 @@ func main() { println("output-dir should be set outside of -r base-dir to avoid overlay") os.Exit(2) } - createDirTree(a.Recurse, a.OutputFile) recurseDump(ast, a.Recurse, a.OutputFile) - relativePath, err := filepath.Rel(a.Recurse, a.IDL) - if err != nil { - println("-r input err, range should cover all the target IDLs;", err.Error()) - os.Exit(2) - } - outputFileUrl := filepath.Join(a.OutputFile, relativePath) - check(writeStringToFile(outputFileUrl, idl)) - removeEmptyDir(a.OutputFile) } else { check(writeStringToFile(a.OutputFile, idl)) } @@ -139,16 +130,21 @@ func recurseDump(ast *parser.Thrift, sourceDir, outDir string) { if ast == nil { return } + out, err := dump.DumpIDL(ast) + check(err) + relativeUrl, err := filepath.Rel(sourceDir, ast.Filename) + if err != nil { + println("-r input err, range should cover all the target IDLs;", err.Error()) + os.Exit(2) + } + outputFileUrl := filepath.Join(outDir, relativeUrl) + err = os.MkdirAll(filepath.Dir(outputFileUrl), os.ModePerm) + if err != nil { + println("mkdir", filepath.Dir(outputFileUrl), "error:", err.Error()) + os.Exit(2) + } + check(writeStringToFile(outputFileUrl, out)) for _, includes := range ast.Includes { - out, err := dump.DumpIDL(includes.Reference) - check(err) - relativeUrl, err := filepath.Rel(sourceDir, includes.Reference.Filename) - if err != nil { - println("-r input err, range should cover all the target IDLs;", err.Error()) - os.Exit(2) - } - outputFileUrl := filepath.Join(outDir, relativeUrl) - check(writeStringToFile(outputFileUrl, out)) recurseDump(includes.Reference, sourceDir, outDir) } } diff --git a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift index a7359c51..c5017d7c 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift +++ b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift @@ -13,8 +13,10 @@ // limitations under the License. include "../../../sample1.thrift" +include "../dir3/dir4/another.thrift" // @preserve struct TestStruct{ 1: sample1.Person person + 2: another.AnotherStruct another } \ No newline at end of file diff --git a/tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift b/tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift new file mode 100644 index 00000000..20aff287 --- /dev/null +++ b/tool/trimmer/test_cases/tests/dir/dir3/dir4/another.thrift @@ -0,0 +1,16 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +struct AnotherStruct{ +} \ No newline at end of file From 5058520755b72b00e5fb601fb385b3a1bff07a6d Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 9 Oct 2023 20:49:10 +0800 Subject: [PATCH 12/17] feat: add yaml-config support for trimmer --- generator/golang/backend.go | 3 +- tool/trimmer/args.go | 4 +- tool/trimmer/dirTree.go | 81 ------------------- tool/trimmer/dirTree_test.go | 58 ------------- tool/trimmer/main.go | 11 +++ .../test_cases/tests/dir/dir2/test.thrift | 6 ++ .../tests/dir/dir2/trim_config.yaml | 17 ++++ tool/trimmer/trim/config.go | 48 +++++++++++ 8 files changed, 86 insertions(+), 142 deletions(-) delete mode 100644 tool/trimmer/dirTree.go delete mode 100644 tool/trimmer/dirTree_test.go create mode 100644 tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml create mode 100644 tool/trimmer/trim/config.go diff --git a/generator/golang/backend.go b/generator/golang/backend.go index d96e843d..15b6cbbd 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -86,7 +86,8 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.log = log g.prepareUtilities() if g.utils.Features().TrimIDL { - err := trim.TrimAST(req.AST, nil, false) + cfg := trim.ParseYamlConfig(filepath.Dir(req.AST.Filename)) + err := trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) if err != nil { g.log.Warn("trim error:", err.Error()) } diff --git a/tool/trimmer/args.go b/tool/trimmer/args.go index eee0f637..ca3cea05 100644 --- a/tool/trimmer/args.go +++ b/tool/trimmer/args.go @@ -63,8 +63,8 @@ func (a *Arguments) BuildFlags() *flag.FlagSet { f.Var(&a.Methods, "m", "") f.Var(&a.Methods, "method", "") - f.StringVar(&a.Preserve, "p", "true", "") - f.StringVar(&a.Preserve, "preserve", "true", "") + f.StringVar(&a.Preserve, "p", "", "") + f.StringVar(&a.Preserve, "preserve", "", "") f.Usage = help return f diff --git a/tool/trimmer/dirTree.go b/tool/trimmer/dirTree.go deleted file mode 100644 index c7c39683..00000000 --- a/tool/trimmer/dirTree.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2023 CloudWeGo Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "errors" - "fmt" - "os" - "path/filepath" -) - -// create directory-tree before dump -func createDirTree(sourceDir, destinationDir string) { - err := filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - if path[len(sourceDir)-1] != filepath.Separator { - path = path + string(filepath.Separator) - } - newDir := filepath.Join(destinationDir, path[len(sourceDir):]) - err := os.MkdirAll(newDir, os.ModePerm) - if err != nil { - return errors.New("create dir tree error:" + err.Error()) - } - } - return nil - }) - if err != nil { - fmt.Printf("manage output error: %v\n", err) - os.Exit(2) - } -} - -// remove empty directory of output dir-tree -func removeEmptyDir(source string) { - files, err := os.ReadDir(source) - if err != nil { - return - } - for _, file := range files { - if file.IsDir() { - removeEmptyDir(source + string(filepath.Separator) + file.Name()) - } - } - empty, err := isDirectoryEmpty(source) - if empty || err != nil { - _ = os.RemoveAll(source) - } -} - -func isDirectoryEmpty(path string) (bool, error) { - dir, err := os.Open(path) - if err != nil { - return false, err - } - defer dir.Close() - - _, err = dir.Readdirnames(1) - if err == nil { - return false, nil - } - - if errors.Is(err, os.ErrNotExist) { - return true, nil - } - return false, err -} diff --git a/tool/trimmer/dirTree_test.go b/tool/trimmer/dirTree_test.go deleted file mode 100644 index 7ae23697..00000000 --- a/tool/trimmer/dirTree_test.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2023 CloudWeGo Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "os" - "path/filepath" - "testing" - - "github.com/cloudwego/thriftgo/pkg/test" -) - -func TestDirTree(t *testing.T) { - _ = os.RemoveAll("trimmer_test") - createDirTree("test_cases", "trimmer_test") - fileCount, dirCount, err := countFilesAndSubdirectories("trimmer_test") - test.Assert(t, err == nil) - test.Assert(t, fileCount == 0) - test.Assert(t, dirCount == 4) - removeEmptyDir("trimmer_test") - _, err = os.ReadDir("trimmer_test") - test.Assert(t, err != nil) -} - -func countFilesAndSubdirectories(dirPath string) (int, int, error) { - var fileCount, dirCount int - files, err := os.ReadDir(dirPath) - if err != nil { - return 0, 0, err - } - for _, file := range files { - if file.IsDir() { - dirCount++ - subDirPath := filepath.Join(dirPath, file.Name()) - subFileCount, subDirCount, err := countFilesAndSubdirectories(subDirPath) - if err != nil { - return 0, 0, err - } - fileCount += subFileCount - dirCount += subDirCount - } else { - fileCount++ - } - } - return fileCount, dirCount, nil -} diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index 75bd3575..85f69f66 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -73,6 +73,17 @@ func main() { check(err) check(semantic.ResolveSymbols(ast)) + // try parse yaml config + cfg := trim.ParseYamlConfig(filepath.Dir(a.IDL)) + if cfg != nil { + if len(a.Methods) == 0 && len(cfg.Methods) > 0 { + a.Methods = cfg.Methods + } + if a.Preserve == "" && !(*cfg.Preserve) { + preserve = false + } + } + // trim ast check(trim.TrimAST(ast, a.Methods, !preserve)) diff --git a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift index c5017d7c..56ff1303 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift +++ b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift @@ -19,4 +19,10 @@ include "../dir3/dir4/another.thrift" struct TestStruct{ 1: sample1.Person person 2: another.AnotherStruct another +} + +service TestService{ + void func1() + another.AnotherStruct func2() + void func3() } \ No newline at end of file diff --git a/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml new file mode 100644 index 00000000..1b0dcbe1 --- /dev/null +++ b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml @@ -0,0 +1,17 @@ +# Copyright 2023 CloudWeGo Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +methods: + - "TestService.func1" + - "TestService.func3" +preserve: false \ No newline at end of file diff --git a/tool/trimmer/trim/config.go b/tool/trimmer/trim/config.go new file mode 100644 index 00000000..af1085f4 --- /dev/null +++ b/tool/trimmer/trim/config.go @@ -0,0 +1,48 @@ +// Copyright 2023 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trim + +import ( + "fmt" + "gopkg.in/yaml.v3" + "os" + "path/filepath" +) + +var DefaultYamlFileName = "trim_config.yaml" + +type YamlArguments struct { + Methods []string `yaml:"methods,omitempty"` + Preserve *bool `yaml:"preserve,omitempty"` +} + +func ParseYamlConfig(path string) *YamlArguments { + cfg := YamlArguments{} + dataBytes, err := os.ReadFile(filepath.Join(path, DefaultYamlFileName)) + if err != nil { + return nil + } + fmt.Println("using trim config:", filepath.Join(path, DefaultYamlFileName)) + err = yaml.Unmarshal(dataBytes, &cfg) + if err != nil { + fmt.Println("unmarshal yaml config fail:", err) + return nil + } + if cfg.Preserve == nil { + t := true + cfg.Preserve = &t + } + return &cfg +} From 910fc7d5a3ba3f982e17c57f2f49e0645d5b75cc Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 9 Oct 2023 20:49:10 +0800 Subject: [PATCH 13/17] feat: add yaml-config support for trimmer --- tool/trimmer/trim/config.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tool/trimmer/trim/config.go b/tool/trimmer/trim/config.go index af1085f4..61a34606 100644 --- a/tool/trimmer/trim/config.go +++ b/tool/trimmer/trim/config.go @@ -16,9 +16,10 @@ package trim import ( "fmt" - "gopkg.in/yaml.v3" "os" "path/filepath" + + "gopkg.in/yaml.v3" ) var DefaultYamlFileName = "trim_config.yaml" From d0150deffd895ddd3728da3a9f1e97ca8ae055a3 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 9 Oct 2023 20:49:10 +0800 Subject: [PATCH 14/17] feat: add yaml-config support for trimmer --- generator/golang/backend.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index 15b6cbbd..5499ab01 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -87,7 +87,13 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.prepareUtilities() if g.utils.Features().TrimIDL { cfg := trim.ParseYamlConfig(filepath.Dir(req.AST.Filename)) - err := trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) + var err error + if cfg == nil { + err = trim.TrimAST(req.AST, nil, false) + } else { + err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) + } + if err != nil { g.log.Warn("trim error:", err.Error()) } From 624795ce021333a64beb6028b250accff4a4c1dc Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Fri, 20 Oct 2023 13:06:54 +0800 Subject: [PATCH 15/17] chore: set trimmer yaml path to WD --- generator/golang/backend.go | 4 +++- tool/trimmer/main.go | 16 +++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index 5499ab01..460ef9e9 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -17,6 +17,7 @@ package golang import ( "fmt" "go/format" + "os" "path/filepath" "strings" "text/template" @@ -86,7 +87,8 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.log = log g.prepareUtilities() if g.utils.Features().TrimIDL { - cfg := trim.ParseYamlConfig(filepath.Dir(req.AST.Filename)) + wd, _ := os.Getwd() + cfg := trim.ParseYamlConfig(wd) var err error if cfg == nil { err = trim.TrimAST(req.AST, nil, false) diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index 85f69f66..38100d7b 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -74,13 +74,15 @@ func main() { check(semantic.ResolveSymbols(ast)) // try parse yaml config - cfg := trim.ParseYamlConfig(filepath.Dir(a.IDL)) - if cfg != nil { - if len(a.Methods) == 0 && len(cfg.Methods) > 0 { - a.Methods = cfg.Methods - } - if a.Preserve == "" && !(*cfg.Preserve) { - preserve = false + if wd, err := os.Getwd(); err == nil { + cfg := trim.ParseYamlConfig(wd) + if cfg != nil { + if len(a.Methods) == 0 && len(cfg.Methods) > 0 { + a.Methods = cfg.Methods + } + if a.Preserve == "" && !(*cfg.Preserve) { + preserve = false + } } } From 72bd28229b307240e5ccaef735a2409db2415d80 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Mon, 23 Oct 2023 20:21:31 +0800 Subject: [PATCH 16/17] feat: support preserve-structs for yaml-config of trimmer tool --- generator/golang/backend.go | 4 ++-- tool/trimmer/main.go | 4 +++- tool/trimmer/test_cases/tests/dir/dir2/test.thrift | 3 +++ .../test_cases/tests/dir/dir2/trim_config.yaml | 4 +++- tool/trimmer/trim/config.go | 5 +++-- tool/trimmer/trim/mark.go | 5 +++++ tool/trimmer/trim/traversal.go | 4 ++-- tool/trimmer/trim/trimmer.go | 12 +++++++----- 8 files changed, 28 insertions(+), 13 deletions(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index 460ef9e9..f6e3a328 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -91,9 +91,9 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R cfg := trim.ParseYamlConfig(wd) var err error if cfg == nil { - err = trim.TrimAST(req.AST, nil, false) + err = trim.TrimAST(req.AST, nil, false, nil) } else { - err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve) + err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve, cfg.PreservedStructs) } if err != nil { diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index 38100d7b..b79ef37a 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -74,6 +74,7 @@ func main() { check(semantic.ResolveSymbols(ast)) // try parse yaml config + var preservedStructs []string if wd, err := os.Getwd(); err == nil { cfg := trim.ParseYamlConfig(wd) if cfg != nil { @@ -83,11 +84,12 @@ func main() { if a.Preserve == "" && !(*cfg.Preserve) { preserve = false } + preservedStructs = cfg.PreservedStructs } } // trim ast - check(trim.TrimAST(ast, a.Methods, !preserve)) + check(trim.TrimAST(ast, a.Methods, !preserve, preservedStructs)) // dump the trimmed ast to idl idl, err := dump.DumpIDL(ast) diff --git a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift index 56ff1303..804cb5d8 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/test.thrift +++ b/tool/trimmer/test_cases/tests/dir/dir2/test.thrift @@ -25,4 +25,7 @@ service TestService{ void func1() another.AnotherStruct func2() void func3() +} + +union useless{ } \ No newline at end of file diff --git a/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml index 1b0dcbe1..f65338b1 100644 --- a/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml +++ b/tool/trimmer/test_cases/tests/dir/dir2/trim_config.yaml @@ -14,4 +14,6 @@ methods: - "TestService.func1" - "TestService.func3" -preserve: false \ No newline at end of file +preserve: true +preserved_structs: + - "useless" \ No newline at end of file diff --git a/tool/trimmer/trim/config.go b/tool/trimmer/trim/config.go index 61a34606..28786bab 100644 --- a/tool/trimmer/trim/config.go +++ b/tool/trimmer/trim/config.go @@ -25,8 +25,9 @@ import ( var DefaultYamlFileName = "trim_config.yaml" type YamlArguments struct { - Methods []string `yaml:"methods,omitempty"` - Preserve *bool `yaml:"preserve,omitempty"` + Methods []string `yaml:"methods,omitempty"` + Preserve *bool `yaml:"preserve,omitempty"` + PreservedStructs []string `yaml:"preserved_structs,omitempty"` } func ParseYamlConfig(path string) *YamlArguments { diff --git a/tool/trimmer/trim/mark.go b/tool/trimmer/trim/mark.go index 55adbb1a..8bd5e903 100644 --- a/tool/trimmer/trim/mark.go +++ b/tool/trimmer/trim/mark.go @@ -261,5 +261,10 @@ func (t *Trimmer) checkPreserve(theStruct *parser.StructLike) bool { if t.forceTrimming { return false } + for _, name := range t.preservedStructs { + if name == theStruct.Name { + return true + } + } return t.preserveRegex.MatchString(strings.ToLower(theStruct.ReservedComments)) } diff --git a/tool/trimmer/trim/traversal.go b/tool/trimmer/trim/traversal.go index ddba0cf8..bc4441e0 100644 --- a/tool/trimmer/trim/traversal.go +++ b/tool/trimmer/trim/traversal.go @@ -40,7 +40,7 @@ func (t *Trimmer) traversal(ast *parser.Thrift, filename string) { var listUnion []*parser.StructLike for i := range ast.Unions { - if t.marks[filename][ast.Unions[i]] { + if t.marks[filename][ast.Unions[i]] || t.checkPreserve(ast.Unions[i]) { listUnion = append(listUnion, ast.Unions[i]) } } @@ -48,7 +48,7 @@ func (t *Trimmer) traversal(ast *parser.Thrift, filename string) { var listException []*parser.StructLike for i := range ast.Exceptions { - if t.marks[filename][ast.Exceptions[i]] { + if t.marks[filename][ast.Exceptions[i]] || t.checkPreserve(ast.Exceptions[i]) { listException = append(listException, ast.Exceptions[i]) } } diff --git a/tool/trimmer/trim/trimmer.go b/tool/trimmer/trim/trimmer.go index 39a143f2..1bee9d7c 100644 --- a/tool/trimmer/trim/trimmer.go +++ b/tool/trimmer/trim/trimmer.go @@ -32,14 +32,15 @@ type Trimmer struct { marks map[string]map[interface{}]bool outDir string // use -m - trimMethods []string - trimMethodValid []bool - preserveRegex *regexp.Regexp - forceTrimming bool + trimMethods []string + trimMethodValid []bool + preserveRegex *regexp.Regexp + forceTrimming bool + preservedStructs []string } // TrimAST trim the single AST, pass method names if -m specified -func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool) error { +func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool, preservedStructs []string) error { trimmer, err := newTrimmer(nil, "") if err != nil { return err @@ -59,6 +60,7 @@ func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool) error } } } + trimmer.preservedStructs = preservedStructs trimmer.markAST(ast) trimmer.traversal(ast, ast.Filename) if path := parser.CircleDetect(ast); len(path) > 0 { From 7afa4e32c839bc729a76f8d4d68fbfa0467cdd54 Mon Sep 17 00:00:00 2001 From: linhanyuan Date: Tue, 24 Oct 2023 14:40:36 +0800 Subject: [PATCH 17/17] feat: support preserve-structs for yaml-config of trimmer tool --- generator/golang/backend.go | 11 +------- tool/trimmer/main.go | 24 ++++------------ tool/trimmer/trim/trimmer.go | 33 ++++++++++++++++++++-- tool/trimmer/trim/trimmer_test.go | 47 +++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 30 deletions(-) diff --git a/generator/golang/backend.go b/generator/golang/backend.go index f6e3a328..e653c1db 100644 --- a/generator/golang/backend.go +++ b/generator/golang/backend.go @@ -17,7 +17,6 @@ package golang import ( "fmt" "go/format" - "os" "path/filepath" "strings" "text/template" @@ -87,15 +86,7 @@ func (g *GoBackend) Generate(req *plugin.Request, log backend.LogFunc) *plugin.R g.log = log g.prepareUtilities() if g.utils.Features().TrimIDL { - wd, _ := os.Getwd() - cfg := trim.ParseYamlConfig(wd) - var err error - if cfg == nil { - err = trim.TrimAST(req.AST, nil, false, nil) - } else { - err = trim.TrimAST(req.AST, cfg.Methods, !*cfg.Preserve, cfg.PreservedStructs) - } - + err := trim.TrimAST(&trim.TrimASTArg{Ast: req.AST, TrimMethods: nil, Preserve: nil}) if err != nil { g.log.Warn("trim error:", err.Error()) } diff --git a/tool/trimmer/main.go b/tool/trimmer/main.go index b79ef37a..fa97afac 100644 --- a/tool/trimmer/main.go +++ b/tool/trimmer/main.go @@ -53,13 +53,14 @@ func main() { os.Exit(0) } - preserve := true + var preserveInput *bool if a.Preserve != "" { - preserve, err = strconv.ParseBool(a.Preserve) + preserve, err := strconv.ParseBool(a.Preserve) if err != nil { help() os.Exit(2) } + preserveInput = &preserve } // parse file to ast @@ -73,23 +74,10 @@ func main() { check(err) check(semantic.ResolveSymbols(ast)) - // try parse yaml config - var preservedStructs []string - if wd, err := os.Getwd(); err == nil { - cfg := trim.ParseYamlConfig(wd) - if cfg != nil { - if len(a.Methods) == 0 && len(cfg.Methods) > 0 { - a.Methods = cfg.Methods - } - if a.Preserve == "" && !(*cfg.Preserve) { - preserve = false - } - preservedStructs = cfg.PreservedStructs - } - } - // trim ast - check(trim.TrimAST(ast, a.Methods, !preserve, preservedStructs)) + check(trim.TrimAST(&trim.TrimASTArg{ + Ast: ast, TrimMethods: a.Methods, Preserve: preserveInput, + })) // dump the trimmed ast to idl idl, err := dump.DumpIDL(ast) diff --git a/tool/trimmer/trim/trimmer.go b/tool/trimmer/trim/trimmer.go index 1bee9d7c..97fe1bdd 100644 --- a/tool/trimmer/trim/trimmer.go +++ b/tool/trimmer/trim/trimmer.go @@ -39,8 +39,37 @@ type Trimmer struct { preservedStructs []string } -// TrimAST trim the single AST, pass method names if -m specified -func TrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool, preservedStructs []string) error { +type TrimASTArg struct { + Ast *parser.Thrift + TrimMethods []string + Preserve *bool +} + +// TrimAST parse the cfg and trim the single AST +func TrimAST(arg *TrimASTArg) error { + var preservedStructs []string + if wd, err := os.Getwd(); err == nil { + cfg := ParseYamlConfig(wd) + if cfg != nil { + if len(arg.TrimMethods) == 0 && len(cfg.Methods) > 0 { + arg.TrimMethods = cfg.Methods + } + if arg.Preserve == nil && !(*cfg.Preserve) { + preserve := false + arg.Preserve = &preserve + } + preservedStructs = cfg.PreservedStructs + } + } + forceTrim := false + if arg.Preserve != nil { + forceTrim = !*arg.Preserve + } + return doTrimAST(arg.Ast, arg.TrimMethods, forceTrim, preservedStructs) +} + +// doTrimAST trim the single AST, pass method names if -m specified +func doTrimAST(ast *parser.Thrift, trimMethods []string, forceTrimming bool, preservedStructs []string) error { trimmer, err := newTrimmer(nil, "") if err != nil { return err diff --git a/tool/trimmer/trim/trimmer_test.go b/tool/trimmer/trim/trimmer_test.go index 5687a2d1..0dd219ae 100644 --- a/tool/trimmer/trim/trimmer_test.go +++ b/tool/trimmer/trim/trimmer_test.go @@ -85,3 +85,50 @@ func TestInclude(t *testing.T) { test.Assert(t, len(ast.Includes) == 1) test.Assert(t, ast.Includes[0].Used == nil) } + +func TestTrimMethod(t *testing.T) { + filename := filepath.Join("..", "test_cases", "tests", "dir", "dir2", "test.thrift") + ast, err := parser.ParseFile(filename, nil, true) + check(err) + if path := parser.CircleDetect(ast); len(path) > 0 { + check(fmt.Errorf("found include circle:\n\t%s", path)) + } + checker := semantic.NewChecker(semantic.Options{FixWarnings: true}) + _, err = checker.CheckAll(ast) + check(err) + check(semantic.ResolveSymbols(ast)) + + methods := make([]string, 1) + methods[0] = "func1" + + err = TrimAST(&TrimASTArg{ + Ast: ast, + TrimMethods: methods, + Preserve: nil, + }) + check(err) + test.Assert(t, len(ast.Services[0].Functions) == 1) +} + +func TestPreserve(t *testing.T) { + filename := filepath.Join("..", "test_cases", "tests", "dir", "dir2", "test.thrift") + ast, err := parser.ParseFile(filename, nil, true) + check(err) + if path := parser.CircleDetect(ast); len(path) > 0 { + check(fmt.Errorf("found include circle:\n\t%s", path)) + } + checker := semantic.NewChecker(semantic.Options{FixWarnings: true}) + _, err = checker.CheckAll(ast) + check(err) + check(semantic.ResolveSymbols(ast)) + + preserve := false + + err = TrimAST(&TrimASTArg{ + Ast: ast, + TrimMethods: nil, + Preserve: &preserve, + }) + check(err) + test.Assert(t, len(ast.Structs) == 0) +}