├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── pr-check.yml │ └── tests.yml ├── .gitignore ├── .golangci.yaml ├── .licenserc.yaml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── README_CN.md ├── _typos.toml ├── cmd └── static │ ├── api_list_flags.go │ ├── client_flags.go │ ├── cmd.go │ ├── doc_flags.go │ ├── job_flags.go │ ├── model_flags.go │ └── server_flags.go ├── config ├── api_list.go ├── argument.go ├── client.go ├── doc.go ├── fallback.go ├── job.go ├── model.go └── server.go ├── cwgo.go ├── go.mod ├── go.sum ├── hack ├── resolve-modules.sh ├── tools.sh └── util.sh ├── images ├── lark_group.png └── lark_group_cn.png ├── licenses ├── LICENSE-sprig.txt ├── License-camelcase.txt ├── License-cli.txt ├── License-cobra.txt ├── License-gen.txt ├── License-gorm.txt ├── License-mongo-go-driver.txt ├── License-mysql.txt ├── License-postgres.txt ├── License-repogen.txt ├── License-retry-go.txt ├── License-sqlite.txt ├── License-sqlserver.txt ├── License-survey.txt ├── License-typeid.txt └── License-yaml2go.txt ├── meta └── version.go ├── pkg ├── api_list │ ├── api_list.go │ ├── api_list_test.go │ ├── consts.go │ ├── internal │ │ └── tests │ │ │ ├── case1 │ │ │ ├── biz │ │ │ │ └── router │ │ │ │ │ ├── hello │ │ │ │ │ └── example │ │ │ │ │ │ └── hello.go │ │ │ │ │ └── register.go │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── hello.thrift │ │ │ ├── main.go │ │ │ ├── router.go │ │ │ └── router_gen.go │ │ │ ├── case2 │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ └── main.go │ │ │ └── case3 │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── main.go │ │ │ └── router │ │ │ ├── router.go │ │ │ └── user │ │ │ └── user.go │ ├── module.go │ └── search.go ├── client │ ├── check.go │ ├── client.go │ ├── hz.go │ └── kitex.go ├── common │ ├── kx_registry │ │ └── registry.go │ ├── parser │ │ ├── consts.go │ │ └── proto.go │ └── utils │ │ ├── env.go │ │ ├── file.go │ │ ├── git.go │ │ ├── hz.go │ │ └── slice.go ├── config_generator │ ├── config_generator.go │ ├── config_generator_test.go │ ├── metadata.go │ ├── sdk.go │ ├── sdk_test.go │ ├── util.go │ ├── yaml2go.go │ └── yaml2go_test.go ├── consts │ └── const.go ├── curd │ ├── code │ │ ├── common.go │ │ ├── statement.go │ │ └── type.go │ ├── doc │ │ ├── doc.go │ │ └── mongo │ │ │ ├── codegen │ │ │ ├── aggregate_base.go │ │ │ ├── base_params.go │ │ │ ├── bulk.go │ │ │ ├── bulk_base.go │ │ │ ├── codegen.go │ │ │ ├── codegen_base.go │ │ │ ├── count.go │ │ │ ├── count_base.go │ │ │ ├── delete.go │ │ │ ├── delete_base.go │ │ │ ├── find.go │ │ │ ├── find_base.go │ │ │ ├── insert.go │ │ │ ├── insert_base.go │ │ │ ├── query.go │ │ │ ├── transaction.go │ │ │ ├── update.go │ │ │ └── update_base.go │ │ │ └── plugin │ │ │ ├── base.go │ │ │ ├── plugin.go │ │ │ └── thriftgo.go │ ├── extract │ │ ├── extract.go │ │ ├── proto.go │ │ └── thrift.go │ ├── parse │ │ ├── bulk.go │ │ ├── count.go │ │ ├── delete.go │ │ ├── error.go │ │ ├── find.go │ │ ├── insert.go │ │ ├── operation.go │ │ ├── parse.go │ │ ├── query.go │ │ ├── transaction.go │ │ └── update.go │ └── template │ │ ├── base.go │ │ ├── function.go │ │ ├── interface.go │ │ ├── method.go │ │ ├── render.go │ │ ├── struct.go │ │ └── template.go ├── fallback │ └── fallback.go ├── job │ ├── job.go │ ├── job_test.go │ └── template.go ├── model │ └── model.go └── server │ ├── check.go │ ├── hz.go │ ├── kitex.go │ └── server.go └── tpl ├── hertz ├── client │ └── standard │ │ └── package.yaml └── server │ ├── standard │ ├── layout.yaml │ └── package.yaml │ └── standard_v2 │ ├── layout.yaml │ └── package.yaml ├── init.go └── kitex ├── client └── standard │ ├── client_tpl.yaml │ ├── default_tpl.yaml │ └── init_tpl.yaml └── server └── standard ├── bootstrap_sh_tpl.yaml ├── build_sh_tpl.yaml ├── conf_dev_tpl.yaml ├── conf_online_tpl.yaml ├── conf_test_tpl.yaml ├── conf_tpl.yaml ├── dal_init.yaml ├── docker_compose.yaml ├── handler_tpl.yaml ├── ignore_tpl.yaml ├── kitex_yaml.yaml ├── main_tpl.yaml ├── mysql.yaml ├── readme_tpl.yaml ├── redis.yaml ├── service.yaml └── service_test.yaml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | **To Reproduce** 15 | 16 | Steps to reproduce the behavior: 17 | 1. Go to '...' 18 | 2. Click on '....' 19 | 3. Scroll down to '....' 20 | 4. See error 21 | 22 | **Expected behavior** 23 | 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | 28 | If applicable, add screenshots to help explain your problem. 29 | 30 | **Kitex version:** 31 | 32 | Please provide the version of Kitex you are using. 33 | 34 | **Environment:** 35 | 36 | The output of `go env`. 37 | 38 | **Additional context** 39 | 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | 14 | **Describe the solution you'd like** 15 | 16 | A clear and concise description of what you want to happen. 17 | 18 | **Describe alternatives you've considered** 19 | 20 | A clear and concise description of any alternative solutions or features you've considered. 21 | 22 | **Additional context** 23 | 24 | Add any other context or screenshots about the feature request here. 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### What type of PR is this? 2 | 17 | 18 | #### What this PR does / why we need it (en: English/zh: Chinese): 19 | 23 | en: 24 | zh: 25 | 26 | #### Which issue(s) this PR fixes: 27 | 31 | -------------------------------------------------------------------------------- /.github/workflows/pr-check.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Check 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | compliant: 7 | runs-on: [self-hosted, X64] 8 | steps: 9 | - uses: actions/checkout@v3 10 | 11 | - name: Check License Header 12 | uses: apache/skywalking-eyes/header@v0.4.0 13 | 14 | - name: typos-action 15 | uses: crate-ci/typos@master 16 | 17 | resolve-modules: 18 | name: resolve module 19 | runs-on: ubuntu-latest 20 | outputs: 21 | matrix: ${{ steps.set-matrix.outputs.matrix }} 22 | steps: 23 | - name: Checkout Repo 24 | uses: actions/checkout@v3 25 | 26 | - id: set-matrix 27 | run: ./hack/resolve-modules.sh 28 | 29 | lint: 30 | name: lint module 31 | runs-on: ubuntu-latest 32 | needs: resolve-modules 33 | strategy: 34 | matrix: ${{ fromJson(needs.resolve-modules.outputs.matrix) }} 35 | steps: 36 | - uses: actions/checkout@v3 37 | - name: Lint 38 | uses: golangci/golangci-lint-action@v3 39 | with: 40 | version: latest 41 | working-directory: ${{ matrix.workdir }} 42 | args: -E gofumpt --timeout 5m 43 | skip-pkg-cache: true 44 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [ push, pull_request ] 4 | 5 | jobs: 6 | ut: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | - name: Set up Go 12 | uses: actions/setup-go@v5 13 | with: 14 | go-version: "1.22" 15 | 16 | - name: Setup Environment 17 | run: | 18 | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV 19 | echo "$(go env GOPATH)/bin" >> $GITHUB_PATH 20 | - name: Module cache 21 | uses: actions/cache@v3 22 | with: 23 | path: | 24 | ~/.cache/go-build 25 | ~/go/pkg/mod 26 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} 27 | restore-keys: | 28 | ${{ runner.os }}-go 29 | 30 | - name: Unit Test 31 | run: make test 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | # the result of the go build 18 | output* 19 | output/* 20 | 21 | # Files generated by IDEs 22 | .idea/ 23 | *.iml 24 | 25 | # Vim swap files 26 | *.swp 27 | 28 | # Vscode files 29 | .vscode 30 | 31 | # mac 32 | .DS_Store 33 | 34 | # platform 35 | /platform/server/log/ 36 | /platform/manifest/config/config-dev.yaml 37 | /platform/manifest/config/config-pro.yaml 38 | /platform/dist/ 39 | 40 | 41 | -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | # Options for analysis running. 2 | run: 3 | # include `vendor` `third_party` `testdata` `examples` `Godeps` `builtin` 4 | skip-dirs-use-default: true 5 | skip-dirs: 6 | - kitex_gen 7 | skip-files: 8 | - ".*\\.mock\\.go$" 9 | # output configuration options 10 | output: 11 | # Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions 12 | format: colored-line-number 13 | # All available settings of specific linters. 14 | # Refer to https://golangci-lint.run/usage/linters 15 | linters-settings: 16 | gofumpt: 17 | # Choose whether to use the extra rules. 18 | # Default: false 19 | extra-rules: true 20 | govet: 21 | # Disable analyzers by name. 22 | # Run `go tool vet help` to see all analyzers. 23 | disable: 24 | - stdmethods 25 | linters: 26 | enable: 27 | - gofumpt 28 | - gofmt 29 | disable: 30 | - errcheck 31 | - typecheck 32 | - deadcode 33 | - varcheck 34 | - staticcheck 35 | issues: 36 | exclude-use-default: true 37 | -------------------------------------------------------------------------------- /.licenserc.yaml: -------------------------------------------------------------------------------- 1 | header: 2 | license: 3 | spdx-id: Apache-2.0 4 | copyright-owner: CloudWeGo Authors 5 | 6 | paths: 7 | - '**/*.go' 8 | - '**/*.s' 9 | 10 | paths-ignore: 11 | - "example/**" 12 | - "platform/server/shared/kitex_gen/**" 13 | - "platform/server/cmd/api/internal/biz/model/**" 14 | 15 | comment: on-failure -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | ## Your First Pull Request 4 | We use github for our codebase. You can start by reading [How To Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests). 5 | 6 | ## Branch Organization 7 | We use [git-flow](https://nvie.com/posts/a-successful-git-branching-model/) as our branch organization, as known as [FDD](https://en.wikipedia.org/wiki/Feature-driven_development) 8 | 9 | ## Bugs 10 | ### 1. How to Find Known Issues 11 | We are using [Github Issues](https://github.com/cloudwego/kitex/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn’t already exist. 12 | 13 | ### 2. Reporting New Issues 14 | Providing a reduced test code is a recommended way for reporting issues. Then can placed in: 15 | - Just in issues 16 | - [Golang Playground](https://play.golang.org/) 17 | 18 | ### 3. Security Bugs 19 | Please do not report the safe disclosure of bugs to public issues. Contact us by [Support Email](mailto:conduct@cloudwego.io) 20 | 21 | ## How to Get in Touch 22 | - [Email](mailto:conduct@cloudwego.io) 23 | 24 | ## Submit a Pull Request 25 | Before you submit your Pull Request (PR) consider the following guidelines: 26 | 1. Search [GitHub](https://github.com/cloudwego/kitex/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate existing efforts. 27 | 2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add. Discussing the design upfront helps to ensure that we're ready to accept your work. 28 | 3. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the cloudwego/kitex repo. 29 | 4. In your forked repository, make your changes in a new git branch: 30 | ``` 31 | git checkout -b my-fix-branch develop 32 | ``` 33 | 5. Create your patch, including appropriate test cases. 34 | 6. Follow our [Style Guides](#code-style-guides). 35 | 7. Commit your changes using a descriptive commit message that follows [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit). 36 | Adherence to these conventions is necessary because release notes are automatically generated from these messages. 37 | 8. Push your branch to GitHub: 38 | ``` 39 | git push origin my-fix-branch 40 | ``` 41 | 9. In GitHub, send a pull request to `kitex:develop` 42 | 43 | ## Contribution Prerequisites 44 | - Our development environment keeps up with [Go Official](https://golang.org/project/). 45 | - You need fully checking with lint tools before submit your pull request. [gofmt](https://golang.org/pkg/cmd/gofmt/) and [golangci-lint](https://github.com/golangci/golangci-lint) 46 | - You are familiar with [Github](https://github.com) 47 | - Maybe you need familiar with [Actions](https://github.com/features/actions)(our default workflow tool). 48 | 49 | ## Code Style Guides 50 | Also see [Pingcap General advice](https://pingcap.github.io/style-guide/general.html). 51 | 52 | Good resources: 53 | - [Effective Go](https://golang.org/doc/effective_go) 54 | - [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) 55 | - [Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md) 56 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TOOLS_SHELL="./hack/tools.sh" 2 | 3 | .PHONY: test 4 | test: 5 | @${TOOLS_SHELL} test 6 | @echo "go test finished" 7 | 8 | 9 | 10 | .PHONY: vet 11 | vet: 12 | @${TOOLS_SHELL} vet 13 | @echo "vet check finished" -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | # cwgo 2 | 3 | 中文 | [English](./README.md) 4 | 5 | cwgo 是 CloudWeGo All in one 代码生成工具,整合了 kitex 和 hz 工具的优势,以提高开发者的编码效率和使用体验。其主要功能特点如下: 6 | 7 | ## 工具特点 8 | 9 | - 支持生成工程化模板 10 | 11 | cwgo 工具支持生成 MVC 项目 Layout,用户只需要根据不同目录的功能,在相应的位置完成自己的业务代码即可,聚焦业务逻辑。 12 | 13 | - 支持生成 Server、Client 代码 14 | 15 | cwgo 工具支持生成 Kitex、Hertz 的 Server 和 Client 代码,提供了对 Client 的封装。用户可以开箱即用的调用下游,免去封装 Client 的繁琐步骤。 16 | 17 | - 支持生成关系型数据库代码 18 | 19 | cwgo 工具支持生成关系型数据库 CURD 代码。用户无需再自行封装繁琐的 CURD 代码,提高用户的工作效率。 20 | 21 | - 支持生成文档类数据库代码 22 | 23 | cwgo 工具支持基于 IDL (thrift/protobuf) 生成文档类数据库 CURD 代码,目前支持 MongoDB。用户无需再自行封装繁琐的 CURD 代码,提高用户的工作效率。 24 | 25 | - 支持生成命令行自动补全脚本 26 | 27 | cwgo 工具支持生成命令行自动补全脚本,提高用户命令行编写的效率。 28 | 29 | - 支持分析 Hertz 项目路由和(路由注册)代码的关系 30 | 31 | cwgo 支持通过分析 Hertz 项目代码获取路由和(路由注册)代码的关系。 32 | 33 | - 支持回退为 kitex、Hz 工具 34 | 35 | 如果之前是 kitex、Hz 工具的用户,仍然可以使用 cwgo 工具。cwgo 工具支持回退功能,可以当作 kitex、Hz 使用,真正实现一个工具生成所有。 36 | 37 | ## 安装 cwgo 工具 38 | 39 | ```shell 40 | # Go 1.15 及之前版本 41 | GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get github.com/cloudwego/cwgo@latest 42 | 43 | # Go 1.16 及以后版本 44 | GOPROXY=https://goproxy.cn/,direct go install github.com/cloudwego/cwgo@latest 45 | ``` 46 | 47 | ## 详细文档 48 | 49 | ### [快速开始](https://www.cloudwego.io/zh/docs/cwgo/getting-started/) 50 | 51 | ### 命令行工具 52 | 53 | 包含命令行工具形式及使用,详见[文档](https://www.cloudwego.io/zh/docs/cwgo/tutorials/cli/) 54 | 55 | ### 模板拓展 56 | 57 | 包含用户自定义模板的使用,详见[文档](https://www.cloudwego.cn/zh/docs/cwgo/tutorials/templete-extension/) 58 | 59 | ### Layout 60 | 61 | Layout 生成及 Layout 介绍,详见[文档](https://www.cloudwego.io/zh/docs/cwgo/tutorials/layout/) 62 | 63 | ### Client 64 | 65 | 包含封装后的 Client 的生成和使用,详见[文档](https://www.cloudwego.io/zh/docs/cwgo/tutorials/client/) 66 | 67 | ### DB 68 | 69 | 包含如何使用 cwgo 工具生成关系型数据库 CURD 代码,详见[文档](https://www.cloudwego.io/zh/docs/cwgo/tutorials/db/) 70 | 71 | ### Doc 72 | 73 | 包含如何使用 cwgo 工具生成文档型数据库 CURD 代码,详见[文档](https://www.cloudwego.cn/zh/docs/cwgo/tutorials/doc/) 74 | 75 | ### Api-list 76 | 77 | 支持分析 Hertz 项目代码获取路由和(路由注册)代码的关系,详见[文档](https://www.cloudwego.io/zh/docs/cwgo/tutorials/api-list) 78 | 79 | ### Server 80 | 81 | 包含如何生成 RPC Server、HTTP Server 代码,详见[文档](https://www.cloudwego.cn/zh/docs/cwgo/tutorials/server/) 82 | 83 | ### 命令行自动补全 84 | 85 | 包含如何启用命令行自动补全功能,详见[文档](https://www.cloudwego.cn/zh/docs/cwgo/tutorials/auto-completion/) 86 | 87 | ## 开源许可 88 | 89 | cwgo 基于[Apache License 2.0](https://github.com/cloudwego/cwgo/blob/main/LICENSE) 许可证,其依赖的三方组件的开源许可见 [Licenses](https://github.com/cloudwego/cwgo/blob/main/licenses)。 90 | 91 | ## 联系我们 92 | 93 | - Email: conduct@cloudwego.io 94 | - 如何成为 member: [COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md) 95 | - Issues: [Issues](https://github.com/cloudwego/cwgo/issues) 96 | - Discord: 加入我们的 [Discord 频道](https://discord.gg/jceZSE7DsW) 97 | - 飞书用户群([注册飞书](https://www.larksuite.com/zh_cn/download)进群) 98 | 99 | ![LarkGroup](images/lark_group_cn.png) 100 | 101 | ## Landscapes 102 | 103 |

104 |    105 |

106 | CloudWeGo 丰富了 CNCF 云原生生态。 107 |

108 | -------------------------------------------------------------------------------- /_typos.toml: -------------------------------------------------------------------------------- 1 | # Typo check: https://github.com/crate-ci/typos 2 | 3 | [files] 4 | extend-exclude = ["go.sum", "check_branch_name.sh","go.mod"] 5 | 6 | [default.extend-identifiers] 7 | # *sigh* this just isn't worth the cost of fixing 8 | O_WRONLY = "O_WRONLY" 9 | WRONLY = "WRONLY" -------------------------------------------------------------------------------- /cmd/static/api_list_flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package static 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/consts" 21 | "github.com/urfave/cli/v2" 22 | ) 23 | 24 | func apiFlags() []cli.Flag { 25 | return []cli.Flag{ 26 | &cli.StringFlag{ 27 | Name: consts.ProjectPath, 28 | Usage: "Specify the project path.", 29 | }, 30 | &cli.StringFlag{ 31 | Name: consts.HertzRepoUrl, 32 | Aliases: []string{"r"}, 33 | DefaultText: consts.HertzRepoDefaultUrl, 34 | Usage: "Specify the url of the hertz repository you want", 35 | }, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /cmd/static/client_flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package static 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/config" 21 | "github.com/cloudwego/cwgo/pkg/consts" 22 | "github.com/urfave/cli/v2" 23 | ) 24 | 25 | func clientFlags() []cli.Flag { 26 | globalArgs := config.GetGlobalArgs() 27 | return []cli.Flag{ 28 | &cli.StringFlag{Name: consts.Service, Usage: "Specify the server name.(Not recommended,Deprecate in v0.2.0)", Destination: &globalArgs.ClientArgument.ServerName}, 29 | &cli.StringFlag{Name: consts.ServerName, Usage: "Specify the server name.", Destination: &globalArgs.ClientArgument.ServerName}, 30 | &cli.StringFlag{Name: consts.ServiceType, Usage: "Specify the generate type. (RPC or HTTP)", Value: consts.RPC}, 31 | &cli.StringFlag{Name: consts.Module, Aliases: []string{"mod"}, Usage: "Specify the Go module name to generate go.mod.", Destination: &globalArgs.ClientArgument.GoMod}, 32 | &cli.StringFlag{Name: consts.IDLPath, Usage: "Specify the IDL file path. (.thrift or .proto)", Destination: &globalArgs.ClientArgument.IdlPath}, 33 | &cli.StringFlag{Name: consts.Template, Usage: "Specify the template path. Currently cwgo supports git templates, such as `--template https://github.com/***/cwgo_template.git`", Destination: &globalArgs.ClientArgument.Template}, 34 | &cli.StringFlag{Name: consts.Branch, Usage: "Specify the git template's branch, default is main branch.", Destination: &globalArgs.ClientArgument.Branch}, 35 | &cli.StringFlag{Name: consts.Registry, Usage: "Specify the registry, default is None"}, 36 | &cli.StringSliceFlag{Name: consts.ProtoSearchPath, Aliases: []string{"I"}, Usage: "Add an IDL search path for includes. (Valid only if idl is protobuf)"}, 37 | &cli.StringSliceFlag{Name: consts.Pass, Usage: "pass param to hz or kitex"}, 38 | &cli.BoolFlag{Name: consts.Verbose, Usage: "Turn on verbose mode."}, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cmd/static/doc_flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package static 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/consts" 21 | "github.com/urfave/cli/v2" 22 | ) 23 | 24 | func docFlags() []cli.Flag { 25 | return []cli.Flag{ 26 | &cli.StringFlag{Name: consts.IDLPath, Usage: "Specify the IDL file path. (.thrift or .proto)"}, 27 | &cli.StringFlag{Name: consts.Module, Aliases: []string{"mod"}, Usage: "Specify the Go module name to generate go.mod."}, 28 | &cli.StringFlag{Name: consts.OutDir, Usage: "Specify output directory, default is current dir."}, 29 | &cli.StringFlag{Name: consts.ModelDir, Usage: "Specify model output directory, default is biz/doc/model."}, 30 | &cli.StringFlag{Name: consts.DaoDir, Usage: "Specify dao output directory, default is biz/doc/dao."}, 31 | &cli.StringFlag{Name: consts.Name, Usage: "Specify specific doc name, default is mongodb."}, 32 | &cli.StringSliceFlag{Name: consts.ProtoSearchPath, Aliases: []string{"I"}, Usage: "Add an IDL search path for includes."}, 33 | &cli.StringSliceFlag{Name: consts.ThriftGo, Aliases: []string{"t"}, Usage: "Specify arguments for the thriftgo. ({flag}={value})"}, 34 | &cli.StringSliceFlag{Name: consts.Protoc, Aliases: []string{"p"}, Usage: "Specify arguments for the protoc. ({flag}={value})"}, 35 | &cli.BoolFlag{Name: consts.Verbose, Usage: "Turn on verbose mode, default is false."}, 36 | &cli.BoolFlag{Name: consts.GenBase, Usage: "Generate base mongo code, default is false."}, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /cmd/static/job_flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package static 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/consts" 21 | "github.com/urfave/cli/v2" 22 | ) 23 | 24 | func jobFlags() []cli.Flag { 25 | return []cli.Flag{ 26 | &cli.StringSliceFlag{Name: consts.JobName, Usage: "Specify the job name."}, 27 | &cli.StringFlag{Name: consts.Module, Aliases: []string{"mod"}, Usage: "Specify the Go module name to generate go.mod."}, 28 | &cli.StringFlag{Name: consts.OutDir, Usage: "Specify output directory, default is current dir."}, 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cmd/static/model_flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package static 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | 23 | "github.com/cloudwego/cwgo/config" 24 | "github.com/cloudwego/cwgo/pkg/consts" 25 | "github.com/urfave/cli/v2" 26 | ) 27 | 28 | func modelFlags() []cli.Flag { 29 | return []cli.Flag{ 30 | &cli.StringFlag{Name: consts.DSN, Usage: "Specify the database source name. (https://gorm.io/docs/connecting_to_the_database.html)", Value: "", DefaultText: "", Action: func(context *cli.Context, s string) error { 31 | if len(s) == 0 { 32 | return fmt.Errorf("dsn cannot be empty") 33 | } 34 | return nil 35 | }}, 36 | &cli.StringFlag{Name: consts.DBType, Usage: "Specify database type. (mysql or sqlserver or sqlite or postgres)", Value: string(consts.MySQL), DefaultText: string(consts.MySQL), Action: func(context *cli.Context, s string) error { 37 | if _, ok := config.OpenTypeFuncMap[consts.DataBaseType(strings.ToLower(s))]; !ok { 38 | return fmt.Errorf("unknow db type %s (support mysql || postgres || sqlite || sqlserver for now)", s) 39 | } 40 | return nil 41 | }}, 42 | &cli.StringFlag{Name: consts.OutDir, Usage: "Specify output directory", Value: consts.DefaultDbOutDir, DefaultText: consts.DefaultDbOutDir}, 43 | &cli.StringFlag{Name: consts.OutFile, Usage: "Specify output filename", Value: consts.DefaultDbOutFile, DefaultText: consts.DefaultDbOutFile}, 44 | &cli.StringSliceFlag{Name: consts.Tables, Usage: "Specify databases tables"}, 45 | &cli.StringSliceFlag{Name: consts.ExcludeTables, Usage: "Specify exclude tables"}, 46 | &cli.BoolFlag{Name: consts.UnitTest, Usage: "Specify generate unit test", Value: false, DefaultText: "false"}, 47 | &cli.BoolFlag{Name: consts.OnlyModel, Usage: "Specify only generate model code", Value: false, DefaultText: "false"}, 48 | &cli.StringFlag{Name: consts.ModelPkgName, Usage: "Specify model package name", Value: "", DefaultText: ""}, 49 | &cli.BoolFlag{Name: consts.Nullable, Usage: "Specify generate with pointer when field is nullable", Value: false, DefaultText: "false"}, 50 | &cli.BoolFlag{Name: consts.Signable, Usage: "Specify detect integer field's unsigned type, adjust generated data type", Value: false, DefaultText: "false"}, 51 | &cli.BoolFlag{Name: consts.TypeTag, Usage: "Specify generate field with gorm column type tag", Value: false, DefaultText: "false"}, 52 | &cli.BoolFlag{Name: consts.IndexTag, Usage: "Specify generate field with gorm index tag", Value: false, DefaultText: "false"}, 53 | &cli.StringFlag{Name: consts.SQLDir, Usage: "Specify a sql file or directory", Value: "", DefaultText: ""}, 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /cmd/static/server_flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package static 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/config" 21 | "github.com/cloudwego/cwgo/pkg/consts" 22 | "github.com/urfave/cli/v2" 23 | ) 24 | 25 | func serverFlags() []cli.Flag { 26 | globalArgs := config.GetGlobalArgs() 27 | return []cli.Flag{ 28 | &cli.StringFlag{Name: consts.Service, Usage: "Specify the server name.(Not recommended,Deprecate in v0.2.0)", Destination: &globalArgs.ServerArgument.ServerName}, 29 | &cli.StringFlag{Name: consts.ServerName, Usage: "Specify the server name.", Destination: &globalArgs.ServerArgument.ServerName}, 30 | &cli.StringFlag{Name: consts.ServiceType, Usage: "Specify the generate type. (RPC or HTTP)", Value: consts.RPC}, 31 | &cli.StringFlag{Name: consts.Module, Aliases: []string{"mod"}, Usage: "Specify the Go module name to generate go.mod.", Destination: &globalArgs.ServerArgument.GoMod}, 32 | &cli.StringFlag{Name: consts.IDLPath, Usage: "Specify the IDL file path. (.thrift or .proto)", Destination: &globalArgs.ServerArgument.IdlPath}, 33 | &cli.StringFlag{Name: consts.Template, Usage: "Specify the template path. Currently cwgo supports git templates, such as `--template https://github.com/***/cwgo_template.git`", Destination: &globalArgs.ServerArgument.Template}, 34 | &cli.StringFlag{Name: consts.Branch, Usage: "Specify the git template's branch, default is main branch.", Destination: &globalArgs.ServerArgument.Branch}, 35 | &cli.StringFlag{Name: consts.Registry, Usage: "Specify the registry, default is None."}, 36 | &cli.StringSliceFlag{Name: consts.ProtoSearchPath, Aliases: []string{"I"}, Usage: "Add an IDL search path for includes."}, 37 | &cli.StringSliceFlag{Name: consts.Pass, Usage: "Pass param to hz or Kitex."}, 38 | &cli.BoolFlag{Name: consts.Verbose, Usage: "Turn on verbose mode."}, 39 | &cli.BoolFlag{Name: consts.HexTag, Usage: "Add HTTP listen for Kitex.", Destination: &globalArgs.Hex}, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /config/api_list.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/consts" 21 | "github.com/urfave/cli/v2" 22 | ) 23 | 24 | type ApiArgument struct { 25 | ProjectPath string 26 | HertzRepoUrl string 27 | } 28 | 29 | func NewApiArgument() *ApiArgument { 30 | return &ApiArgument{} 31 | } 32 | 33 | func (c *ApiArgument) ParseCli(ctx *cli.Context) error { 34 | c.ProjectPath = ctx.String(consts.ProjectPath) 35 | c.HertzRepoUrl = ctx.String(consts.HertzRepoUrl) 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /config/argument.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/consts" 21 | "gorm.io/driver/mysql" 22 | "gorm.io/driver/postgres" 23 | "gorm.io/driver/sqlite" 24 | "gorm.io/driver/sqlserver" 25 | "gorm.io/gorm" 26 | ) 27 | 28 | var globalArgs = NewArgument() 29 | 30 | func GetGlobalArgs() *Argument { 31 | return globalArgs 32 | } 33 | 34 | type Argument struct { 35 | Verbose bool 36 | 37 | *ServerArgument 38 | *ClientArgument 39 | *ModelArgument 40 | *DocArgument 41 | *JobArgument 42 | *ApiArgument 43 | *FallbackArgument 44 | } 45 | 46 | func NewArgument() *Argument { 47 | return &Argument{ 48 | ServerArgument: NewServerArgument(), 49 | ClientArgument: NewClientArgument(), 50 | ModelArgument: NewModelArgument(), 51 | DocArgument: NewDocArgument(), 52 | JobArgument: NewJobArgument(), 53 | ApiArgument: NewApiArgument(), 54 | FallbackArgument: NewFallbackArgument(), 55 | } 56 | } 57 | 58 | type DialectorFunc func(string) gorm.Dialector 59 | 60 | var OpenTypeFuncMap = map[consts.DataBaseType]DialectorFunc{ 61 | consts.MySQL: mysql.Open, 62 | consts.SQLServer: sqlserver.Open, 63 | consts.Sqlite: sqlite.Open, 64 | consts.Postgres: postgres.Open, 65 | } 66 | -------------------------------------------------------------------------------- /config/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "strings" 21 | 22 | "github.com/cloudwego/cwgo/pkg/consts" 23 | "github.com/urfave/cli/v2" 24 | ) 25 | 26 | type ClientArgument struct { 27 | // Common Param 28 | *CommonParam 29 | 30 | SliceParam *SliceParam 31 | 32 | Verbose bool 33 | Template string 34 | Branch string 35 | Cwd string 36 | GoSrc string 37 | GoPkg string 38 | GoPath string 39 | } 40 | 41 | func NewClientArgument() *ClientArgument { 42 | return &ClientArgument{ 43 | SliceParam: &SliceParam{}, 44 | CommonParam: &CommonParam{}, 45 | } 46 | } 47 | 48 | func (c *ClientArgument) ParseCli(ctx *cli.Context) error { 49 | c.Type = strings.ToUpper(ctx.String(consts.ServiceType)) 50 | c.Registry = strings.ToUpper(ctx.String(consts.Registry)) 51 | c.Verbose = ctx.Bool(consts.Verbose) 52 | c.SliceParam.ProtoSearchPath = ctx.StringSlice(consts.ProtoSearchPath) 53 | c.SliceParam.Pass = ctx.StringSlice(consts.Pass) 54 | return nil 55 | } 56 | -------------------------------------------------------------------------------- /config/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | 23 | "github.com/cloudwego/cwgo/pkg/consts" 24 | "github.com/cloudwego/hertz/cmd/hz/util" 25 | "github.com/urfave/cli/v2" 26 | ) 27 | 28 | type DocArgument struct { 29 | GoMod string 30 | PackagePrefix string 31 | IdlPath string 32 | IdlType string 33 | OutDir string 34 | Name string 35 | ModelDir string 36 | DaoDir string 37 | Verbose bool 38 | ProtoSearchPath []string 39 | ProtocOptions []string // options to pass through to protoc 40 | ThriftOptions []string // options to pass through to thriftgo for go flag 41 | GenBase bool 42 | } 43 | 44 | func NewDocArgument() *DocArgument { 45 | return &DocArgument{} 46 | } 47 | 48 | func (d *DocArgument) ParseCli(ctx *cli.Context) error { 49 | d.IdlPath = ctx.String(consts.IDLPath) 50 | d.GoMod = ctx.String(consts.Module) 51 | d.OutDir = ctx.String(consts.OutDir) 52 | d.ModelDir = ctx.String(consts.ModelDir) 53 | d.DaoDir = ctx.String(consts.DaoDir) 54 | d.Name = ctx.String(consts.Name) 55 | d.Verbose = ctx.Bool(consts.Verbose) 56 | d.ProtoSearchPath = ctx.StringSlice(consts.ProtoSearchPath) 57 | d.ProtocOptions = ctx.StringSlice(consts.Protoc) 58 | d.ThriftOptions = ctx.StringSlice(consts.ThriftGo) 59 | d.GenBase = ctx.Bool(consts.GenBase) 60 | return nil 61 | } 62 | 63 | func (d *DocArgument) Unpack(data []string) error { 64 | err := util.UnpackArgs(data, d) 65 | if err != nil { 66 | return fmt.Errorf("unpack argument failed: %s", err) 67 | } 68 | return nil 69 | } 70 | 71 | func (d *DocArgument) Pack() ([]string, error) { 72 | data, err := util.PackArgs(d) 73 | if err != nil { 74 | return nil, fmt.Errorf("pack argument failed: %s", err) 75 | } 76 | return data, nil 77 | } 78 | 79 | func (d *DocArgument) GetThriftgoOptions(prefix string) (string, error) { 80 | d.ThriftOptions = append(d.ThriftOptions, "package_prefix="+prefix) 81 | gas := "go:" + strings.Join(d.ThriftOptions, ",") 82 | return gas, nil 83 | } 84 | -------------------------------------------------------------------------------- /config/fallback.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/cloudwego/cwgo/pkg/consts" 23 | "github.com/urfave/cli/v2" 24 | ) 25 | 26 | type FallbackArgument struct { 27 | ToolType consts.ToolType 28 | Args []string 29 | } 30 | 31 | func NewFallbackArgument() *FallbackArgument { 32 | return &FallbackArgument{} 33 | } 34 | 35 | func (c *FallbackArgument) ParseCli(ctx *cli.Context) error { 36 | args := ctx.Args().Slice() 37 | if len(args) < 1 { 38 | return fmt.Errorf("please input tool type") 39 | } 40 | 41 | c.ToolType = consts.ToolType(args[0]) 42 | switch consts.ToolType(args[0]) { 43 | case consts.Hz: 44 | c.ToolType = consts.Hz 45 | case consts.KitexTool: 46 | c.ToolType = consts.KitexTool 47 | default: 48 | return fmt.Errorf("tool type is not supported") 49 | } 50 | 51 | c.Args = args 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /config/job.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/consts" 21 | "github.com/urfave/cli/v2" 22 | ) 23 | 24 | type JobArgument struct { 25 | GoMod string 26 | PackagePrefix string 27 | JobName []string 28 | OutDir string 29 | } 30 | 31 | func NewJobArgument() *JobArgument { 32 | return &JobArgument{} 33 | } 34 | 35 | func (j *JobArgument) ParseCli(ctx *cli.Context) error { 36 | j.JobName = ctx.StringSlice(consts.JobName) 37 | j.GoMod = ctx.String(consts.Module) 38 | j.OutDir = ctx.String(consts.OutDir) 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /config/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "strings" 21 | 22 | "github.com/cloudwego/cwgo/pkg/consts" 23 | "github.com/urfave/cli/v2" 24 | ) 25 | 26 | type ModelArgument struct { 27 | DSN string 28 | Type string 29 | Tables []string 30 | ExcludeTables []string 31 | OnlyModel bool 32 | OutPath string 33 | OutFile string 34 | WithUnitTest bool 35 | ModelPkgName string 36 | FieldNullable bool 37 | FieldSignable bool 38 | FieldWithIndexTag bool 39 | FieldWithTypeTag bool 40 | SQLDir string 41 | } 42 | 43 | func NewModelArgument() *ModelArgument { 44 | return &ModelArgument{ 45 | OutPath: consts.DefaultDbOutDir, 46 | OutFile: consts.DefaultDbOutFile, 47 | } 48 | } 49 | 50 | func (c *ModelArgument) ParseCli(ctx *cli.Context) error { 51 | c.DSN = ctx.String(consts.DSN) 52 | c.Type = strings.ToLower(ctx.String(consts.DBType)) 53 | c.Tables = ctx.StringSlice(consts.Tables) 54 | c.ExcludeTables = ctx.StringSlice(consts.ExcludeTables) 55 | c.OnlyModel = ctx.Bool(consts.OnlyModel) 56 | c.OutPath = ctx.String(consts.OutDir) 57 | c.OutFile = ctx.String(consts.OutFile) 58 | c.WithUnitTest = ctx.Bool(consts.UnitTest) 59 | c.ModelPkgName = ctx.String(consts.ModelPkgName) 60 | c.FieldNullable = ctx.Bool(consts.Nullable) 61 | c.FieldSignable = ctx.Bool(consts.Signable) 62 | c.FieldWithIndexTag = ctx.Bool(consts.IndexTag) 63 | c.FieldWithTypeTag = ctx.Bool(consts.TypeTag) 64 | c.SQLDir = ctx.String(consts.SQLDir) 65 | return nil 66 | } 67 | -------------------------------------------------------------------------------- /config/server.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "strings" 21 | 22 | "github.com/cloudwego/cwgo/pkg/consts" 23 | "github.com/urfave/cli/v2" 24 | ) 25 | 26 | type ServerArgument struct { 27 | // Common Param 28 | *CommonParam 29 | 30 | Template string 31 | Branch string 32 | SliceParam *SliceParam 33 | Verbose bool 34 | Hex bool // add http listen for kitex 35 | 36 | Cwd string 37 | GoSrc string 38 | GoPkg string 39 | GoPath string 40 | } 41 | 42 | type CommonParam struct { 43 | ServerName string // server name 44 | Type string // GenerateType: RPC or HTTP 45 | GoMod string // Go Mod name 46 | IdlPath string 47 | OutDir string // output path 48 | Registry string 49 | } 50 | 51 | func NewServerArgument() *ServerArgument { 52 | return &ServerArgument{ 53 | SliceParam: &SliceParam{}, 54 | CommonParam: &CommonParam{}, 55 | } 56 | } 57 | 58 | func (s *ServerArgument) ParseCli(ctx *cli.Context) error { 59 | s.Type = strings.ToUpper(ctx.String(consts.ServiceType)) 60 | s.Registry = strings.ToUpper(ctx.String(consts.Registry)) 61 | s.Verbose = ctx.Bool(consts.Verbose) 62 | s.SliceParam.ProtoSearchPath = ctx.StringSlice(consts.ProtoSearchPath) 63 | s.SliceParam.Pass = ctx.StringSlice(consts.Pass) 64 | return nil 65 | } 66 | 67 | func (s *SliceParam) WriteAnswer(name string, value interface{}) error { 68 | if name == consts.Pass { 69 | s.Pass = strings.Split(value.(string), consts.BlackSpace) 70 | } 71 | if name == consts.ProtoSearchPath { 72 | s.ProtoSearchPath = strings.Split(value.(string), consts.BlackSpace) 73 | } 74 | return nil 75 | } 76 | 77 | type SliceParam struct { 78 | Pass []string 79 | ProtoSearchPath []string 80 | } 81 | -------------------------------------------------------------------------------- /cwgo.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package main 17 | 18 | import ( 19 | "os" 20 | 21 | "github.com/cloudwego/cwgo/pkg/curd/doc/mongo/plugin" 22 | 23 | "github.com/cloudwego/cwgo/cmd/static" 24 | "github.com/cloudwego/cwgo/tpl" 25 | "github.com/cloudwego/hertz/cmd/hz/app" 26 | "github.com/cloudwego/hertz/cmd/hz/util/logs" 27 | kargs "github.com/cloudwego/kitex/tool/cmd/kitex/args" 28 | "github.com/cloudwego/kitex/tool/internal_pkg/pluginmode/protoc" 29 | "github.com/cloudwego/kitex/tool/internal_pkg/pluginmode/thriftgo" 30 | ) 31 | 32 | func main() { 33 | tpl.RegisterTemplateFunc() 34 | 35 | // run cwgo as hz plugin mode 36 | app.PluginMode() 37 | // run cwgo as kitex plugin mode 38 | kitexPluginMode() 39 | // run cwgo as mongo plugin mode 40 | plugin.MongoPluginMode() 41 | 42 | tpl.Init() 43 | cli := static.Init() 44 | 45 | err := cli.Run(os.Args) 46 | if err != nil { 47 | logs.Errorf("%v\n", err) 48 | } 49 | } 50 | 51 | func kitexPluginMode() { 52 | mode := os.Getenv(kargs.EnvPluginMode) 53 | if len(os.Args) <= 1 && mode != "" { 54 | // run as a plugin 55 | switch mode { 56 | case thriftgo.PluginName: 57 | os.Exit(thriftgo.Run()) 58 | case protoc.PluginName: 59 | os.Exit(protoc.Run()) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cloudwego/cwgo 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/Masterminds/sprig/v3 v3.2.3 7 | github.com/cloudwego/hertz/cmd/hz v0.8.1 8 | github.com/cloudwego/kitex v0.9.1 9 | github.com/cloudwego/thriftgo v0.3.10 10 | github.com/fatih/camelcase v1.0.0 11 | github.com/stretchr/testify v1.8.4 12 | github.com/urfave/cli/v2 v2.27.1 13 | golang.org/x/tools v0.20.0 14 | gopkg.in/yaml.v3 v3.0.1 15 | gorm.io/driver/mysql v1.5.6 16 | gorm.io/driver/postgres v1.5.7 17 | gorm.io/driver/sqlite v1.5.5 18 | gorm.io/driver/sqlserver v1.5.3 19 | gorm.io/gen v0.3.26 20 | gorm.io/gorm v1.25.9 21 | gorm.io/rawsql v1.0.2 22 | ) 23 | 24 | require ( 25 | github.com/Masterminds/goutils v1.1.1 // indirect 26 | github.com/Masterminds/semver/v3 v3.2.0 // indirect 27 | github.com/apache/thrift v0.13.0 // indirect 28 | github.com/benbjohnson/clock v1.1.0 // indirect 29 | github.com/cloudwego/fastpb v0.0.4 // indirect 30 | github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect 31 | github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect 32 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 33 | github.com/dlclark/regexp2 v1.11.0 // indirect 34 | github.com/go-sql-driver/mysql v1.7.0 // indirect 35 | github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect 36 | github.com/golang-sql/sqlexp v0.1.0 // indirect 37 | github.com/golang/protobuf v1.5.3 // indirect 38 | github.com/google/go-cmp v0.6.0 // indirect 39 | github.com/google/uuid v1.4.0 // indirect 40 | github.com/hashicorp/go-version v1.5.0 // indirect 41 | github.com/huandu/xstrings v1.3.3 // indirect 42 | github.com/imdario/mergo v0.3.11 // indirect 43 | github.com/jackc/pgpassfile v1.0.0 // indirect 44 | github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect 45 | github.com/jackc/pgx/v5 v5.4.3 // indirect 46 | github.com/jhump/protoreflect v1.12.0 // indirect 47 | github.com/jinzhu/inflection v1.0.0 // indirect 48 | github.com/jinzhu/now v1.1.5 // indirect 49 | github.com/kr/text v0.2.0 // indirect 50 | github.com/mattn/go-sqlite3 v1.14.17 // indirect 51 | github.com/microsoft/go-mssqldb v1.6.0 // indirect 52 | github.com/mitchellh/copystructure v1.0.0 // indirect 53 | github.com/mitchellh/reflectwalk v1.0.0 // indirect 54 | github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect 55 | github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7 // indirect 56 | github.com/pingcap/tidb/parser v0.0.0-20230327100244-b67c0321c05a // indirect 57 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 58 | github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect 59 | github.com/rogpeppe/go-internal v1.8.1 // indirect 60 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 61 | github.com/shopspring/decimal v1.2.0 // indirect 62 | github.com/spf13/cast v1.3.1 // indirect 63 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect 64 | go.uber.org/atomic v1.7.0 // indirect 65 | go.uber.org/multierr v1.6.0 // indirect 66 | go.uber.org/zap v1.24.0 // indirect 67 | golang.org/x/crypto v0.18.0 // indirect 68 | golang.org/x/exp v0.0.0-20220428152302-39d4317da171 // indirect 69 | golang.org/x/mod v0.17.0 // indirect 70 | golang.org/x/sync v0.7.0 // indirect 71 | golang.org/x/text v0.14.0 // indirect 72 | google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect 73 | google.golang.org/grpc v1.55.0-dev // indirect 74 | google.golang.org/protobuf v1.28.1 // indirect 75 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect 76 | gopkg.in/yaml.v2 v2.4.0 // indirect 77 | gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect 78 | gorm.io/hints v1.1.0 // indirect 79 | gorm.io/plugin/dbresolver v1.5.0 // indirect 80 | ) 81 | -------------------------------------------------------------------------------- /hack/resolve-modules.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This is used by the linter action. 4 | # Recursively finds all directories with a go.mod file and creates 5 | # a GitHub Actions JSON output option. 6 | 7 | set -o errexit 8 | 9 | HOME=$( 10 | cd "$(dirname "${BASH_SOURCE[0]}")" && 11 | cd .. && 12 | pwd 13 | ) 14 | 15 | source "${HOME}/hack/util.sh" 16 | all_modules=$(util::find_modules) 17 | PATHS="" 18 | for mod in $all_modules; do 19 | PATHS+=$(printf '{"workdir":"%s"},' ${mod}) 20 | done 21 | 22 | echo "::set-output name=matrix::{\"include\":[${PATHS%?}]}" -------------------------------------------------------------------------------- /hack/tools.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | set -o pipefail 6 | 7 | HOME=$( 8 | cd "$(dirname "${BASH_SOURCE[0]}")" && 9 | cd .. && 10 | pwd 11 | ) 12 | 13 | source "${HOME}/hack/util.sh" 14 | 15 | all_modules=$(util::find_modules) 16 | 17 | # test all mod 18 | function test() { 19 | for mod in $all_modules; do 20 | pushd "$mod" >/dev/null && 21 | echo "go test $(sed -n 1p go.mod | cut -d ' ' -f2)" && 22 | go test -race -covermode=atomic -coverprofile=coverage.out ./... 23 | popd >/dev/null || exit 24 | done 25 | } 26 | 27 | # vet all mod 28 | function vet() { 29 | for mod in $all_modules; do 30 | pushd "$mod" >/dev/null && 31 | echo "go vet $(sed -n 1p go.mod | cut -d ' ' -f2)" && 32 | go vet -stdmethods=false ./... 33 | popd >/dev/null || exit 34 | done 35 | } 36 | 37 | function help() { 38 | echo "use: test,vet" 39 | } 40 | 41 | case $1 in 42 | vet) 43 | vet 44 | ;; 45 | test) 46 | test 47 | ;; 48 | *) 49 | help 50 | ;; 51 | esac 52 | -------------------------------------------------------------------------------- /hack/util.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # find all go mod path 4 | # returns an array contains mod path 5 | function util::find_modules() { 6 | find . -not \( \ 7 | \( \ 8 | -path './output' \ 9 | -o -path './.git' \ 10 | -o -path '*/third_party/*' \ 11 | -o -path '*/vendor/*' \ 12 | -o -path '*/example/*' \ 13 | -o -path '*/tests/*' \ 14 | \) -prune \ 15 | \) -name 'go.mod' -print0 | xargs -0 -I {} dirname {} 16 | } -------------------------------------------------------------------------------- /images/lark_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudwego/cwgo/06a2cf1ac0dd4280dddb7354b255012f311dcf59/images/lark_group.png -------------------------------------------------------------------------------- /images/lark_group_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudwego/cwgo/06a2cf1ac0dd4280dddb7354b255012f311dcf59/images/lark_group_cn.png -------------------------------------------------------------------------------- /licenses/LICENSE-sprig.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2020 Masterminds 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-camelcase.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Fatih Arslan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-cli.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 urfave/cli maintainers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-gen.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021-NOW Jinzhu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-gorm.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-NOW Jinzhu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-mysql.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-NOW Jinzhu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-postgres.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-NOW Jinzhu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-repogen.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Surawich Laprattanatrai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-retry-go.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Avast 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /licenses/License-sqlite.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-NOW Jinzhu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-sqlserver.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-NOW Jinzhu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-survey.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alec Aivazis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /licenses/License-yaml2go.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Prasad Ghangal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /meta/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package meta 18 | 19 | const ( 20 | Name = "cwgo" 21 | Version = "v0.1.2" 22 | ) 23 | -------------------------------------------------------------------------------- /pkg/api_list/api_list.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package api_list 18 | 19 | import ( 20 | "fmt" 21 | "path/filepath" 22 | 23 | "github.com/cloudwego/cwgo/config" 24 | "github.com/cloudwego/cwgo/pkg/consts" 25 | ) 26 | 27 | func Api(c *config.ApiArgument) error { 28 | if c.ProjectPath == "" { 29 | curPath, err := filepath.Abs(".") 30 | if err != nil { 31 | return fmt.Errorf("get current path failed, err: %v", err) 32 | } 33 | c.ProjectPath = curPath 34 | } 35 | 36 | if c.HertzRepoUrl == "" { 37 | c.HertzRepoUrl = consts.HertzRepoDefaultUrl 38 | } 39 | 40 | parser, err := NewParser(c.ProjectPath, c.HertzRepoUrl) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | moduleName, err := getModuleName(c.ProjectPath) 46 | if err != nil { 47 | return err 48 | } 49 | 50 | fmt.Printf("found module name: %s\n", parser.moduleName) 51 | 52 | err = parser.searchFunc(moduleName, "main", make(map[string]*Var), nil) 53 | if err != nil { 54 | return err 55 | } 56 | 57 | parser.PrintRouters() 58 | 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /pkg/api_list/consts.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package api_list 18 | 19 | type VarType int 20 | 21 | const ( 22 | VarTypeOther = iota 23 | VarTypeServerHertz 24 | VarTypeRouteEngine 25 | VarTypeRouterGroup 26 | ) 27 | 28 | const ( 29 | RouterRegisterFuncNameGET = "GET" 30 | RouterRegisterFuncNamePOST = "POST" 31 | RouterRegisterFuncNamePUT = "PUT" 32 | RouterRegisterFuncNameDELETE = "DELETE" 33 | RouterRegisterFuncNameHEAD = "HEAD" 34 | RouterRegisterFuncNamePATCH = "PATCH" 35 | RouterRegisterFuncNameOPTIONS = "OPTIONS" 36 | 37 | RouterRegisterFuncNameGETEX = "GETEX" 38 | RouterRegisterFuncNamePOSTEX = "POSTEX" 39 | RouterRegisterFuncNamePUTEX = "PUTEX" 40 | RouterRegisterFuncNameDELETEEX = "DELETEEX" 41 | RouterRegisterFuncNameHEADEX = "HEADEX" 42 | RouterRegisterFuncNameAnyEX = "AnyEX" 43 | ) 44 | 45 | const ( 46 | BuiltinFuncNameAppend = "append" 47 | BuiltinFuncNameCopy = "copy" 48 | BuiltinFuncNameDelete = "delete" 49 | BuiltinFuncNameLen = "len" 50 | BuiltinFuncNameCap = "cap" 51 | BuiltinFuncNameMake = "make" 52 | BuiltinFuncNameNew = "new" 53 | BuiltinFuncNameComplex = "complex" 54 | BuiltinFuncNameReal = "real" 55 | BuiltinFuncNameImag = "imag" 56 | BuiltinFuncNameClear = "clear" 57 | BuiltinFuncNameClose = "close" 58 | BuiltinFuncNamePanic = "panic" 59 | BuiltinFuncNameRecover = "recover" 60 | BuiltinFuncNamePrint = "print" 61 | BuiltinFuncNamePrintln = "println" 62 | ) 63 | 64 | var ( 65 | HertzFuncAssignmentFuncOfCoreMap = map[string]struct{}{ 66 | "Default": {}, 67 | "New": {}, 68 | } 69 | 70 | RouterFuncNameMap = map[string]struct{}{ 71 | RouterRegisterFuncNameGET: {}, 72 | RouterRegisterFuncNamePOST: {}, 73 | RouterRegisterFuncNamePUT: {}, 74 | RouterRegisterFuncNameDELETE: {}, 75 | RouterRegisterFuncNameHEAD: {}, 76 | RouterRegisterFuncNamePATCH: {}, 77 | RouterRegisterFuncNameOPTIONS: {}, 78 | RouterRegisterFuncNameGETEX: {}, 79 | RouterRegisterFuncNamePOSTEX: {}, 80 | RouterRegisterFuncNamePUTEX: {}, 81 | RouterRegisterFuncNameDELETEEX: {}, 82 | RouterRegisterFuncNameHEADEX: {}, 83 | RouterRegisterFuncNameAnyEX: {}, 84 | } 85 | 86 | BuiltinFuncNameMap = map[string]struct{}{ 87 | BuiltinFuncNameAppend: {}, 88 | BuiltinFuncNameCopy: {}, 89 | BuiltinFuncNameDelete: {}, 90 | BuiltinFuncNameLen: {}, 91 | BuiltinFuncNameCap: {}, 92 | BuiltinFuncNameMake: {}, 93 | BuiltinFuncNameNew: {}, 94 | BuiltinFuncNameComplex: {}, 95 | BuiltinFuncNameReal: {}, 96 | BuiltinFuncNameImag: {}, 97 | BuiltinFuncNameClear: {}, 98 | BuiltinFuncNameClose: {}, 99 | BuiltinFuncNamePanic: {}, 100 | BuiltinFuncNameRecover: {}, 101 | BuiltinFuncNamePrint: {}, 102 | BuiltinFuncNamePrintln: {}, 103 | } 104 | ) 105 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/biz/router/hello/example/hello.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Code generated by hertz generator. DO NOT EDIT. 18 | 19 | package example 20 | 21 | import ( 22 | "github.com/cloudwego/hertz/pkg/app/server" 23 | ) 24 | 25 | /* 26 | This file will register all the routes of the services in the master idl. 27 | And it will update automatically when you use the "update" command for the idl. 28 | So don't modify the contents of the file, or your code will be deleted when it is updated. 29 | */ 30 | 31 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 32 | func Register(r *server.Hertz) { 33 | root := r.Group("/", nil) 34 | root.GET("/hello", nil) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/biz/router/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Code generated by hertz generator. DO NOT EDIT. 18 | 19 | package router 20 | 21 | import ( 22 | hello_example "example.com/m/biz/router/hello/example" 23 | "github.com/cloudwego/hertz/pkg/app/server" 24 | ) 25 | 26 | // GeneratedRegister registers routers generated by IDL. 27 | func GeneratedRegister(r *server.Hertz) { 28 | //INSERT_POINT: DO NOT DELETE THIS LINE! 29 | hello_example.Register(r) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/go.mod: -------------------------------------------------------------------------------- 1 | module example.com/m 2 | 3 | go 1.18 4 | 5 | replace github.com/apache/thrift => github.com/apache/thrift v0.13.0 6 | 7 | require ( 8 | github.com/apache/thrift v0.0.0-00010101000000-000000000000 9 | github.com/cloudwego/hertz v0.8.1 10 | ) 11 | 12 | require ( 13 | github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect 14 | github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 // indirect 15 | github.com/bytedance/sonic v1.8.1 // indirect 16 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 17 | github.com/cloudwego/netpoll v0.5.0 // indirect 18 | github.com/fsnotify/fsnotify v1.5.4 // indirect 19 | github.com/golang/protobuf v1.5.0 // indirect 20 | github.com/henrylee2cn/ameda v1.4.10 // indirect 21 | github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect 22 | github.com/klauspost/cpuid/v2 v2.0.9 // indirect 23 | github.com/nyaruka/phonenumbers v1.0.55 // indirect 24 | github.com/tidwall/gjson v1.14.4 // indirect 25 | github.com/tidwall/match v1.1.1 // indirect 26 | github.com/tidwall/pretty v1.2.0 // indirect 27 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 28 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect 29 | golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect 30 | google.golang.org/protobuf v1.27.1 // indirect 31 | ) 32 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/hello.thrift: -------------------------------------------------------------------------------- 1 | // idl/hello.thrift 2 | namespace go hello.example 3 | 4 | struct HelloReq { 5 | 1: string Name (api.query="name"); // 添加 api 注解为方便进行参数绑定 6 | } 7 | 8 | struct HelloResp { 9 | 1: string RespBody; 10 | } 11 | 12 | 13 | service HelloService { 14 | HelloResp HelloMethod(1: HelloReq request) (api.get="/hello"); 15 | } -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Code generated by hertz generator. 18 | 19 | package main 20 | 21 | import ( 22 | "github.com/cloudwego/hertz/pkg/app/server" 23 | ) 24 | 25 | func main() { 26 | h := server.Default() 27 | 28 | register(h) 29 | h.Spin() 30 | } 31 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/router.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Code generated by hertz generator. 18 | 19 | package main 20 | 21 | import ( 22 | "github.com/cloudwego/hertz/pkg/app/server" 23 | ) 24 | 25 | // customizeRegister registers customize routers. 26 | func customizedRegister(r *server.Hertz) { 27 | r.GET("/ping", nil) 28 | 29 | // your code ... 30 | } 31 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case1/router_gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Code generated by hertz generator. DO NOT EDIT. 18 | 19 | package main 20 | 21 | import ( 22 | router "example.com/m/biz/router" 23 | "github.com/cloudwego/hertz/pkg/app/server" 24 | ) 25 | 26 | // register registers all routers. 27 | func register(r *server.Hertz) { 28 | 29 | router.GeneratedRegister(r) 30 | 31 | customizedRegister(r) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case2/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.18 4 | 5 | require github.com/cloudwego/hertz v0.8.1 6 | 7 | require ( 8 | github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect 9 | github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 // indirect 10 | github.com/bytedance/sonic v1.8.1 // indirect 11 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 12 | github.com/cloudwego/netpoll v0.5.0 // indirect 13 | github.com/fsnotify/fsnotify v1.5.4 // indirect 14 | github.com/golang/protobuf v1.5.0 // indirect 15 | github.com/henrylee2cn/ameda v1.4.10 // indirect 16 | github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect 17 | github.com/klauspost/cpuid/v2 v2.0.9 // indirect 18 | github.com/nyaruka/phonenumbers v1.0.55 // indirect 19 | github.com/tidwall/gjson v1.14.4 // indirect 20 | github.com/tidwall/match v1.1.1 // indirect 21 | github.com/tidwall/pretty v1.2.0 // indirect 22 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 23 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect 24 | golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect 25 | google.golang.org/protobuf v1.27.1 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case2/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import "github.com/cloudwego/hertz/pkg/app/server" 20 | 21 | func main() { 22 | h := server.Default() 23 | h.GET("/server/get", nil) 24 | h.POST("/server/post", nil) 25 | h.PUT("/server/put", nil) 26 | h.DELETE("/server/delete", nil) 27 | h.HEAD("/server/head", nil) 28 | h.PATCH("/server/patch", nil) 29 | h.OPTIONS("/server/options", nil) 30 | h.GETEX("/server/getex", nil, "") 31 | h.POSTEX("/server/postex", nil, "") 32 | h.PUTEX("/server/putex", nil, "") 33 | h.DELETEEX("/server/deleteex", nil, "") 34 | h.HEADEX("/server/headex", nil, "") 35 | h.AnyEX("/server/anyex", nil, "") 36 | 37 | e := h.Engine 38 | e.GET("/engine/get", nil) 39 | 40 | g1 := h.Group("/g1") 41 | g1.GET("/get", nil) 42 | 43 | g2 := e.Group("/g2") 44 | g2.GET("/get", nil) 45 | 46 | g3 := h.Group("/g3") 47 | g31 := g3.Group("/g1") 48 | g31.GET("/get", nil) 49 | 50 | g31.POST( 51 | "/post", 52 | nil, 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case3/go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.18 4 | 5 | require github.com/cloudwego/hertz v0.8.1 6 | 7 | require ( 8 | github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect 9 | github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 // indirect 10 | github.com/bytedance/sonic v1.8.1 // indirect 11 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 12 | github.com/cloudwego/netpoll v0.5.0 // indirect 13 | github.com/fsnotify/fsnotify v1.5.4 // indirect 14 | github.com/golang/protobuf v1.5.0 // indirect 15 | github.com/henrylee2cn/ameda v1.4.10 // indirect 16 | github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect 17 | github.com/klauspost/cpuid/v2 v2.0.9 // indirect 18 | github.com/nyaruka/phonenumbers v1.0.55 // indirect 19 | github.com/tidwall/gjson v1.14.4 // indirect 20 | github.com/tidwall/match v1.1.1 // indirect 21 | github.com/tidwall/pretty v1.2.0 // indirect 22 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 23 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect 24 | golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect 25 | google.golang.org/protobuf v1.27.1 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case3/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "main/router" 21 | 22 | "github.com/cloudwego/hertz/pkg/app/server" 23 | ) 24 | 25 | func main() { 26 | h := server.Default() 27 | 28 | router.InitRoutes(h.Engine) 29 | } 30 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case3/router/router.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package router 18 | 19 | import ( 20 | "main/router/user" 21 | 22 | "github.com/cloudwego/hertz/pkg/route" 23 | ) 24 | 25 | func InitRoutes(e *route.Engine) { 26 | e.GET("/ping", nil) 27 | 28 | g := e.Group("/api/v1") 29 | 30 | initDefault(g) 31 | user.InitUserRoutes(g.Group("/user")) 32 | } 33 | 34 | func initDefault(g *route.RouterGroup) { 35 | g.GET("/help", nil) 36 | } 37 | -------------------------------------------------------------------------------- /pkg/api_list/internal/tests/case3/router/user/user.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package user 18 | 19 | import "github.com/cloudwego/hertz/pkg/route" 20 | 21 | func InitUserRoutes(g *route.RouterGroup) { 22 | g.GET("/info", nil) 23 | g.POST("/nickname", nil) 24 | } 25 | -------------------------------------------------------------------------------- /pkg/api_list/module.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package api_list 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/cloudwego/cwgo/pkg/common/utils" 23 | ) 24 | 25 | func getModuleName(path string) (string, error) { 26 | module, _, ok := utils.SearchGoMod(path, false) 27 | if !ok { 28 | return "", fmt.Errorf("path: %s not found go.mod", path) 29 | } 30 | 31 | return module, nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/client/check.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "os" 23 | "path/filepath" 24 | "strings" 25 | 26 | "github.com/cloudwego/cwgo/config" 27 | "github.com/cloudwego/cwgo/pkg/common/utils" 28 | "github.com/cloudwego/cwgo/pkg/consts" 29 | ) 30 | 31 | func check(ca *config.ClientArgument) error { 32 | if ca.Type != consts.RPC && ca.Type != consts.HTTP { 33 | return errors.New("generate type not supported") 34 | } 35 | 36 | if ca.Registry != "" && 37 | ca.Registry != consts.Zk && 38 | ca.Registry != consts.Nacos && 39 | ca.Registry != consts.Etcd && 40 | ca.Registry != consts.Polaris { 41 | return errors.New("unsupported registry") 42 | } 43 | 44 | if ca.ServerName == "" { 45 | return errors.New("must specify server name") 46 | } 47 | 48 | // handle cwd and output dir 49 | dir, err := os.Getwd() 50 | if err != nil { 51 | return fmt.Errorf("get current path failed: %s", err) 52 | } 53 | ca.Cwd = dir 54 | if ca.OutDir == "" { 55 | if strings.ToUpper(ca.Type) == consts.HTTP { 56 | ca.OutDir = consts.DefaultHZClientDir 57 | } else { 58 | ca.OutDir = dir 59 | } 60 | } 61 | if !filepath.IsAbs(ca.OutDir) { 62 | ap := filepath.Join(ca.Cwd, ca.OutDir) 63 | ca.OutDir = ap 64 | } 65 | 66 | gopath, err := utils.GetGOPATH() 67 | if err != nil { 68 | return fmt.Errorf("get gopath failed: %s", err) 69 | } 70 | if gopath == "" { 71 | return fmt.Errorf("GOPATH is not set") 72 | } 73 | 74 | ca.GoPath = gopath 75 | ca.GoSrc = filepath.Join(gopath, consts.Src) 76 | 77 | // Generate the project under gopath, use the relative path as the package name 78 | if strings.HasPrefix(ca.Cwd, ca.GoSrc) { 79 | if goPkg, err := filepath.Rel(ca.GoSrc, ca.Cwd); err != nil { 80 | return fmt.Errorf("get relative path to GOPATH/src failed: %s", err) 81 | } else { 82 | ca.GoPkg = goPkg 83 | } 84 | 85 | if ca.GoMod == "" { 86 | if utils.IsWindows() { 87 | ca.GoMod = strings.ReplaceAll(ca.GoPkg, consts.BackSlash, consts.Slash) 88 | } else { 89 | ca.GoMod = ca.GoPkg 90 | } 91 | } 92 | 93 | if ca.GoMod != "" { 94 | if utils.IsWindows() { 95 | goPkgSlash := strings.ReplaceAll(ca.GoPkg, consts.BackSlash, consts.Slash) 96 | if goPkgSlash != ca.GoMod { 97 | return fmt.Errorf("module name: %s is not the same with GoPkg under GoPath: %s", ca.GoMod, goPkgSlash) 98 | } 99 | } else { 100 | if ca.GoMod != ca.GoPkg { 101 | return fmt.Errorf("module name: %s is not the same with GoPkg under GoPath: %s", ca.GoMod, ca.GoPkg) 102 | } 103 | } 104 | } 105 | } 106 | return nil 107 | } 108 | -------------------------------------------------------------------------------- /pkg/client/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "bytes" 21 | "os" 22 | "strings" 23 | 24 | "github.com/cloudwego/cwgo/pkg/common/kx_registry" 25 | "github.com/cloudwego/cwgo/pkg/consts" 26 | 27 | "github.com/cloudwego/cwgo/pkg/common/utils" 28 | kargs "github.com/cloudwego/kitex/tool/cmd/kitex/args" 29 | "github.com/cloudwego/kitex/tool/internal_pkg/log" 30 | "github.com/cloudwego/kitex/tool/internal_pkg/pluginmode/thriftgo" 31 | 32 | "github.com/cloudwego/hertz/cmd/hz/app" 33 | 34 | "github.com/cloudwego/cwgo/config" 35 | 36 | hzConfig "github.com/cloudwego/hertz/cmd/hz/config" 37 | "github.com/cloudwego/hertz/cmd/hz/meta" 38 | "github.com/cloudwego/hertz/cmd/hz/util/logs" 39 | "github.com/urfave/cli/v2" 40 | ) 41 | 42 | func Client(c *config.ClientArgument) error { 43 | var err error 44 | err = check(c) 45 | if err != nil { 46 | return err 47 | } 48 | switch c.Type { 49 | case consts.RPC: 50 | var args kargs.Arguments 51 | log.Verbose = c.Verbose 52 | err = convertKitexArgs(c, &args) 53 | if err != nil { 54 | return err 55 | } 56 | 57 | kx_registry.HandleRegistry(c.CommonParam, args.TemplateDir) 58 | defer kx_registry.RemoveExtension() 59 | 60 | out := new(bytes.Buffer) 61 | cmd := args.BuildCmd(out) 62 | err = cmd.Run() 63 | if err != nil { 64 | if args.Use != "" { 65 | out := strings.TrimSpace(out.String()) 66 | if strings.HasSuffix(out, thriftgo.TheUseOptionMessage) { 67 | utils.ReplaceThriftVersion() 68 | } 69 | } 70 | os.Exit(1) 71 | } 72 | utils.ReplaceThriftVersion() 73 | utils.UpgradeGolangProtobuf() 74 | utils.Hessian2PostProcessing(args) 75 | case consts.HTTP: 76 | args := hzConfig.NewArgument() 77 | utils.SetHzVerboseLog(c.Verbose) 78 | err = convertHzArgument(c, args) 79 | if err != nil { 80 | return err 81 | } 82 | args.CmdType = meta.CmdClient 83 | logs.Debugf("Args: %#v\n", args) 84 | err = app.TriggerPlugin(args) 85 | if err != nil { 86 | return cli.Exit(err, meta.PluginError) 87 | } 88 | } 89 | return nil 90 | } 91 | -------------------------------------------------------------------------------- /pkg/client/hz.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "flag" 21 | "fmt" 22 | "path" 23 | "path/filepath" 24 | "strings" 25 | 26 | "github.com/cloudwego/cwgo/config" 27 | "github.com/cloudwego/cwgo/pkg/common/utils" 28 | "github.com/cloudwego/cwgo/pkg/consts" 29 | "github.com/cloudwego/cwgo/tpl" 30 | hzConfig "github.com/cloudwego/hertz/cmd/hz/config" 31 | ) 32 | 33 | func convertHzArgument(ca *config.ClientArgument, hzArgument *hzConfig.Argument) (err error) { 34 | // Common commands 35 | abPath, err := filepath.Abs(ca.IdlPath) 36 | if err != nil { 37 | return fmt.Errorf("idl path %s is not absolute", ca.IdlPath) 38 | } 39 | 40 | if strings.HasSuffix(ca.Template, consts.SuffixGit) { 41 | err = utils.GitClone(ca.Template, path.Join(tpl.HertzDir, consts.Client)) 42 | if err != nil { 43 | return err 44 | } 45 | gitPath, err := utils.GitPath(ca.Template) 46 | if err != nil { 47 | return err 48 | } 49 | gitPath = path.Join(tpl.HertzDir, consts.Client, gitPath) 50 | if err = utils.GitCheckout(ca.Branch, gitPath); err != nil { 51 | return err 52 | } 53 | hzArgument.CustomizePackage = path.Join(gitPath, consts.PackageLayoutFile) 54 | } else { 55 | if len(ca.Template) != 0 { 56 | hzArgument.CustomizePackage = path.Join(ca.Template, consts.PackageLayoutFile) 57 | } else { 58 | hzArgument.CustomizePackage = path.Join(tpl.HertzDir, consts.Client, consts.Standard, consts.PackageLayoutFile) 59 | } 60 | } 61 | 62 | hzArgument.IdlPaths = []string{abPath} 63 | hzArgument.Gomod = ca.GoMod 64 | hzArgument.ServiceName = ca.ServerName 65 | hzArgument.Includes = ca.SliceParam.ProtoSearchPath 66 | hzArgument.Cwd = ca.Cwd 67 | hzArgument.Gosrc = ca.GoSrc 68 | hzArgument.Gopkg = ca.GoPkg 69 | hzArgument.Gopath = ca.GoPath 70 | hzArgument.Verbose = ca.Verbose 71 | hzArgument.OutDir = ca.Cwd 72 | // Automatic judgment param 73 | hzArgument.IdlType, err = utils.GetIdlType(abPath) 74 | if err != nil { 75 | return 76 | } 77 | 78 | // specific commands from -pass param 79 | f := flag.NewFlagSet("", flag.ContinueOnError) 80 | f.StringVar(&hzArgument.HandlerDir, "handler_dir", "", "") 81 | f.StringVar(&hzArgument.ModelDir, "model_dir", consts.DefaultHZModelDir, "") 82 | f.StringVar(&hzArgument.ClientDir, "client_dir", ca.OutDir, "") 83 | f.StringVar(&hzArgument.Use, "use", "", "") 84 | f.StringVar(&hzArgument.BaseDomain, "base_domain", "", "") 85 | var excludeFile, thriftgo, protoc, thriftPlugins, protocPlugins utils.FlagStringSlice 86 | f.Var(&excludeFile, "exclude_file", "") 87 | f.Var(&thriftgo, "thriftgo", "") 88 | f.Var(&protoc, "protoc", "") 89 | f.Var(&thriftPlugins, "thrift-plugins", "") 90 | f.Var(&protocPlugins, "protoc-plugins", "") 91 | f.BoolVar(&hzArgument.NoRecurse, "no_recurse", false, "") 92 | f.BoolVar(&hzArgument.JSONEnumStr, "json_enumstr", false, "") 93 | f.BoolVar(&hzArgument.UnsetOmitempty, "unset_omitempty", false, "") 94 | f.BoolVar(&hzArgument.ProtobufCamelJSONTag, "pb_camel_json_tag", false, "") 95 | f.BoolVar(&hzArgument.SnakeName, "snake_tag", false, "") 96 | f.BoolVar(&hzArgument.HandlerByMethod, "handler_by_method", false, "") 97 | 98 | err = f.Parse(utils.StringSliceSpilt(ca.SliceParam.Pass)) 99 | if err != nil { 100 | return err 101 | } 102 | hzArgument.Excludes = excludeFile 103 | hzArgument.ThriftOptions = thriftgo 104 | hzArgument.ProtocOptions = protoc 105 | hzArgument.ThriftPlugins = thriftPlugins 106 | hzArgument.ProtobufPlugins = protocPlugins 107 | return nil 108 | } 109 | -------------------------------------------------------------------------------- /pkg/common/parser/consts.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2023 CloudWeGo Authors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package parser 20 | 21 | // Regular expression capture 22 | const ( 23 | includePattern = `include\s*"([^"]+)"` 24 | importPattern = `import\s+"([^"]+)"` 25 | ) 26 | -------------------------------------------------------------------------------- /pkg/common/parser/proto.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2023 CloudWeGo Authors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package parser 20 | 21 | import ( 22 | "os" 23 | "path/filepath" 24 | "regexp" 25 | 26 | "github.com/cloudwego/cwgo/pkg/common/utils" 27 | ) 28 | 29 | type ProtoParser struct { 30 | reg *regexp.Regexp 31 | } 32 | 33 | func NewProtoParser() *ProtoParser { 34 | return &ProtoParser{ 35 | reg: regexp.MustCompile(importPattern), 36 | } 37 | } 38 | 39 | func (p *ProtoParser) GetDependentFilePaths(baseDirPath, mainIdlPath string) (string, []string, error) { 40 | // create maps to keep track of processed and related paths 41 | processedPaths := make(map[string]bool) 42 | relatedPaths := make(map[string]bool) 43 | var resultPaths []string 44 | 45 | var importBaseDirPath string 46 | 47 | // define a function to process each file recursively 48 | var processFile func(filePath string) error 49 | processFile = func(filePath string) error { 50 | // if the file has already been processed, skip it 51 | if processedPaths[filePath] { 52 | return nil 53 | } 54 | 55 | // read the content of the Thrift file 56 | protoContent, err := os.ReadFile(filePath) 57 | if err != nil { 58 | return err 59 | } 60 | 61 | // find all import statements in the Thrift file 62 | matches := p.reg.FindAllStringSubmatch(string(protoContent), -1) 63 | var includePaths []string 64 | 65 | // extract the paths from the import statements 66 | for _, match := range matches { 67 | if len(match) >= 2 { 68 | includePath := match[1] 69 | // obtain the fields in the import here and process them 70 | if importBaseDirPath == "" { 71 | importBaseDirPath = utils.FindRootPath(filePath, includePath) 72 | if importBaseDirPath == "" { 73 | continue 74 | } 75 | } 76 | 77 | absolutePath := filepath.Clean(filepath.Join(importBaseDirPath, includePath)) 78 | _, err := os.Stat(absolutePath) 79 | if err != nil { 80 | continue 81 | } 82 | includePaths = append(includePaths, absolutePath) 83 | } 84 | } 85 | 86 | // mark the current file as processed 87 | processedPaths[filePath] = true 88 | 89 | // recursively process the included files 90 | for _, includePath := range includePaths { 91 | if !relatedPaths[includePath] { 92 | relatedPaths[includePath] = true 93 | resultPaths = append(resultPaths, includePath) 94 | err := processFile(includePath) 95 | if err != nil { 96 | return err 97 | } 98 | } 99 | } 100 | 101 | return nil 102 | } 103 | 104 | // start the recursive processing with the main IDL file 105 | mainAbsPath := filepath.Join(baseDirPath, mainIdlPath) 106 | err := processFile(mainAbsPath) 107 | if err != nil { 108 | return "", nil, err 109 | } 110 | 111 | // calculate the relative paths to the base dir path 112 | relativePaths := make([]string, len(resultPaths)) 113 | for i, path := range resultPaths { 114 | relativePath, _ := filepath.Rel(importBaseDirPath, path) 115 | relativePaths[i] = filepath.ToSlash(relativePath) 116 | } 117 | 118 | rel, err := filepath.Rel(baseDirPath, importBaseDirPath) 119 | if err != nil { 120 | return "", nil, err 121 | } 122 | 123 | return rel, relativePaths, nil 124 | } 125 | -------------------------------------------------------------------------------- /pkg/common/utils/file.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "os" 23 | "path/filepath" 24 | 25 | "github.com/cloudwego/hertz/cmd/hz/meta" 26 | ) 27 | 28 | // PathExist is used to judge whether the path exists in file system. 29 | func PathExist(path string) (bool, error) { 30 | abPath, err := filepath.Abs(path) 31 | if err != nil { 32 | return false, err 33 | } 34 | _, err = os.Stat(abPath) 35 | if err != nil { 36 | return os.IsExist(err), nil 37 | } 38 | return true, nil 39 | } 40 | 41 | // GetIdlType is used to return the idl type. 42 | func GetIdlType(path string, pbName ...string) (string, error) { 43 | ext := filepath.Ext(path) 44 | if ext == "" || ext[0] != '.' { 45 | return "", fmt.Errorf("idl path %s is not a valid file", path) 46 | } 47 | ext = ext[1:] 48 | switch ext { 49 | case meta.IdlThrift: 50 | return meta.IdlThrift, nil 51 | case meta.IdlProto: 52 | if len(pbName) > 0 { 53 | return pbName[0], nil 54 | } 55 | return meta.IdlProto, nil 56 | default: 57 | return "", fmt.Errorf("IDL type %s is not supported", ext) 58 | } 59 | } 60 | 61 | func ReadFileContent(filePath string) (content []byte, err error) { 62 | file, err := os.Open(filePath) 63 | defer file.Close() 64 | if err != nil { 65 | return nil, err 66 | } 67 | 68 | return io.ReadAll(file) 69 | } 70 | 71 | func CreateFile(path, content string) (err error) { 72 | return os.WriteFile(path, []byte(content), os.FileMode(0o644)) 73 | } 74 | 75 | func FindRootPath(absoluteFilePath, relativeFilePath string) string { 76 | absRoot := filepath.Dir(absoluteFilePath) 77 | return findRootPathRecursive(absRoot, relativeFilePath) 78 | } 79 | 80 | func findRootPathRecursive(currentDirPath, relativeFilePath string) string { 81 | filePath := filepath.Join(currentDirPath, relativeFilePath) 82 | 83 | if _, err := os.Stat(filePath); err == nil { 84 | return currentDirPath 85 | } 86 | 87 | parentPath := filepath.Dir(currentDirPath) 88 | if parentPath == currentDirPath { 89 | return "" 90 | } 91 | 92 | return findRootPathRecursive(parentPath, relativeFilePath) 93 | } 94 | -------------------------------------------------------------------------------- /pkg/common/utils/git.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "net/url" 21 | "os" 22 | "os/exec" 23 | "strings" 24 | 25 | "github.com/cloudwego/cwgo/pkg/consts" 26 | ) 27 | 28 | func GitClone(gitURL, path string) error { 29 | _, err := exec.LookPath("git") 30 | if err != nil { 31 | return err 32 | } 33 | c := exec.Command("git", "clone", gitURL) 34 | c.Dir = path 35 | c.Stderr = os.Stderr 36 | return c.Run() 37 | } 38 | 39 | func GitCheckout(branch, path string) error { 40 | if branch == "" { 41 | return nil 42 | } 43 | 44 | c := exec.Command("git", "checkout", branch) 45 | c.Dir = path 46 | c.Stderr = os.Stderr 47 | return c.Run() 48 | } 49 | 50 | func GitPath(gitURL string) (string, error) { 51 | if len(gitURL) > 3 && gitURL[0:3] == "git" { 52 | p := strings.Split(gitURL, consts.Slash) 53 | path := p[len(p)-1] 54 | return path[:len(path)-4], nil 55 | } 56 | u, err := url.Parse(gitURL) 57 | if err != nil { 58 | return "", err 59 | } 60 | p := strings.Split(strings.Trim(u.Path, ""), consts.Slash) 61 | path := p[len(p)-1] 62 | return path[:len(path)-4], nil 63 | } 64 | -------------------------------------------------------------------------------- /pkg/common/utils/hz.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "path" 21 | 22 | "github.com/cloudwego/cwgo/pkg/consts" 23 | "github.com/cloudwego/hertz/cmd/hz/util/logs" 24 | ) 25 | 26 | func SetHzVerboseLog(v bool) { 27 | if v { 28 | logs.SetLevel(logs.LevelDebug) 29 | } else { 30 | logs.SetLevel(logs.LevelWarn) 31 | } 32 | } 33 | 34 | func IsHzNew(outputDir string) bool { 35 | exist, _ := PathExist(path.Join(outputDir, consts.HzFile)) 36 | return !exist 37 | } 38 | -------------------------------------------------------------------------------- /pkg/common/utils/slice.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "strings" 21 | 22 | "github.com/cloudwego/cwgo/pkg/consts" 23 | ) 24 | 25 | type FlagStringSlice []string 26 | 27 | func (f *FlagStringSlice) String() string { 28 | return "" 29 | } 30 | 31 | func (f *FlagStringSlice) Set(value string) error { 32 | *f = append(*f, value) 33 | return nil 34 | } 35 | 36 | func StringSliceSpilt(s []string) []string { 37 | var ret []string 38 | for _, v := range s { 39 | ret = append(ret, strings.Split(v, consts.BlackSpace)...) 40 | } 41 | return ret 42 | } 43 | -------------------------------------------------------------------------------- /pkg/config_generator/config_generator_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config_generator 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestConvertToGoStructName(t *testing.T) { 24 | tests := []struct { 25 | name string 26 | want string 27 | }{ 28 | {"config_center.yml", "ConfigCenter"}, 29 | {"config-center_test", "ConfigCenterTest"}, 30 | {"dss/config-center", "ConfigCenter"}, 31 | {"config-center-test", "ConfigCenterTest"}, 32 | } 33 | for _, tt := range tests { 34 | t.Run(tt.name, func(t *testing.T) { 35 | if got := convertToGoStructName(tt.name); got != tt.want { 36 | t.Errorf("convertToGoStructName() = %v, want %v", got, tt.want) 37 | } 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pkg/config_generator/metadata.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config_generator 18 | 19 | type ConfigGenerateMeta struct { 20 | Desc string `json:"desc,omitempty"` 21 | Kind string `json:"kind,omitempty"` 22 | ConfigStruct Struct `json:"config_struct,omitempty"` 23 | ConfigValueType ConfigValueType `json:"config_value_type,omitempty"` 24 | Key string `json:"key,omitempty"` 25 | 26 | structTree map[string]Struct `json:"-"` 27 | } 28 | 29 | type FieldTag struct { 30 | TagKey string `json:"tag_key"` // eg: json 31 | TagValue string `json:"tag_value"` // eg: "name,omitempty" 32 | } 33 | 34 | // Struct to store struct fields 35 | type Struct struct { 36 | StructName string `json:"struct_name,omitempty"` 37 | Fields []Field `json:"fields,omitempty"` 38 | } 39 | 40 | type Field struct { 41 | FieldName string `json:"field_name,omitempty"` // FieldName of the field 42 | Value string `json:"value,omitempty"` // Value of the field (used for primitive types) 43 | FieldType string `json:"field_type,omitempty"` // FieldType of the field 44 | IsStruct bool `json:"is_struct"` 45 | IsSlice bool `json:"is_slice"` 46 | IsBasicType bool `json:"is_basic"` 47 | Tags []FieldTag `json:"tags,omitempty"` 48 | Children []Field `json:"children,omitempty"` 49 | } 50 | -------------------------------------------------------------------------------- /pkg/config_generator/sdk.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config_generator 18 | 19 | import "fmt" 20 | 21 | type Result struct { 22 | ServiceName string `json:"service_name,omitempty"` 23 | Addr string `json:"addr,omitempty"` 24 | SubConfigMetadataList []SubConfigMetadata `json:"sub_config_metadata_list,omitempty"` 25 | } 26 | 27 | type SubConfigMetadata struct { 28 | Namespace string `json:"namespace,omitempty"` 29 | ConfigMetadata []ConfigGenerateMeta `json:"config_metadata,omitempty"` 30 | } 31 | 32 | // HandleRequest processes the configuration request and returns the result. 33 | func HandleRequest(req *Config) (*Result, error) { 34 | var addr string 35 | if req.Addr == nil { 36 | addr = "" 37 | } else { 38 | addr = *req.Addr 39 | } 40 | 41 | // Create a new result object 42 | result := &Result{ 43 | ServiceName: req.ServiceName, 44 | Addr: addr, 45 | } 46 | 47 | // Iterate over each sub-config and process it 48 | for _, subConfig := range req.SubConfigList { 49 | subConfigMetadata, err := processSubConfig(subConfig) 50 | if err != nil { 51 | return nil, fmt.Errorf("failed to process sub-config '%s': %w", subConfig.NameSpace, err) 52 | } 53 | 54 | // Append processed sub-config metadata to the result 55 | result.SubConfigMetadataList = append(result.SubConfigMetadataList, subConfigMetadata) 56 | } 57 | 58 | return result, nil 59 | } 60 | 61 | // processSubConfig processes a single sub-config and returns the metadata. 62 | func processSubConfig(subConfig *SubConfig) (SubConfigMetadata, error) { 63 | metadata := SubConfigMetadata{ 64 | Namespace: subConfig.NameSpace, 65 | } 66 | 67 | // Iterate over each key-value pair and process it 68 | for _, configKvPair := range subConfig.ConfigKvPairList { 69 | fileMetas, err := processConfigKvPair(configKvPair) 70 | if err != nil { 71 | return metadata, err 72 | } 73 | 74 | // Add the processed file metadata to the sub-config metadata 75 | metadata.ConfigMetadata = append(metadata.ConfigMetadata, fileMetas...) 76 | } 77 | 78 | return metadata, nil 79 | } 80 | 81 | // processConfigKvPair processes a single key-value pair and returns the file metadata. 82 | func processConfigKvPair(configKvPair *ConfigKvPair) ([]ConfigGenerateMeta, error) { 83 | var result []ConfigGenerateMeta 84 | 85 | key := configKvPair.Key 86 | content := configKvPair.Value 87 | desc := configKvPair.Desc 88 | group := configKvPair.Kind 89 | valueType := configKvPair.ValueType 90 | 91 | // Check if the value type is either JsonType or YamlType 92 | switch valueType { 93 | case ConfigValueType_YamlType, ConfigValueType_JsonType: 94 | // Convert configuration content into Go structs 95 | yaml2Go := New(key, desc, group, valueType) 96 | if _, err := yaml2Go.Convert(convertToGoStructName(key), []byte(content)); err != nil { 97 | return nil, fmt.Errorf("failed to convert content for key '%s': %w", key, err) 98 | } 99 | 100 | // Organize the resulting structs 101 | organizeStructs(yaml2Go.StructsMeta) 102 | result = append(result, *yaml2Go.StructsMeta) 103 | default: 104 | // Store the raw text content for unsupported types 105 | result = append(result, ConfigGenerateMeta{ 106 | Desc: desc, 107 | Kind: group, 108 | ConfigValueType: valueType, 109 | Key: key, 110 | }) 111 | } 112 | 113 | return result, nil 114 | } 115 | -------------------------------------------------------------------------------- /pkg/config_generator/sdk_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config_generator 18 | 19 | import ( 20 | "encoding/json" 21 | "os" 22 | "testing" 23 | ) 24 | 25 | func Test_HandleRequest(t *testing.T) { 26 | c := &Config{ 27 | ServiceName: "nacos_config_server", 28 | SubConfigList: []*SubConfig{ 29 | { 30 | NameSpace: "public", 31 | ConfigKvPairList: []*ConfigKvPair{ 32 | { 33 | Key: "conf.yaml", 34 | ValueType: ConfigValueType_YamlType, 35 | Kind: "dev", 36 | Desc: "dsds", 37 | Value: value, 38 | }, 39 | { 40 | Key: "conf.yaml", 41 | ValueType: ConfigValueType_XmlType, 42 | Kind: "dev", 43 | Value: value, 44 | }, 45 | }, 46 | }, 47 | }, 48 | } 49 | ss, err := HandleRequest(c) 50 | if err != nil { 51 | t.Fatal(err) 52 | } 53 | out, err := json.Marshal(ss) 54 | if err != nil { 55 | t.Fatal(err) 56 | } 57 | os.WriteFile("test.json", out, 0o644) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/config_generator/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config_generator 18 | 19 | import ( 20 | "path/filepath" 21 | "strings" 22 | ) 23 | 24 | func convertToGoStructName(s string) string { 25 | var result string 26 | s = filepath.Base(s) 27 | if idx := strings.LastIndex(s, "."); idx != -1 { 28 | s = s[:idx] 29 | } 30 | 31 | // Split the string by spaces or underscores 32 | words := strings.FieldsFunc(s, func(r rune) bool { 33 | return r == ' ' || r == '_' || r == '-' 34 | }) 35 | 36 | // Capitalize the first letter of each word 37 | for _, word := range words { 38 | if len(word) > 0 { 39 | result += strings.ToUpper(string(word[0])) + strings.ToLower(word[1:]) 40 | } 41 | } 42 | 43 | return result 44 | } 45 | 46 | // isBasicType checks if the given type is a basic Go type 47 | func isBasicType(typeName string) bool { 48 | basicTypes := map[string]bool{ 49 | "int": true, 50 | "int8": true, 51 | "int16": true, 52 | "int32": true, 53 | "int64": true, 54 | "uint": true, 55 | "uint8": true, 56 | "uint16": true, 57 | "uint32": true, 58 | "uint64": true, 59 | "float32": true, 60 | "float64": true, 61 | "bool": true, 62 | "string": true, 63 | "byte": true, 64 | "rune": true, 65 | } 66 | 67 | return basicTypes[typeName] 68 | } 69 | -------------------------------------------------------------------------------- /pkg/config_generator/yaml2go_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config_generator 18 | 19 | import ( 20 | "encoding/json" 21 | "os" 22 | "testing" 23 | ) 24 | 25 | var value = ` 26 | kitex: 27 | service: p.s.m 28 | version: 1.0.0 29 | ports: 30 | - 8888 31 | - 8889 32 | ` 33 | 34 | func TestYaml2Go(t *testing.T) { 35 | yaml2Go := New("key", "desc", "group", ConfigValueType_YamlType) 36 | s, err := yaml2Go.Convert("config", []byte(value)) 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | t.Log(s) 41 | 42 | organizeStructs(yaml2Go.StructsMeta) 43 | marshal, err := json.Marshal(yaml2Go.StructsMeta) 44 | if err != nil { 45 | t.Fatal(err) 46 | } 47 | os.WriteFile("metadata.json", marshal, 0o644) 48 | } 49 | -------------------------------------------------------------------------------- /pkg/curd/code/type.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * MIT License 17 | * 18 | * Copyright (c) 2021 Surawich Laprattanatrai 19 | * 20 | * Permission is hereby granted, free of charge, to any person obtaining a copy 21 | * of this software and associated documentation files (the "Software"), to deal 22 | * in the Software without restriction, including without limitation the rights 23 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 24 | * copies of the Software, and to permit persons to whom the Software is 25 | * furnished to do so, subject to the following conditions: 26 | * 27 | * The above copyright notice and this permission notice shall be included in all 28 | * copies or substantial portions of the Software. 29 | * 30 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 31 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 32 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 33 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 34 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 35 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 36 | * SOFTWARE. 37 | */ 38 | 39 | package code 40 | 41 | import "fmt" 42 | 43 | type Type interface { 44 | RealName() string 45 | } 46 | 47 | type IdentType string 48 | 49 | func (st IdentType) RealName() string { 50 | return string(st) 51 | } 52 | 53 | type SelectorExprType struct { 54 | X string 55 | Sel string 56 | } 57 | 58 | func (set SelectorExprType) RealName() string { 59 | return set.X + "." + set.Sel 60 | } 61 | 62 | type InterfaceType struct { 63 | Name string 64 | Methods InterfaceMethods 65 | } 66 | 67 | func (it InterfaceType) RealName() string { 68 | return "interface{}" 69 | } 70 | 71 | type SliceType struct { 72 | ElementType Type 73 | } 74 | 75 | func (st SliceType) RealName() string { 76 | return "[]" + st.ElementType.RealName() 77 | } 78 | 79 | type MapType struct { 80 | KeyType Type 81 | ValueType Type 82 | } 83 | 84 | func (mt MapType) RealName() string { 85 | return fmt.Sprintf("map[%s]%s", mt.KeyType.RealName(), mt.ValueType.RealName()) 86 | } 87 | 88 | type StarExprType struct { 89 | RealType Type 90 | } 91 | 92 | func (set StarExprType) RealName() string { 93 | return "*" + set.RealType.RealName() 94 | } 95 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/aggregate_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func aggregateBaseCodegen() []code.Statement { 22 | stmt := `if pipeline == nil { 23 | return fmt.Errorf("pipeline param is empty") 24 | } 25 | 26 | cursor, err := b.collection.Aggregate(ctx, pipeline) 27 | if err != nil { 28 | return err 29 | } 30 | defer cursor.Close(ctx) 31 | 32 | return cursor.All(ctx, result)` 33 | 34 | return []code.Statement{ 35 | code.RawStmt(stmt), 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/bulk.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/parse" 22 | ) 23 | 24 | func bulkCodegen(bulk *parse.BulkParse) []code.Statement { 25 | return []code.Statement{ 26 | code.DeclVarStmt{ 27 | Name: "models", 28 | Type: code.SliceType{ 29 | ElementType: code.SelectorExprType{ 30 | X: "mongo", 31 | Sel: "WriteModel", 32 | }, 33 | }, 34 | }, 35 | bulkOperationsCodegen(bulk), 36 | code.ReturnStmt{ 37 | ListCommaStmt: code.ListCommaStmt{ 38 | code.CallStmt{ 39 | Caller: code.RawStmt("r.collection"), 40 | CallName: "BulkWrite", 41 | Args: code.ListCommaStmt{ 42 | code.RawStmt(bulk.CtxParamName), 43 | code.RawStmt("models"), 44 | }, 45 | }, 46 | }, 47 | }, 48 | } 49 | } 50 | 51 | func bulkOperationsCodegen(bulk *parse.BulkParse) code.SliceAppendsStmt { 52 | operations := make([]code.SliceAppendStmt, 0, 10) 53 | for _, operation := range bulk.Operations { 54 | if operation.GetOperationName() == parse.Insert { 55 | operations = append(operations, bulkInsertCodegen(operation.(*parse.InsertParse))) 56 | } 57 | if operation.GetOperationName() == parse.Update { 58 | operations = append(operations, bulkUpdateCodegen(operation.(*parse.UpdateParse))) 59 | } 60 | if operation.GetOperationName() == parse.Delete { 61 | operations = append(operations, bulkDeleteCodegen(operation.(*parse.DeleteParse))) 62 | } 63 | } 64 | return operations 65 | } 66 | 67 | func bulkInsertCodegen(insert *parse.InsertParse) code.SliceAppendStmt { 68 | return code.SliceAppendStmt{ 69 | SliceName: "models", 70 | AppendData: code.CallStmt{ 71 | Caller: code.RawStmt("mongo.NewInsertOneModel()"), 72 | CallName: "SetDocument", 73 | Args: code.ListCommaStmt{ 74 | code.RawStmt(insert.MethodParamNames[0]), 75 | }, 76 | }, 77 | } 78 | } 79 | 80 | func bulkUpdateCodegen(update *parse.UpdateParse) code.SliceAppendStmt { 81 | if update.OperateMode == parse.OperateOne { 82 | return getBulkUpdateCode(update, "mongo.NewUpdateOneModel().SetFilter") 83 | } else { 84 | return getBulkUpdateCode(update, "mongo.NewUpdateManyModel().SetFilter") 85 | } 86 | } 87 | 88 | func bulkDeleteCodegen(delete *parse.DeleteParse) code.SliceAppendStmt { 89 | if delete.OperateMode == parse.OperateOne { 90 | return getBulkDeleteCode(delete, "mongo.NewDeleteOneModel().SetFilter") 91 | } else { 92 | return getBulkDeleteCode(delete, "mongo.NewDeleteManyModel().SetFilter") 93 | } 94 | } 95 | 96 | func getBulkUpdateCode(update *parse.UpdateParse, callName string) code.SliceAppendStmt { 97 | chainCall := make(code.ChainStmt, 0, 5) 98 | return code.SliceAppendStmt{ 99 | SliceName: "models", 100 | AppendData: chainCall.ChainCall(code.Chain{ 101 | CallName: callName, 102 | Args: code.ListCommaStmt{ 103 | queryCodegen(update.Query), 104 | }, 105 | }).ChainCall(code.Chain{ 106 | CallName: "SetUpdate", 107 | Args: code.ListCommaStmt{ 108 | updateFieldsCodegen(update), 109 | }, 110 | }).ChainCall(code.Chain{ 111 | CallName: "SetUpsert", 112 | Args: code.ListCommaStmt{ 113 | upsertCodegen(update.Upsert), 114 | }, 115 | }), 116 | } 117 | } 118 | 119 | func getBulkDeleteCode(delete *parse.DeleteParse, callName string) code.SliceAppendStmt { 120 | chainCall := make(code.ChainStmt, 0, 5) 121 | return code.SliceAppendStmt{ 122 | SliceName: "models", 123 | AppendData: chainCall.ChainCall(code.Chain{ 124 | CallName: callName, 125 | Args: code.ListCommaStmt{ 126 | queryCodegen(delete.Query), 127 | }, 128 | }), 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/bulk_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func bulkInsertBaseCodegen() []code.Statement { 22 | stmt := `if len(batchData) == 0 { 23 | return nil, fmt.Errorf("batch param is empty") 24 | } 25 | 26 | models := make([]mongo.WriteModel, len(batchData)) 27 | for i, doc := range batchData { 28 | models[i] = mongo.NewInsertOneModel().SetDocument(doc) 29 | } 30 | 31 | return b.collection.BulkWrite(ctx, models)` 32 | 33 | return []code.Statement{ 34 | code.RawStmt(stmt), 35 | } 36 | } 37 | 38 | func bulkUpdateBaseCodegen() []code.Statement { 39 | stmt := `if len(filter) != len(updater) { 40 | return nil, fmt.Errorf("filter and updater must have the same length") 41 | } 42 | 43 | models := make([]mongo.WriteModel, len(filter)) 44 | for i := range filter { 45 | models[i] = mongo.NewUpdateOneModel().SetFilter(filter[i]).SetUpdate(updater[i]) 46 | } 47 | 48 | return b.collection.BulkWrite(ctx, models)` 49 | 50 | return []code.Statement{ 51 | code.RawStmt(stmt), 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/count.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/parse" 22 | ) 23 | 24 | func countCodegen(count *parse.CountParse) []code.Statement { 25 | return []code.Statement{ 26 | code.DeclColonStmt{ 27 | Left: code.ListCommaStmt{ 28 | code.RawStmt("result"), 29 | code.RawStmt("err"), 30 | }, 31 | Right: code.CallStmt{ 32 | Caller: code.RawStmt("r.collection"), 33 | CallName: "CountDocuments", 34 | Args: code.ListCommaStmt{ 35 | code.RawStmt(count.CtxParamName), 36 | queryCodegen(count.Query), 37 | }, 38 | }, 39 | }, 40 | code.RawStmt("if err != nil {\n\treturn 0, err\n}"), 41 | code.ReturnStmt{ 42 | ListCommaStmt: code.ListCommaStmt{ 43 | code.RawStmt("int(result)"), 44 | code.RawStmt("nil"), 45 | }, 46 | }, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/count_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func countBaseCodegen() []code.Statement { 22 | stmt := `if selector == nil { 23 | return -1, fmt.Errorf("query param is empty") 24 | } 25 | 26 | return b.collection.CountDocuments(ctx, selector)` 27 | 28 | return []code.Statement{ 29 | code.RawStmt(stmt), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/delete.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/parse" 22 | ) 23 | 24 | func deleteCodegen(delete *parse.DeleteParse) []code.Statement { 25 | if delete.OperateMode == parse.OperateOne { 26 | return []code.Statement{ 27 | code.DeclColonStmt{ 28 | Left: code.ListCommaStmt{ 29 | code.RawStmt("result"), 30 | code.RawStmt("err"), 31 | }, 32 | Right: code.CallStmt{ 33 | Caller: code.RawStmt("r.collection"), 34 | CallName: "DeleteOne", 35 | Args: code.ListCommaStmt{ 36 | code.RawStmt(delete.CtxParamName), 37 | queryCodegen(delete.Query), 38 | }, 39 | }, 40 | }, 41 | code.RawStmt("if err != nil {\n\treturn false, err\n}"), 42 | code.ReturnStmt{ 43 | ListCommaStmt: code.ListCommaStmt{ 44 | code.RawStmt("result.DeletedCount > 0"), 45 | code.RawStmt("nil"), 46 | }, 47 | }, 48 | } 49 | } else { 50 | return []code.Statement{ 51 | code.DeclColonStmt{ 52 | Left: code.ListCommaStmt{ 53 | code.RawStmt("result"), 54 | code.RawStmt("err"), 55 | }, 56 | Right: code.CallStmt{ 57 | Caller: code.RawStmt("r.collection"), 58 | CallName: "DeleteMany", 59 | Args: code.ListCommaStmt{ 60 | code.RawStmt(delete.CtxParamName), 61 | queryCodegen(delete.Query), 62 | }, 63 | }, 64 | }, 65 | code.RawStmt("if err != nil {\n\treturn 0, err\n}"), 66 | code.ReturnStmt{ 67 | ListCommaStmt: code.ListCommaStmt{ 68 | code.RawStmt("int(result.DeletedCount)"), 69 | code.RawStmt("nil"), 70 | }, 71 | }, 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/delete_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func deleteOneBaseCodegen() []code.Statement { 22 | stmt := `if deleteOneData == nil { 23 | return nil, fmt.Errorf("delete param is empty") 24 | } 25 | 26 | return b.collection.DeleteOne(ctx, deleteOneData)` 27 | 28 | return []code.Statement{ 29 | code.RawStmt(stmt), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/find_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func findBaseCodegen() []code.Statement { 22 | stmt := `if selector == nil { 23 | return fmt.Errorf("query param is empty") 24 | } 25 | 26 | return b.collection.FindOne(ctx, selector).Decode(result)` 27 | 28 | return []code.Statement{ 29 | code.RawStmt(stmt), 30 | } 31 | } 32 | 33 | func findListBaseCodegen() []code.Statement { 34 | stmt := `if selector == nil { 35 | return fmt.Errorf("query param is empty") 36 | } 37 | 38 | cursor, err := b.collection.Find(ctx, selector) 39 | if err != nil { 40 | return err 41 | } 42 | defer cursor.Close(ctx) 43 | 44 | return cursor.All(ctx, result)` 45 | 46 | return []code.Statement{ 47 | code.RawStmt(stmt), 48 | } 49 | } 50 | 51 | func findPageListBaseCodegen() []code.Statement { 52 | stmt := `if selector == nil { 53 | return fmt.Errorf("query param is empty") 54 | } 55 | 56 | if skip < 0 || limit < 0 { 57 | return fmt.Errorf("skip or limit not correct") 58 | } 59 | 60 | ops := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit)) 61 | if sort != "" { 62 | if strings.Contains(sort, "-") { 63 | sort = strings.TrimPrefix(sort, "-") 64 | ops.SetSort(bson.D{bson.E{Key: sort, Value: -1}}) 65 | } else { 66 | ops.SetSort(bson.D{bson.E{Key: sort, Value: 1}}) 67 | } 68 | } 69 | 70 | cursor, err := b.collection.Find(ctx, selector, ops) 71 | if err != nil { 72 | return err 73 | } 74 | defer cursor.Close(ctx) 75 | 76 | return cursor.All(ctx, result)` 77 | 78 | return []code.Statement{ 79 | code.RawStmt(stmt), 80 | } 81 | } 82 | 83 | func findSortPageListBaseCodegen() []code.Statement { 84 | stmt := `if selector == nil { 85 | return fmt.Errorf("query param is empty") 86 | } 87 | 88 | if skip < 0 || limit < 0 { 89 | return fmt.Errorf("skip or limit not correct") 90 | } 91 | 92 | ops := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit)) 93 | if len(sorts) > 0 { 94 | sortFields := make(bson.D, len(sorts)) 95 | for i, field := range sorts { 96 | if strings.Contains(field, "-") { 97 | field = strings.TrimPrefix(field, "-") 98 | sortFields[i] = bson.E{Key: field, Value: -1} 99 | } else { 100 | sortFields[i] = bson.E{Key: field, Value: 1} 101 | } 102 | } 103 | ops.SetSort(sortFields) 104 | } 105 | 106 | cursor, err := b.collection.Find(ctx, selector, ops) 107 | if err != nil { 108 | return err 109 | } 110 | defer cursor.Close(ctx) 111 | 112 | return cursor.All(ctx, result)` 113 | 114 | return []code.Statement{ 115 | code.RawStmt(stmt), 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/insert.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/parse" 22 | ) 23 | 24 | func insertCodegen(insert *parse.InsertParse) []code.Statement { 25 | if insert.OperateMode == parse.OperateOne { 26 | return []code.Statement{ 27 | code.DeclColonStmt{ 28 | Left: code.ListCommaStmt{ 29 | code.RawStmt("result"), 30 | code.RawStmt("err"), 31 | }, 32 | Right: code.CallStmt{ 33 | Caller: code.RawStmt("r.collection"), 34 | CallName: "InsertOne", 35 | Args: code.ListCommaStmt{ 36 | code.RawStmt(insert.MethodParamNames[0]), 37 | code.RawStmt(insert.MethodParamNames[1]), 38 | }, 39 | }, 40 | }, 41 | code.RawStmt("if err != nil {\n\treturn nil, err\n}"), 42 | code.ReturnStmt{ 43 | ListCommaStmt: code.ListCommaStmt{ 44 | code.RawStmt("result.InsertedID"), 45 | code.RawStmt("nil"), 46 | }, 47 | }, 48 | } 49 | } else { 50 | return []code.Statement{ 51 | code.DeclVarStmt{ 52 | Name: "entities", 53 | Type: code.SliceType{ 54 | ElementType: code.InterfaceType{}, 55 | }, 56 | }, 57 | code.ForRangeBlockStmt{ 58 | RangeName: insert.MethodParamNames[1], 59 | Value: "model", 60 | Body: []code.Statement{ 61 | code.RawStmt("entities = append(entities, model)"), 62 | }, 63 | }, 64 | code.DeclColonStmt{ 65 | Left: code.ListCommaStmt{ 66 | code.RawStmt("result"), 67 | code.RawStmt("err"), 68 | }, 69 | Right: code.CallStmt{ 70 | Caller: code.RawStmt("r.collection"), 71 | CallName: "InsertMany", 72 | Args: code.ListCommaStmt{ 73 | code.RawStmt(insert.MethodParamNames[0]), 74 | code.RawStmt("entities"), 75 | }, 76 | }, 77 | }, 78 | code.RawStmt("if err != nil {\n\treturn nil, err\n}"), 79 | code.ReturnStmt{ 80 | ListCommaStmt: code.ListCommaStmt{ 81 | code.RawStmt("result.InsertedIDs"), 82 | code.RawStmt("nil"), 83 | }, 84 | }, 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/insert_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func insertOneBaseCodegen() []code.Statement { 22 | stmt := `if insertOneData == nil { 23 | return nil, fmt.Errorf("insert param is empty") 24 | } 25 | 26 | return b.collection.InsertOne(ctx, insertOneData)` 27 | 28 | return []code.Statement{ 29 | code.RawStmt(stmt), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/query.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/parse" 22 | ) 23 | 24 | func queryCodegen(query *parse.Query) code.Statement { 25 | if query.QueryMode == parse.All { 26 | return code.MapStmt{ 27 | Name: "bson.M", 28 | Pair: []code.MapPair{}, 29 | } 30 | } else { 31 | return code.MapStmt{ 32 | Name: "bson.M", 33 | Pair: []code.MapPair{ 34 | dfsCodegen(query.ConnectionOpTree), 35 | }, 36 | } 37 | } 38 | } 39 | 40 | func dfsCodegen(node *parse.ConnectionOpTree) code.MapPair { 41 | // leaves node 42 | if node.LeftChildren == nil { 43 | return comparatorCodegen(node) 44 | } else { 45 | // none-leaves node 46 | return code.MapPair{ 47 | Key: code.RawStmt(node.Name), 48 | Value: code.SliceStmt{ 49 | Name: "[]bson.M", 50 | Values: []code.MapPair{ 51 | dfsCodegen(node.LeftChildren), 52 | dfsCodegen(node.RightChildren), 53 | }, 54 | }, 55 | } 56 | } 57 | } 58 | 59 | func comparatorCodegen(node *parse.ConnectionOpTree) code.MapPair { 60 | switch parse.QueryComparator(node.Name) { 61 | case parse.Equal: 62 | return singleMapCodegen(node.MongoFieldName, node.ParamNames[0]) 63 | case parse.NotEqual: 64 | return oneMapParamCodegen(node.MongoFieldName, "$ne", node.ParamNames[0]) 65 | case parse.LessThan: 66 | return oneMapParamCodegen(node.MongoFieldName, "$lt", node.ParamNames[0]) 67 | case parse.LessThanEqual: 68 | return oneMapParamCodegen(node.MongoFieldName, "$lte", node.ParamNames[0]) 69 | case parse.GreaterThan: 70 | return oneMapParamCodegen(node.MongoFieldName, "$gt", node.ParamNames[0]) 71 | case parse.GreaterThanEqual: 72 | return oneMapParamCodegen(node.MongoFieldName, "$gte", node.ParamNames[0]) 73 | case parse.Between: 74 | return twoMapParamsCodegen(node.MongoFieldName, "$gte", node.ParamNames[0], 75 | "$lte", node.ParamNames[1]) 76 | case parse.NotBetween: 77 | return twoMapParamsCodegen(node.MongoFieldName, "$lt", node.ParamNames[0], 78 | "$gt", node.ParamNames[1]) 79 | case parse.In: 80 | return oneMapParamCodegen(node.MongoFieldName, "$in", node.ParamNames[0]) 81 | case parse.NotIn: 82 | return oneMapParamCodegen(node.MongoFieldName, "$n"+"in", node.ParamNames[0]) 83 | case parse.True: 84 | return singleMapCodegen(node.MongoFieldName, "true") 85 | case parse.False: 86 | return singleMapCodegen(node.MongoFieldName, "false") 87 | case parse.Exists: 88 | return oneMapParamCodegen(node.MongoFieldName, "$exists", "1") 89 | case parse.NotExists: 90 | return oneMapParamCodegen(node.MongoFieldName, "$exists", "0") 91 | default: 92 | } 93 | 94 | return code.MapPair{} 95 | } 96 | 97 | func singleMapCodegen(key, value string) code.MapPair { 98 | return code.MapPair{ 99 | Key: code.RawStmt(key), 100 | Value: code.RawStmt(value), 101 | } 102 | } 103 | 104 | func oneMapParamCodegen(key, valueKey, valueValue string) code.MapPair { 105 | return code.MapPair{ 106 | Key: code.RawStmt(key), 107 | Value: code.MapStmt{ 108 | Name: "bson.M", 109 | Pair: []code.MapPair{ 110 | { 111 | Key: code.RawStmt(valueKey), 112 | Value: code.RawStmt(valueValue), 113 | }, 114 | }, 115 | }, 116 | } 117 | } 118 | 119 | func twoMapParamsCodegen(key, valueKey1, valueValue1, valueKey2, valueValue2 string) code.MapPair { 120 | return code.MapPair{ 121 | Key: code.RawStmt(key), 122 | Value: code.MapStmt{ 123 | Name: "bson.M", 124 | Pair: []code.MapPair{ 125 | { 126 | Key: code.RawStmt(valueKey1), 127 | Value: code.RawStmt(valueValue1), 128 | }, 129 | { 130 | Key: code.RawStmt(valueKey2), 131 | Value: code.RawStmt(valueValue2), 132 | }, 133 | }, 134 | }, 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/update.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/parse" 22 | ) 23 | 24 | func updateCodegen(update *parse.UpdateParse) []code.Statement { 25 | chainCall := make(code.ChainStmt, 0, 5) 26 | if update.OperateMode == parse.OperateOne { 27 | return []code.Statement{ 28 | code.DeclColonStmt{ 29 | Left: code.ListCommaStmt{ 30 | code.RawStmt("result"), 31 | code.RawStmt("err"), 32 | }, 33 | Right: code.CallStmt{ 34 | Caller: code.RawStmt("r.collection"), 35 | CallName: "UpdateOne", 36 | Args: code.ListCommaStmt{ 37 | code.RawStmt(update.CtxParamName), 38 | queryCodegen(update.Query), 39 | updateFieldsCodegen(update), 40 | chainCall.ChainCall(code.Chain{ 41 | CallName: "options.Update", 42 | Args: code.ListCommaStmt{}, 43 | }).ChainCall(code.Chain{ 44 | CallName: "SetUpsert", 45 | Args: code.ListCommaStmt{ 46 | upsertCodegen(update.Upsert), 47 | }, 48 | }), 49 | }, 50 | }, 51 | }, 52 | code.RawStmt("if err != nil {\n\treturn false, err\n}"), 53 | code.ReturnStmt{ 54 | ListCommaStmt: code.ListCommaStmt{ 55 | code.RawStmt("result.MatchedCount > 0"), 56 | code.RawStmt("nil"), 57 | }, 58 | }, 59 | } 60 | } else { 61 | return []code.Statement{ 62 | code.DeclColonStmt{ 63 | Left: code.ListCommaStmt{ 64 | code.RawStmt("result"), 65 | code.RawStmt("err"), 66 | }, 67 | Right: code.CallStmt{ 68 | Caller: code.RawStmt("r.collection"), 69 | CallName: "UpdateMany", 70 | Args: code.ListCommaStmt{ 71 | code.RawStmt(update.CtxParamName), 72 | queryCodegen(update.Query), 73 | updateFieldsCodegen(update), 74 | chainCall.ChainCall(code.Chain{ 75 | CallName: "options.Update", 76 | Args: code.ListCommaStmt{}, 77 | }).ChainCall(code.Chain{ 78 | CallName: "SetUpsert", 79 | Args: code.ListCommaStmt{ 80 | upsertCodegen(update.Upsert), 81 | }, 82 | }), 83 | }, 84 | }, 85 | }, 86 | code.RawStmt("if err != nil {\n\treturn 0, err\n}"), 87 | code.ReturnStmt{ 88 | ListCommaStmt: code.ListCommaStmt{ 89 | code.RawStmt("int(result.MatchedCount)"), 90 | code.RawStmt("nil"), 91 | }, 92 | }, 93 | } 94 | } 95 | } 96 | 97 | func updateFieldsCodegen(update *parse.UpdateParse) code.MapStmt { 98 | if update.UpdateStructObjName == "" { 99 | mapPairs := make([]code.MapPair, 0, 5) 100 | for _, field := range update.UpdateFields { 101 | mapPairs = append(mapPairs, code.MapPair{ 102 | Key: code.RawStmt(field.MongoFieldName), 103 | Value: code.RawStmt(field.ParamName), 104 | }) 105 | } 106 | return code.MapStmt{ 107 | Name: "bson.M", 108 | Pair: []code.MapPair{ 109 | { 110 | Key: code.RawStmt("$set"), 111 | Value: code.MapStmt{ 112 | Name: "bson.M", 113 | Pair: mapPairs, 114 | }, 115 | }, 116 | }, 117 | } 118 | } else { 119 | return code.MapStmt{ 120 | Name: "bson.M", 121 | Pair: []code.MapPair{ 122 | { 123 | Key: code.RawStmt("$set"), 124 | Value: code.RawStmt(update.UpdateStructObjName), 125 | }, 126 | }, 127 | } 128 | } 129 | } 130 | 131 | func upsertCodegen(upsert bool) code.RawStmt { 132 | if upsert { 133 | return "true" 134 | } 135 | return "false" 136 | } 137 | -------------------------------------------------------------------------------- /pkg/curd/doc/mongo/codegen/update_base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package codegen 18 | 19 | import "github.com/cloudwego/cwgo/pkg/curd/code" 20 | 21 | func updateOneBaseCodegen() []code.Statement { 22 | stmt := `if selector == nil || updater == nil { 23 | return nil, fmt.Errorf("update param is empty") 24 | } 25 | 26 | return b.collection.UpdateOne(ctx, selector, updater)` 27 | 28 | return []code.Statement{ 29 | code.RawStmt(stmt), 30 | } 31 | } 32 | 33 | func updateManyBaseCodegen() []code.Statement { 34 | stmt := `if selector == nil || updater == nil { 35 | return nil, fmt.Errorf("update param is empty") 36 | } 37 | 38 | return b.collection.UpdateMany(ctx, selector, updater)` 39 | 40 | return []code.Statement{ 41 | code.RawStmt(stmt), 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pkg/curd/parse/count.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package parse 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/cloudwego/cwgo/pkg/curd/extract" 23 | ) 24 | 25 | type CountParse struct { 26 | // Query defines the Query information contained in the Count operation 27 | Query *Query 28 | 29 | // CtxParamName defines the method's context.Context param name 30 | CtxParamName string 31 | 32 | // BelongedToMethod defines the method to which Count belongs 33 | BelongedToMethod *extract.InterfaceMethod 34 | } 35 | 36 | func newCountParse() *CountParse { 37 | return &CountParse{Query: newQuery()} 38 | } 39 | 40 | func (cp *CountParse) GetOperationName() string { 41 | return Count 42 | } 43 | 44 | // parseCount can be called independently. 45 | // 46 | // input params description: 47 | // tokens: it contains all tokens belonging to Count except for Count token 48 | // method: the method to which Count belongs 49 | // curParamIndex: current method's param index 50 | func (cp *CountParse) parseCount(tokens []string, method *extract.InterfaceMethod, curParamIndex *int) error { 51 | if err := cp.check(method); err != nil { 52 | return err 53 | } 54 | 55 | cp.BelongedToMethod = method 56 | 57 | if err := cp.parseQuery(tokens, method, curParamIndex); err != nil { 58 | return err 59 | } 60 | 61 | if *curParamIndex < len(method.Params) { 62 | return newMethodSyntaxError(method.Name, fmt.Sprintf("too many method parameters written, "+ 63 | "%v and subsequent parameters are useless", method.Params[*curParamIndex].Name)) 64 | } 65 | 66 | return nil 67 | } 68 | 69 | func (cp *CountParse) check(method *extract.InterfaceMethod) error { 70 | if len(method.Params) < 1 { 71 | return newMethodSyntaxError(method.Name, "less than one input parameters") 72 | } 73 | 74 | if len(method.Returns) != 2 { 75 | return newMethodSyntaxError(method.Name, "return parameter not equal to 2") 76 | } 77 | 78 | if method.Params[0].Type.RealName() != "context.Context" { 79 | return newMethodSyntaxError(method.Name, "the first parameter in the input parameters "+ 80 | "should be context.Context") 81 | } 82 | 83 | if method.Returns[0].RealName() != "int" { 84 | return newMethodSyntaxError(method.Name, "the first parameter in the return parameters "+ 85 | "should be int") 86 | } 87 | 88 | if method.Returns[1].RealName() != "error" { 89 | return newMethodSyntaxError(method.Name, "the second parameter in the return parameters "+ 90 | "should be error") 91 | } 92 | 93 | cp.CtxParamName = method.Params[0].Name 94 | 95 | return nil 96 | } 97 | 98 | func (cp *CountParse) parseQuery(tokens []string, method *extract.InterfaceMethod, curParamIndex *int) error { 99 | fqIndex, err := getFirstQueryIndex(tokens) 100 | if err != nil { 101 | return newMethodSyntaxError(method.Name, err.Error()) 102 | } 103 | if err = cp.Query.parseQuery(tokens[fqIndex:], method, curParamIndex); err != nil { 104 | return err 105 | } 106 | return nil 107 | } 108 | -------------------------------------------------------------------------------- /pkg/curd/parse/delete.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package parse 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/cloudwego/cwgo/pkg/curd/code" 23 | "github.com/cloudwego/cwgo/pkg/curd/extract" 24 | ) 25 | 26 | type DeleteParse struct { 27 | // OperateMode One or Many 28 | OperateMode OperateMode 29 | 30 | // Query defines the Query information contained in the Delete operation 31 | Query *Query 32 | 33 | // CtxParamName defines the method's context.Context param name 34 | CtxParamName string 35 | 36 | // BelongedToMethod defines the method to which Delete belongs 37 | BelongedToMethod *extract.InterfaceMethod 38 | } 39 | 40 | func newDeleteParse() *DeleteParse { 41 | return &DeleteParse{Query: newQuery()} 42 | } 43 | 44 | func (dp *DeleteParse) GetOperationName() string { 45 | return Delete 46 | } 47 | 48 | // parseDelete can be called independently or by Bulk or by Transaction, when isCalled = false, is called independently 49 | // 50 | // input params description: 51 | // tokens: it contains all tokens belonging to Delete except for Delete token 52 | // method: the method to which Delete belongs 53 | // curParamIndex: current method's param index 54 | // isCalled: false ==> independently true ==> called by Bulk or Transaction 55 | func (dp *DeleteParse) parseDelete(tokens []string, method *extract.InterfaceMethod, curParamIndex *int, isCalled bool) error { 56 | if !isCalled { 57 | if err := dp.check(method); err != nil { 58 | return err 59 | } 60 | } 61 | 62 | dp.BelongedToMethod = method 63 | 64 | if err := dp.parseQuery(tokens, method, curParamIndex); err != nil { 65 | return err 66 | } 67 | 68 | if !isCalled { 69 | if *curParamIndex < len(method.Params) { 70 | return newMethodSyntaxError(method.Name, fmt.Sprintf("too many method parameters written, "+ 71 | "%v and subsequent parameters are useless", method.Params[*curParamIndex].Name)) 72 | } 73 | } 74 | 75 | return nil 76 | } 77 | 78 | func (dp *DeleteParse) check(method *extract.InterfaceMethod) error { 79 | if len(method.Params) < 1 { 80 | return newMethodSyntaxError(method.Name, "less than one input parameters") 81 | } 82 | 83 | if len(method.Returns) != 2 { 84 | return newMethodSyntaxError(method.Name, "return parameter not equal to 2") 85 | } 86 | 87 | if method.Params[0].Type.RealName() != "context.Context" { 88 | return newMethodSyntaxError(method.Name, "the first parameter in the input parameters "+ 89 | "should be context.Context") 90 | } 91 | 92 | if method.Returns[1].RealName() != "error" { 93 | return newMethodSyntaxError(method.Name, "the second parameter in the return parameters "+ 94 | "should be error") 95 | } 96 | 97 | if t, ok := method.Returns[0].(code.IdentType); ok { 98 | if string(t) == "bool" { 99 | dp.OperateMode = OperateOne 100 | } else if string(t) == "int" { 101 | dp.OperateMode = OperateMany 102 | } else { 103 | return newMethodSyntaxError(method.Name, "the first parameter in the return parameters "+ 104 | "should be bool or int") 105 | } 106 | } else { 107 | return newMethodSyntaxError(method.Name, "the first parameter in the return parameters "+ 108 | "should be bool or int") 109 | } 110 | 111 | dp.CtxParamName = method.Params[0].Name 112 | 113 | return nil 114 | } 115 | 116 | func (dp *DeleteParse) parseQuery(tokens []string, method *extract.InterfaceMethod, curParamIndex *int) error { 117 | fqIndex, err := getFirstQueryIndex(tokens) 118 | if err != nil { 119 | return newMethodSyntaxError(method.Name, err.Error()) 120 | } 121 | if err = dp.Query.parseQuery(tokens[fqIndex:], method, curParamIndex); err != nil { 122 | return err 123 | } 124 | return nil 125 | } 126 | -------------------------------------------------------------------------------- /pkg/curd/parse/error.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package parse 18 | 19 | import "fmt" 20 | 21 | // newMethodSyntaxError creates syntaxError 22 | func newMethodSyntaxError(methodName, errReason string) error { 23 | return methodSyntaxError{ 24 | methodName: methodName, 25 | errReason: errReason, 26 | } 27 | } 28 | 29 | type methodSyntaxError struct { 30 | methodName string 31 | errReason string 32 | } 33 | 34 | func (err methodSyntaxError) Error() string { 35 | return fmt.Sprintf("method %s has syntax errors, specific reasons: %s", err.methodName, err.errReason) 36 | } 37 | -------------------------------------------------------------------------------- /pkg/curd/parse/insert.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package parse 18 | 19 | import ( 20 | "github.com/cloudwego/cwgo/pkg/curd/code" 21 | "github.com/cloudwego/cwgo/pkg/curd/extract" 22 | ) 23 | 24 | type InsertParse struct { 25 | // OperateMode One or Many 26 | OperateMode OperateMode 27 | 28 | // MethodParamNames defines the method's param names 29 | MethodParamNames [2]string 30 | 31 | // BelongedToMethod defines the method to which Insert belongs 32 | BelongedToMethod *extract.InterfaceMethod 33 | } 34 | 35 | func newInsertParse() *InsertParse { 36 | return &InsertParse{MethodParamNames: [2]string{}} 37 | } 38 | 39 | func (ip *InsertParse) GetOperationName() string { 40 | return Insert 41 | } 42 | 43 | // parseInsert can be called independently or by Bulk or by Transaction, when isCalled = false, is called independently 44 | // 45 | // input params description: 46 | // method: the method to which Insert belongs 47 | // curParamIndex: current method's param index 48 | // isCalled: false ==> independently true ==> called by Bulk or Transaction 49 | func (ip *InsertParse) parseInsert(method *extract.InterfaceMethod, curParamIndex *int, isCalled bool) error { 50 | if !isCalled { 51 | if err := ip.check(method); err != nil { 52 | return err 53 | } 54 | } 55 | 56 | if !isCalled { 57 | ip.MethodParamNames = [2]string{ 58 | method.Params[*curParamIndex].Name, 59 | method.Params[*curParamIndex+1].Name, 60 | } 61 | } else { 62 | ip.MethodParamNames = [2]string{ 63 | method.Params[*curParamIndex].Name, 64 | } 65 | *curParamIndex += 1 66 | } 67 | 68 | ip.BelongedToMethod = method 69 | 70 | return nil 71 | } 72 | 73 | func (ip *InsertParse) check(method *extract.InterfaceMethod) error { 74 | if len(method.Params) != 2 { 75 | return newMethodSyntaxError(method.Name, "input parameter not equal to 2") 76 | } 77 | 78 | if len(method.Returns) != 2 { 79 | return newMethodSyntaxError(method.Name, "return parameter not equal to 2") 80 | } 81 | 82 | if method.Params[0].Type.RealName() != "context.Context" { 83 | return newMethodSyntaxError(method.Name, "the first parameter in the input parameters "+ 84 | "should be context.Context") 85 | } 86 | 87 | if method.Returns[1].RealName() != "error" { 88 | return newMethodSyntaxError(method.Name, "the second parameter in the return parameters "+ 89 | "should be error") 90 | } 91 | 92 | if _, ok := method.Params[1].Type.(code.StarExprType); ok { 93 | if method.Returns[0].RealName() != "interface{}" { 94 | return newMethodSyntaxError(method.Name, "inconsistent types, the first parameter in the "+ 95 | "return parameters should be interface{}") 96 | } 97 | ip.OperateMode = OperateOne 98 | } else if _, ok = method.Params[1].Type.(code.SliceType); ok { 99 | if method.Returns[0].RealName() != "[]interface{}" { 100 | return newMethodSyntaxError(method.Name, "inconsistent types, the first parameter in the "+ 101 | "return parameters should be []interface{}") 102 | } 103 | ip.OperateMode = OperateMany 104 | } else { 105 | return newMethodSyntaxError(method.Name, "the first parameter in the return parameters "+ 106 | "should be interface{} or []interface{}") 107 | } 108 | 109 | return nil 110 | } 111 | -------------------------------------------------------------------------------- /pkg/curd/parse/operation.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package parse 18 | 19 | type Operation interface { 20 | GetOperationName() string 21 | } 22 | -------------------------------------------------------------------------------- /pkg/curd/template/base.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import ( 20 | "bytes" 21 | "fmt" 22 | "text/template" 23 | ) 24 | 25 | var baseTemplate = `// Code generated by cwgo ({{.Version}}). DO NOT EDIT. 26 | 27 | package {{.PackageName}} 28 | 29 | import ( 30 | {{.GetImports}} 31 | )` + "\n" 32 | 33 | type BaseRender struct { 34 | Version string // cwgo version 35 | PackageName string // package name in target generation go file 36 | Imports map[string]string // key:import path value:import name 37 | } 38 | 39 | func (bt *BaseRender) RenderObj(buffer *bytes.Buffer) error { 40 | if err := templateRender(buffer, "baseTemplate", baseTemplate, bt); err != nil { 41 | return err 42 | } 43 | return nil 44 | } 45 | 46 | func (bt *BaseRender) GetImports() string { 47 | result := "" 48 | 49 | for key, value := range bt.Imports { 50 | if value != "" { 51 | result += fmt.Sprintf("\tvalue "+`"%s"`+"\n", key) 52 | } else { 53 | result += fmt.Sprintf("\t"+`"%s"`+"\n", key) 54 | } 55 | } 56 | 57 | return result 58 | } 59 | 60 | func templateRender(buffer *bytes.Buffer, templateName, parseText string, data any) error { 61 | tmpl, err := template.New(templateName).Parse(parseText) 62 | if err != nil { 63 | return err 64 | } 65 | 66 | if err = tmpl.Execute(buffer, data); err != nil { 67 | return err 68 | } 69 | 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /pkg/curd/template/function.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import ( 20 | "bytes" 21 | 22 | "github.com/cloudwego/cwgo/pkg/curd/code" 23 | ) 24 | 25 | var funcTemplate = `{{.Comment}} 26 | func {{.Name}}{{.Params.GetCode}} {{.Returns.GetCode}} { 27 | {{.FuncBody.GetCode}} 28 | }` + "\n" 29 | 30 | type FuncRender struct { 31 | Name string 32 | Comment string 33 | Params code.Params 34 | Returns code.Returns 35 | FuncBody code.Body 36 | } 37 | 38 | func (fr *FuncRender) RenderObj(buffer *bytes.Buffer) error { 39 | if err := templateRender(buffer, "funcTemplate", funcTemplate, fr); err != nil { 40 | return err 41 | } 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /pkg/curd/template/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import ( 20 | "bytes" 21 | 22 | "github.com/cloudwego/cwgo/pkg/curd/code" 23 | ) 24 | 25 | var interfaceTemplate = `{{.Comment}} 26 | type {{.Name}} interface { 27 | {{.Methods.GetCode}} 28 | }` + "\n" 29 | 30 | type InterfaceRender struct { 31 | Name string 32 | Comment string 33 | Methods code.InterfaceMethods 34 | } 35 | 36 | func (ir *InterfaceRender) RenderObj(buffer *bytes.Buffer) error { 37 | if err := templateRender(buffer, "interfaceTemplate", interfaceTemplate, ir); err != nil { 38 | return err 39 | } 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /pkg/curd/template/method.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import ( 20 | "bytes" 21 | 22 | "github.com/cloudwego/cwgo/pkg/curd/code" 23 | ) 24 | 25 | var methodTemplate = `{{.Comment}} 26 | func {{.MethodReceiver.GetCode}} {{.Name}}{{.Params.GetCode}} {{.Returns.GetCode}} { 27 | {{.MethodBody.GetCode}} 28 | }` + "\n" 29 | 30 | type MethodRender struct { 31 | Name string 32 | Comment string 33 | MethodReceiver code.MethodReceiver 34 | Params code.Params 35 | Returns code.Returns 36 | MethodBody code.Body 37 | } 38 | 39 | func (mr *MethodRender) RenderObj(buffer *bytes.Buffer) error { 40 | if err := templateRender(buffer, "methodTemplate", methodTemplate, mr); err != nil { 41 | return err 42 | } 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /pkg/curd/template/render.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import "bytes" 20 | 21 | type Render interface { 22 | RenderObj(buffer *bytes.Buffer) error 23 | } 24 | -------------------------------------------------------------------------------- /pkg/curd/template/struct.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import ( 20 | "bytes" 21 | 22 | "github.com/cloudwego/cwgo/pkg/curd/code" 23 | ) 24 | 25 | var structTemplate = `{{.Comment}} 26 | type {{.Name}} struct { 27 | {{.StructFields.GetCode}} 28 | }` + "\n" 29 | 30 | type StructRender struct { 31 | Name string 32 | Comment string 33 | StructFields code.StructFields 34 | } 35 | 36 | func (sr *StructRender) RenderObj(buffer *bytes.Buffer) error { 37 | if err := templateRender(buffer, "structTemplate", structTemplate, sr); err != nil { 38 | return err 39 | } 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /pkg/curd/template/template.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package template 18 | 19 | import "bytes" 20 | 21 | type Template struct { 22 | Renders []Render 23 | } 24 | 25 | func (t *Template) AddRender(render Render) { 26 | t.Renders = append(t.Renders, render) 27 | } 28 | 29 | func (t *Template) Build() (*bytes.Buffer, error) { 30 | buffer := new(bytes.Buffer) 31 | 32 | for _, render := range t.Renders { 33 | if err := render.RenderObj(buffer); err != nil { 34 | return nil, err 35 | } 36 | } 37 | 38 | return buffer, nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/fallback/fallback.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package fallback 18 | 19 | import ( 20 | "bytes" 21 | "os" 22 | "strings" 23 | 24 | "github.com/cloudwego/cwgo/config" 25 | "github.com/cloudwego/cwgo/pkg/consts" 26 | "github.com/cloudwego/hertz/cmd/hz/app" 27 | "github.com/cloudwego/hertz/cmd/hz/util/logs" 28 | "github.com/cloudwego/kitex" 29 | kargs "github.com/cloudwego/kitex/tool/cmd/kitex/args" 30 | "github.com/cloudwego/kitex/tool/internal_pkg/pluginmode/thriftgo" 31 | ) 32 | 33 | func Fallback(c *config.FallbackArgument) error { 34 | switch c.ToolType { 35 | case consts.KitexTool: 36 | os.Args = c.Args 37 | var args kargs.Arguments 38 | args.ParseArgs(kitex.Version) 39 | 40 | out := new(bytes.Buffer) 41 | cmd := args.BuildCmd(out) 42 | err := cmd.Run() 43 | if err != nil { 44 | if args.Use != "" { 45 | out := strings.TrimSpace(out.String()) 46 | if strings.HasSuffix(out, thriftgo.TheUseOptionMessage) { 47 | os.Exit(0) 48 | } 49 | } 50 | os.Exit(1) 51 | } 52 | case consts.Hz: 53 | os.Args = c.Args 54 | defer func() { 55 | logs.Flush() 56 | }() 57 | 58 | cli := app.Init() 59 | err := cli.Run(os.Args) 60 | if err != nil { 61 | logs.Errorf("%v\n", err) 62 | } 63 | } 64 | return nil 65 | } 66 | -------------------------------------------------------------------------------- /pkg/job/template.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package job 18 | 19 | const jobTemplate = `package job 20 | 21 | // Run is an example function job 22 | func Run() { 23 | // TODO: fill with your own logic 24 | 25 | } 26 | ` 27 | 28 | const jobMainTemplate = `// Code generated by cwgo ({{.Version}}). DO NOT EDIT. 29 | package main 30 | 31 | import ( 32 | "log" 33 | schedule "{{.PackagePrefix}}" 34 | ) 35 | 36 | func main() { 37 | err := schedule.Run() 38 | if err != nil { 39 | log.Fatalf("job failed: %v", err) 40 | } 41 | } 42 | 43 | ` 44 | 45 | const jobScheduleTemplate = `package schedule 46 | 47 | import ( 48 | "sync" 49 | {{- range .JobInfos }} 50 | {{.JobName}} "{{.PackagePrefix}}/{{.JobName}}/job" 51 | {{- end }} 52 | ) 53 | 54 | func Run() error { 55 | var wg sync.WaitGroup 56 | 57 | {{- range .JobInfos }} 58 | wg.Add(1) 59 | go func() { 60 | defer wg.Done() 61 | {{.JobName}}.Run() 62 | }() 63 | {{- end }} 64 | 65 | wg.Wait() 66 | return nil 67 | } 68 | 69 | ` 70 | 71 | const scriptTemplate = `#!/bin/bash 72 | 73 | echo "Building job binary..." 74 | go build -o job ../cmd/main.go 75 | 76 | if [ $? -ne 0 ]; then 77 | echo "Error: Failed to build job." 78 | exit 1 79 | fi 80 | 81 | echo "Running job..." 82 | ./job 83 | 84 | if [ $? -ne 0 ]; then 85 | echo "Error: job execution failed." 86 | exit 1 87 | fi 88 | 89 | echo "job Done." 90 | 91 | rm job 92 | 93 | if [ $? -ne 0 ]; then 94 | echo "Error: Failed to remove job binary." 95 | exit 1 96 | fi 97 | 98 | ` 99 | -------------------------------------------------------------------------------- /pkg/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package model 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | 23 | "gorm.io/rawsql" 24 | 25 | "github.com/cloudwego/cwgo/config" 26 | "github.com/cloudwego/cwgo/pkg/consts" 27 | 28 | "gorm.io/gen" 29 | "gorm.io/gorm" 30 | ) 31 | 32 | var ( 33 | db *gorm.DB 34 | err error 35 | ) 36 | 37 | func Model(c *config.ModelArgument) error { 38 | dialector := config.OpenTypeFuncMap[consts.DataBaseType(c.Type)] 39 | 40 | if c.SQLDir != "" { 41 | db, err = gorm.Open(rawsql.New(rawsql.Config{ 42 | FilePath: []string{c.SQLDir}, 43 | })) 44 | } else { 45 | db, err = gorm.Open(dialector(c.DSN)) 46 | } 47 | if err != nil { 48 | return err 49 | } 50 | 51 | genConfig := gen.Config{ 52 | OutPath: c.OutPath, 53 | OutFile: c.OutFile, 54 | ModelPkgPath: c.ModelPkgName, 55 | WithUnitTest: c.WithUnitTest, 56 | FieldNullable: c.FieldNullable, 57 | FieldSignable: c.FieldSignable, 58 | FieldWithIndexTag: c.FieldWithIndexTag, 59 | FieldWithTypeTag: c.FieldWithTypeTag, 60 | } 61 | 62 | if len(c.ExcludeTables) > 0 || c.Type == string(consts.Sqlite) { 63 | genConfig.WithTableNameStrategy(func(tableName string) (targetTableName string) { 64 | if c.Type == string(consts.Sqlite) && strings.HasPrefix(tableName, "sqlite") { 65 | return "" 66 | } 67 | if len(c.ExcludeTables) > 0 { 68 | for _, table := range c.ExcludeTables { 69 | if tableName == table { 70 | return "" 71 | } 72 | } 73 | } 74 | return tableName 75 | }) 76 | } 77 | 78 | g := gen.NewGenerator(genConfig) 79 | 80 | g.UseDB(db) 81 | 82 | models, err := genModels(g, db, c.Tables) 83 | if err != nil { 84 | return err 85 | } 86 | 87 | if !c.OnlyModel { 88 | g.ApplyBasic(models...) 89 | } 90 | 91 | g.Execute() 92 | return nil 93 | } 94 | 95 | func genModels(g *gen.Generator, db *gorm.DB, tables []string) (models []interface{}, err error) { 96 | var tablesNameList []string 97 | if len(tables) == 0 { 98 | tablesNameList, err = db.Migrator().GetTables() 99 | if err != nil { 100 | return nil, fmt.Errorf("migrator get all tables fail: %w", err) 101 | } 102 | } else { 103 | tablesNameList = tables 104 | } 105 | 106 | models = make([]interface{}, len(tablesNameList)) 107 | for i, tableName := range tablesNameList { 108 | models[i] = g.GenerateModel(tableName) 109 | } 110 | return models, nil 111 | } 112 | -------------------------------------------------------------------------------- /pkg/server/check.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package server 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "os" 23 | "path/filepath" 24 | "strings" 25 | 26 | "github.com/cloudwego/cwgo/config" 27 | "github.com/cloudwego/cwgo/pkg/common/utils" 28 | "github.com/cloudwego/cwgo/pkg/consts" 29 | ) 30 | 31 | func check(sa *config.ServerArgument) error { 32 | if sa.Type != consts.RPC && sa.Type != consts.HTTP { 33 | return errors.New("generate type not supported") 34 | } 35 | 36 | if sa.Registry != "" && 37 | sa.Registry != consts.Zk && 38 | sa.Registry != consts.Nacos && 39 | sa.Registry != consts.Etcd && 40 | sa.Registry != consts.Polaris { 41 | return errors.New("unsupported registry") 42 | } 43 | 44 | if sa.ServerName == "" { 45 | return errors.New("must specify server name") 46 | } 47 | 48 | // handle cwd and output dir 49 | dir, err := os.Getwd() 50 | if err != nil { 51 | return fmt.Errorf("get current path failed: %s", err) 52 | } 53 | sa.Cwd = dir 54 | if sa.OutDir == "" { 55 | sa.OutDir = dir 56 | } 57 | if !filepath.IsAbs(sa.OutDir) { 58 | ap := filepath.Join(sa.Cwd, sa.OutDir) 59 | sa.OutDir = ap 60 | } 61 | 62 | gopath, err := utils.GetGOPATH() 63 | if err != nil { 64 | return fmt.Errorf("get gopath failed: %s", err) 65 | } 66 | if gopath == "" { 67 | return fmt.Errorf("GOPATH is not set") 68 | } 69 | 70 | sa.GoPath = gopath 71 | sa.GoSrc = filepath.Join(gopath, consts.Src) 72 | 73 | // Generate the project under gopath, use the relative path as the package name 74 | if strings.HasPrefix(sa.Cwd, sa.GoSrc) { 75 | if goPkg, err := filepath.Rel(sa.GoSrc, sa.Cwd); err != nil { 76 | return fmt.Errorf("get relative path to GOPATH/src failed: %s", err) 77 | } else { 78 | sa.GoPkg = goPkg 79 | } 80 | 81 | if sa.GoMod == "" { 82 | if utils.IsWindows() { 83 | sa.GoMod = strings.ReplaceAll(sa.GoPkg, consts.BackSlash, consts.Slash) 84 | } else { 85 | sa.GoMod = sa.GoPkg 86 | } 87 | } 88 | 89 | if sa.GoMod != "" { 90 | if utils.IsWindows() { 91 | goPkgSlash := strings.ReplaceAll(sa.GoPkg, consts.BackSlash, consts.Slash) 92 | if goPkgSlash != sa.GoMod { 93 | return fmt.Errorf("module name: %s is not the same with GoPkg under GoPath: %s", sa.GoMod, goPkgSlash) 94 | } 95 | } else { 96 | if sa.GoMod != sa.GoPkg { 97 | return fmt.Errorf("module name: %s is not the same with GoPkg under GoPath: %s", sa.GoMod, sa.GoPkg) 98 | } 99 | } 100 | } 101 | } 102 | return nil 103 | } 104 | -------------------------------------------------------------------------------- /tpl/init.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package tpl 18 | 19 | import ( 20 | "embed" 21 | "os" 22 | "path" 23 | "strings" 24 | 25 | "github.com/Masterminds/sprig/v3" 26 | "github.com/cloudwego/cwgo/pkg/consts" 27 | "github.com/cloudwego/kitex/tool/internal_pkg/generator" 28 | ) 29 | 30 | //go:embed kitex 31 | var kitexTpl embed.FS 32 | 33 | //go:embed hertz 34 | var hertzTpl embed.FS 35 | 36 | var ( 37 | KitexDir = path.Join(os.TempDir(), consts.Kitex) 38 | HertzDir = path.Join(os.TempDir(), consts.Hertz) 39 | ) 40 | 41 | func Init() { 42 | os.RemoveAll(KitexDir) 43 | os.RemoveAll(HertzDir) 44 | os.Mkdir(KitexDir, 0o755) 45 | os.Mkdir(HertzDir, 0o755) 46 | initDir(kitexTpl, consts.Kitex, KitexDir) 47 | initDir(hertzTpl, consts.Hertz, HertzDir) 48 | } 49 | 50 | func initDir(fs embed.FS, srcDir, dstDir string) { 51 | files, err := fs.ReadDir(srcDir) 52 | if err != nil { 53 | panic(err) 54 | } 55 | for _, f := range files { 56 | 57 | newDstPath := path.Join(dstDir, f.Name()) 58 | newSrcPath := path.Join(srcDir, f.Name()) 59 | 60 | if f.IsDir() { 61 | os.Mkdir(newDstPath, 0o755) 62 | initDir(fs, newSrcPath, newDstPath) 63 | continue 64 | } 65 | 66 | content, err := fs.ReadFile(newSrcPath) 67 | if err != nil { 68 | panic(err) 69 | } 70 | file, err := os.OpenFile(newDstPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o666) 71 | if err != nil { 72 | panic(err) 73 | } 74 | file.Write(content) 75 | file.Close() 76 | } 77 | } 78 | 79 | func RegisterTemplateFunc() { 80 | for k, f := range sprig.FuncMap() { 81 | generator.AddTemplateFunc(k, f) 82 | } 83 | generator.AddTemplateFunc("ToCamel", func(name string) string { 84 | name = strings.Replace(name, "_", " ", -1) 85 | name = strings.Title(name) 86 | return strings.Replace(name, " ", "", -1) 87 | }) 88 | } 89 | -------------------------------------------------------------------------------- /tpl/kitex/client/standard/client_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: /rpc/{{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }}/{{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }}_client.go 2 | update_behavior: 3 | type: cover 4 | body: |- 5 | package {{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }} 6 | import ( 7 | {{- range $path, $aliases := .Imports}} 8 | {{- if not $aliases }} 9 | "{{$path}}" 10 | {{- else if or (eq $path "github.com/cloudwego/kitex/client") (eq $path "github.com/cloudwego/kitex/pkg/serviceinfo")}} 11 | {{- else}} 12 | {{- range $alias, $is := $aliases}} 13 | {{$alias}} "{{$path}}" 14 | {{- end}} 15 | {{- end}} 16 | {{- end}} 17 | 18 | "{{.ImportPath}}/{{ToLower .ServiceName}}" 19 | "github.com/cloudwego/kitex/client" 20 | "github.com/cloudwego/kitex/client/callopt" 21 | ) 22 | 23 | type RPCClient interface { 24 | KitexClient() {{ToLower .ServiceName}}.Client 25 | Service() string 26 | {{- range .AllMethods}} 27 | {{- if or .ClientStreaming .ServerStreaming}} 28 | {{.Name}}(ctx context.Context {{if not .ClientStreaming}}{{range .Args}}, {{.RawName}} {{.Type}}{{end}}{{end}}, callOptions ...callopt.Option ) (stream {{ToLower .ServiceName}}.{{.ServiceName}}_{{.RawName}}Client, err error) 29 | {{- else}} 30 | {{.Name}}(ctx context.Context {{range .Args}}, {{.RawName}} {{.Type}}{{end}}, callOptions ...callopt.Option ) ({{if not .Void}}r {{.Resp.Type}}, {{end}}err error) 31 | {{- end}} 32 | {{- end}} 33 | } 34 | 35 | func NewRPCClient(dstService string, opts ...client.Option) (RPCClient, error) { 36 | kitexClient, err := {{ToLower .ServiceName}}.NewClient(dstService, opts...) 37 | if err != nil { 38 | return nil, err 39 | } 40 | cli := &clientImpl{ 41 | service: dstService, 42 | kitexClient: kitexClient, 43 | } 44 | 45 | return cli, nil 46 | } 47 | 48 | type clientImpl struct { 49 | service string 50 | kitexClient {{ToLower .ServiceName}}.Client 51 | } 52 | 53 | func (c *clientImpl) Service() string { 54 | return c.service 55 | } 56 | 57 | func (c *clientImpl) KitexClient() {{ToLower .ServiceName}}.Client { 58 | return c.kitexClient 59 | } 60 | {{range .AllMethods}} 61 | {{- if or .ClientStreaming .ServerStreaming}} 62 | func (c *clientImpl) {{.Name}}(ctx context.Context {{if not .ClientStreaming}}{{range .Args}}, {{.RawName}} {{.Type}}{{end}}{{end}}, callOptions ...callopt.Option ) (stream {{ToLower .ServiceName}}.{{.ServiceName}}_{{.RawName}}Client, err error) { 63 | return c.kitexClient.{{.Name}}(ctx{{if not .ClientStreaming}}{{range .Args}}, {{.RawName}}{{end}}{{end}}, callOptions...) 64 | } 65 | {{- else}} 66 | func (c *clientImpl) {{.Name}}(ctx context.Context {{range .Args}}, {{.RawName}} {{.Type}}{{end}}, callOptions ...callopt.Option ) ({{if not .Void}}r {{.Resp.Type}}, {{end}}err error) { 67 | return c.kitexClient.{{.Name}}(ctx{{range .Args}}, {{.RawName}}{{end}}, callOptions...) 68 | } 69 | {{- end}} 70 | {{end}} -------------------------------------------------------------------------------- /tpl/kitex/client/standard/default_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: /rpc/{{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }}/{{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }}_default.go 2 | update_behavior: 3 | type: cover 4 | body: |- 5 | package {{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }} 6 | import ( 7 | {{- range $path, $aliases := .Imports}} 8 | {{- if not $aliases }} 9 | "{{$path}}" 10 | {{- else if or (eq $path "github.com/cloudwego/kitex/client") (eq $path "github.com/cloudwego/kitex/pkg/serviceinfo")}} 11 | {{- else}} 12 | {{- range $alias, $is := $aliases}} 13 | {{$alias}} "{{$path}}" 14 | {{- end}} 15 | {{- end}} 16 | {{- end}} 17 | {{- if .HasStreaming }} 18 | "{{.ImportPath}}/{{ToLower .ServiceName}}" 19 | {{end}} 20 | "github.com/cloudwego/kitex/client/callopt" 21 | "github.com/cloudwego/kitex/pkg/klog" 22 | ) 23 | {{range .AllMethods}} 24 | {{- if or .ClientStreaming .ServerStreaming}} 25 | func {{.Name}} (ctx context.Context {{if not .ClientStreaming}}{{range .Args}}, {{.RawName}} {{.Type}}{{end}}{{end}}, callOptions ...callopt.Option) (stream {{ToLower .ServiceName}}.{{.ServiceName}}_{{.RawName}}Client, err error){ 26 | stream, err = defaultClient.{{.Name}}(ctx {{if not .ClientStreaming}}{{range .Args}}, {{.RawName}} {{end}}{{end}}, callOptions...) 27 | if err != nil { 28 | klog.CtxErrorf(ctx, "{{.Name}} call failed,err =%+v", err) 29 | return nil, err 30 | } 31 | return stream, nil 32 | } 33 | {{ else }} 34 | {{- if .Oneway}} 35 | func {{.Name}}(ctx context.Context, {{- range .Args}} {{LowerFirst .Name}} {{.Type}}, {{end}} callOptions ...callopt.Option) (err error){ 36 | err = defaultClient.{{.Name}}(ctx, {{- range .Args}} {{LowerFirst .Name}}, {{end}} callOptions...) 37 | if err != nil { 38 | klog.CtxErrorf(ctx, "{{.Name}} call failed,err =%+v", err) 39 | return err 40 | } 41 | return nil 42 | } 43 | {{else -}} 44 | func {{.Name}}(ctx context.Context, {{range .Args}} {{LowerFirst .Name}} {{.Type}} ,{{end}} callOptions ...callopt.Option) (resp {{.Resp.Type}}, err error){ 45 | resp, err = defaultClient.{{.Name}}(ctx, {{- range .Args}} {{LowerFirst .Name}}, {{end}} callOptions...) 46 | if err != nil { 47 | klog.CtxErrorf(ctx, "{{.Name}} call failed,err =%+v", err) 48 | return nil,err 49 | } 50 | return resp, nil 51 | } 52 | {{end}} 53 | {{end}} 54 | {{end}} -------------------------------------------------------------------------------- /tpl/kitex/client/standard/init_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: /rpc/{{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }}/{{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }}_init.go 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | package {{ ReplaceString (ReplaceString .RealServiceName "." "_" -1) "/" "_" -1 }} 6 | import ( 7 | "sync" 8 | 9 | "github.com/cloudwego/kitex/client" 10 | {{- if eq .Codec "thrift"}} 11 | "github.com/cloudwego/kitex/pkg/transmeta" 12 | "github.com/cloudwego/kitex/transport" 13 | {{- end }} 14 | ) 15 | var ( 16 | // todo edit custom config 17 | defaultClient RPCClient 18 | defaultDstService = "{{.RealServiceName}}" 19 | defaultClientOpts = []client.Option{ 20 | client.WithHostPorts("127.0.0.1:8888"), 21 | {{- if eq .Codec "thrift"}} 22 | client.WithMetaHandler(transmeta.ClientTTHeaderHandler), 23 | client.WithTransportProtocol(transport.TTHeader), 24 | {{- end}} 25 | } 26 | once sync.Once 27 | ) 28 | 29 | func init() { 30 | DefaultClient() 31 | } 32 | 33 | func DefaultClient() RPCClient { 34 | once.Do(func() { 35 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 36 | }) 37 | return defaultClient 38 | } 39 | 40 | func newClient(dstService string, opts ...client.Option) RPCClient { 41 | c, err := NewRPCClient(dstService, opts...) 42 | if err != nil { 43 | panic("failed to init client: " + err.Error()) 44 | } 45 | return c 46 | } 47 | 48 | func InitClient(dstService string, opts ...client.Option) { 49 | defaultClient = newClient(dstService, opts...) 50 | } 51 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/bootstrap_sh_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: script/bootstrap.sh 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | #! /usr/bin/env bash 6 | CURDIR=$(cd $(dirname $0); pwd) 7 | echo "$CURDIR/bin/{{.RealServiceName}}" 8 | exec "$CURDIR/bin/{{.RealServiceName}}" -------------------------------------------------------------------------------- /tpl/kitex/server/standard/build_sh_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: build.sh 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | #!/usr/bin/env bash 6 | RUN_NAME="{{.RealServiceName}}" 7 | mkdir -p output/bin output/conf 8 | cp script/* output/ 9 | cp -r conf/* output/conf 10 | chmod +x output/bootstrap.sh 11 | go build -o output/bin/${RUN_NAME} 12 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/conf_dev_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: conf/dev/conf.yaml 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | kitex: 6 | service: "{{.RealServiceName}}" 7 | address: ":8888" 8 | log_level: info 9 | log_file_name: "log/kitex.log" 10 | log_max_size: 10 11 | log_max_age: 3 12 | log_max_backups: 50 13 | 14 | registry: 15 | registry_address: 16 | - 127.0.0.1:2379 17 | username: "" 18 | password: "" 19 | 20 | mysql: 21 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 22 | 23 | redis: 24 | address: "127.0.0.1:6379" 25 | username: "" 26 | password: "" 27 | db: 0 28 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/conf_online_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: conf/online/conf.yaml 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | kitex: 6 | service: "{{.RealServiceName}}" 7 | address: ":8888" 8 | log_level: info 9 | log_file_name: "log/kitex.log" 10 | log_max_size: 10 11 | log_max_age: 3 12 | log_max_backups: 50 13 | 14 | registry: 15 | registry_address: 16 | - 127.0.0.1:2379 17 | username: "" 18 | password: "" 19 | 20 | mysql: 21 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 22 | 23 | redis: 24 | address: "127.0.0.1:6379" 25 | username: "" 26 | password: "" 27 | db: 0 28 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/conf_test_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: conf/test/conf.yaml 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | kitex: 6 | service: "{{.RealServiceName}}" 7 | address: ":8888" 8 | log_level: info 9 | log_file_name: "log/kitex.log" 10 | log_max_size: 10 11 | log_max_age: 3 12 | log_max_backups: 50 13 | 14 | registry: 15 | registry_address: 16 | - 127.0.0.1:2379 17 | username: "" 18 | password: "" 19 | 20 | mysql: 21 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 22 | 23 | redis: 24 | address: "127.0.0.1:6379" 25 | username: "" 26 | password: "" 27 | db: 0 28 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/conf_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: conf/conf.go 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | package conf 6 | 7 | import ( 8 | "io/ioutil" 9 | "os" 10 | "path/filepath" 11 | "sync" 12 | 13 | "github.com/cloudwego/kitex/pkg/klog" 14 | "github.com/kr/pretty" 15 | "gopkg.in/validator.v2" 16 | "gopkg.in/yaml.v3" 17 | ) 18 | 19 | var ( 20 | conf *Config 21 | once sync.Once 22 | ) 23 | 24 | type Config struct { 25 | Env string 26 | Kitex Kitex `yaml:"kitex"` 27 | MySQL MySQL `yaml:"mysql"` 28 | Redis Redis `yaml:"redis"` 29 | Registry Registry `yaml:"registry"` 30 | } 31 | 32 | type MySQL struct { 33 | DSN string `yaml:"dsn"` 34 | } 35 | 36 | type Redis struct { 37 | Address string `yaml:"address"` 38 | Username string `yaml:"username"` 39 | Password string `yaml:"password"` 40 | DB int `yaml:"db"` 41 | } 42 | 43 | type Kitex struct { 44 | Service string `yaml:"service"` 45 | Address string `yaml:"address"` 46 | LogLevel string `yaml:"log_level"` 47 | LogFileName string `yaml:"log_file_name"` 48 | LogMaxSize int `yaml:"log_max_size"` 49 | LogMaxBackups int `yaml:"log_max_backups"` 50 | LogMaxAge int `yaml:"log_max_age"` 51 | } 52 | 53 | type Registry struct { 54 | RegistryAddress []string `yaml:"registry_address"` 55 | Username string `yaml:"username"` 56 | Password string `yaml:"password"` 57 | } 58 | 59 | // GetConf gets configuration instance 60 | func GetConf() *Config { 61 | once.Do(initConf) 62 | return conf 63 | } 64 | 65 | func initConf() { 66 | prefix := "conf" 67 | confFileRelPath := filepath.Join(prefix, filepath.Join(GetEnv(), "conf.yaml")) 68 | content, err := ioutil.ReadFile(confFileRelPath) 69 | if err != nil { 70 | panic(err) 71 | } 72 | conf = new(Config) 73 | err = yaml.Unmarshal(content, conf) 74 | if err != nil { 75 | klog.Error("parse yaml error - %v", err) 76 | panic(err) 77 | } 78 | if err := validator.Validate(conf); err != nil { 79 | klog.Error("validate config error - %v", err) 80 | panic(err) 81 | } 82 | conf.Env = GetEnv() 83 | pretty.Printf("%+v\n", conf) 84 | } 85 | 86 | func GetEnv() string { 87 | e := os.Getenv("GO_ENV") 88 | if len(e) == 0 { 89 | return "test" 90 | } 91 | return e 92 | } 93 | 94 | func LogLevel() klog.Level { 95 | level := GetConf().Kitex.LogLevel 96 | switch level { 97 | case "trace": 98 | return klog.LevelTrace 99 | case "debug": 100 | return klog.LevelDebug 101 | case "info": 102 | return klog.LevelInfo 103 | case "notice": 104 | return klog.LevelNotice 105 | case "warn": 106 | return klog.LevelWarn 107 | case "error": 108 | return klog.LevelError 109 | case "fatal": 110 | return klog.LevelFatal 111 | default: 112 | return klog.LevelInfo 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/dal_init.yaml: -------------------------------------------------------------------------------- 1 | path: biz/dal/init.go 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | package dal 6 | 7 | import ( 8 | "{{.Module}}/biz/dal/mysql" 9 | "{{.Module}}/biz/dal/redis" 10 | ) 11 | 12 | func Init() { 13 | redis.Init() 14 | mysql.Init() 15 | } -------------------------------------------------------------------------------- /tpl/kitex/server/standard/docker_compose.yaml: -------------------------------------------------------------------------------- 1 | path: docker-compose.yaml 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | version: '3' 6 | services: 7 | mysql: 8 | image: 'mysql:latest' 9 | ports: 10 | - 3306:3306 11 | environment: 12 | - MYSQL_DATABASE=gorm 13 | - MYSQL_USER=gorm 14 | - MYSQL_PASSWORD=gorm 15 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 16 | redis: 17 | image: 'redis:latest' 18 | ports: 19 | - 6379:6379 -------------------------------------------------------------------------------- /tpl/kitex/server/standard/handler_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: handler.go 2 | update_behavior: 3 | type: append 4 | key: "{{ (index .Methods 0).Name }}" 5 | append_tpl: |- 6 | {{range .AllMethods}} 7 | {{- if or .ClientStreaming .ServerStreaming}} 8 | func (s *{{$.ServiceName}}Impl) {{.Name}}({{if not .ClientStreaming}}{{range .Args}}{{LowerFirst .Name}} {{.Type}}, {{end}}{{end}}stream {{.PkgRefName}}.{{.ServiceName}}_{{.RawName}}Server) (err error) { 9 | ctx := context.Background() 10 | err = service.New{{.Name}}Service(ctx).Run({{if not .ClientStreaming}}{{range .Args}}{{LowerFirst .Name}}, {{end}}{{end}}stream) 11 | return 12 | } 13 | {{- else}} 14 | {{- if .Void}} 15 | // {{.Name}} implements the {{.ServiceName}}Impl interface. 16 | {{- if .Oneway}} 17 | // Oneway methods are not guaranteed to receive 100% of the requests sent by the client. 18 | // And the client may not perceive the loss of requests due to network packet loss. 19 | // If possible, do not use oneway methods. 20 | {{- end}} 21 | func (s *{{$.ServiceName}}Impl) {{.Name}}(ctx context.Context {{- range .Args}}, {{LowerFirst .Name}} {{.Type}}{{end}}) (err error) { 22 | err = service.New{{.Name}}Service(ctx).Run({{range .Args}} {{LowerFirst .Name}}, {{end}}) 23 | 24 | return err 25 | } 26 | {{else -}} 27 | // {{.Name}} implements the {{.ServiceName}}Impl interface. 28 | func (s *{{$.ServiceName}}Impl) {{.Name}}(ctx context.Context {{range .Args}}, {{LowerFirst .Name}} {{.Type}}{{end}} ) (resp {{.Resp.Type}}, err error) { 29 | resp, err = service.New{{.Name}}Service(ctx).Run({{range .Args}} {{LowerFirst .Name}}, {{end}}) 30 | 31 | return resp, err 32 | } 33 | {{end}} 34 | {{end}} 35 | {{end}} 36 | import_tpl: 37 | - "{{ ( index (index (index .Methods 0).Args 0).Deps 0).ImportPath }}" 38 | - "{{ ( index (index .Methods 0).Resp.Deps 0).ImportPath }}" 39 | 40 | body: |- 41 | package main 42 | import ( 43 | {{- range $path, $aliases := .Imports}} 44 | {{- if not $aliases }} 45 | "{{$path}}" 46 | {{- else if or (eq $path "github.com/cloudwego/kitex/client") (eq $path "github.com/cloudwego/kitex/pkg/serviceinfo")}} 47 | {{- else}} 48 | {{- range $alias, $is := $aliases}} 49 | {{$alias}} "{{$path}}" 50 | {{- end}} 51 | {{- end}} 52 | {{- end}} 53 | "{{.Module}}/biz/service" 54 | ) 55 | 56 | // {{.ServiceName}}Impl implements the last service interface defined in the IDL. 57 | type {{.ServiceName}}Impl struct{} 58 | 59 | {{range .AllMethods}} 60 | {{- if or .ClientStreaming .ServerStreaming}} 61 | func (s *{{$.ServiceName}}Impl) {{.Name}}({{if not .ClientStreaming}}{{range .Args}}{{LowerFirst .Name}} {{.Type}}, {{end}}{{end}}stream {{.PkgRefName}}.{{.ServiceName}}_{{.RawName}}Server) (err error) { 62 | ctx := context.Background() 63 | err = service.New{{.Name}}Service(ctx).Run({{if not .ClientStreaming}}{{range .Args}}{{LowerFirst .Name}}, {{end}}{{end}}stream) 64 | return 65 | } 66 | {{- else}} 67 | {{- if .Void}} 68 | // {{.Name}} implements the {{.ServiceName}}Impl interface. 69 | {{- if .Oneway}} 70 | // Oneway methods are not guaranteed to receive 100% of the requests sent by the client. 71 | // And the client may not perceive the loss of requests due to network packet loss. 72 | // If possible, do not use oneway methods. 73 | {{- end}} 74 | func (s *{{$.ServiceName}}Impl) {{.Name}}(ctx context.Context {{- range .Args}}, {{LowerFirst .Name}} {{.Type}}{{end}}) (err error) { 75 | err = service.New{{.Name}}Service(ctx).Run({{range .Args}} {{LowerFirst .Name}}, {{end}}) 76 | 77 | return err 78 | } 79 | {{else -}} 80 | // {{.Name}} implements the {{.ServiceName}}Impl interface. 81 | func (s *{{$.ServiceName}}Impl) {{.Name}}(ctx context.Context {{range .Args}}, {{LowerFirst .Name}} {{.Type}}{{end}} ) (resp {{.Resp.Type}}, err error) { 82 | resp, err = service.New{{.Name}}Service(ctx).Run({{range .Args}} {{LowerFirst .Name}}, {{end}}) 83 | 84 | return resp, err 85 | } 86 | {{end}} 87 | {{end}} 88 | {{end}} -------------------------------------------------------------------------------- /tpl/kitex/server/standard/ignore_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: .gitignore 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | *.o 6 | *.a 7 | *.so 8 | _obj 9 | _test 10 | *.[568vq] 11 | [568vq].out 12 | *.cgo1.go 13 | *.cgo2.c 14 | _cgo_defun.c 15 | _cgo_gotypes.go 16 | _cgo_export.* 17 | _testmain.go 18 | *.exe 19 | *.exe~ 20 | *.test 21 | *.prof 22 | *.rar 23 | *.zip 24 | *.gz 25 | *.psd 26 | *.bmd 27 | *.cfg 28 | *.pptx 29 | *.log 30 | *nohup.out 31 | *settings.pyc 32 | *.sublime-project 33 | *.sublime-workspace 34 | !.gitkeep 35 | .DS_Store 36 | /.idea 37 | /.vscode 38 | /output 39 | *.local.yml -------------------------------------------------------------------------------- /tpl/kitex/server/standard/kitex_yaml.yaml: -------------------------------------------------------------------------------- 1 | path: kitex_info.yaml 2 | update_behavior: 3 | type: cover 4 | body: |- 5 | kitexinfo: 6 | ServiceName: '{{.RealServiceName}}' 7 | ToolVersion: '{{.Version}}' 8 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/main_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: main.go 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | package main 6 | 7 | import ( 8 | "net" 9 | "time" 10 | 11 | "github.com/cloudwego/kitex/pkg/klog" 12 | "github.com/cloudwego/kitex/pkg/rpcinfo" 13 | {{- if eq .Codec "thrift"}} 14 | "github.com/cloudwego/kitex/pkg/transmeta" 15 | {{- end }} 16 | "github.com/cloudwego/kitex/server" 17 | kitexlogrus "github.com/kitex-contrib/obs-opentelemetry/logging/logrus" 18 | "{{.Module}}/conf" 19 | "{{.ImportPath}}/{{ToLower .ServiceName}}" 20 | "go.uber.org/zap/zapcore" 21 | "gopkg.in/natefinch/lumberjack.v2" 22 | ) 23 | 24 | func main() { 25 | opts := kitexInit() 26 | 27 | svr := {{ToLower .ServiceName}}.NewServer(new({{.ServiceName}}Impl), opts...) 28 | 29 | err := svr.Run() 30 | if err != nil { 31 | klog.Error(err.Error()) 32 | } 33 | } 34 | 35 | func kitexInit() (opts []server.Option) { 36 | // address 37 | addr, err := net.ResolveTCPAddr("tcp", conf.GetConf().Kitex.Address) 38 | if err != nil { 39 | panic(err) 40 | } 41 | opts = append(opts, server.WithServiceAddr(addr)) 42 | 43 | // service info 44 | opts = append(opts, server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ 45 | ServiceName: conf.GetConf().Kitex.Service, 46 | })) 47 | 48 | {{- if eq .Codec "thrift"}} 49 | // thrift meta handler 50 | opts = append(opts, server.WithMetaHandler(transmeta.ServerTTHeaderHandler)) 51 | {{- end}} 52 | 53 | // klog 54 | logger := kitexlogrus.NewLogger() 55 | klog.SetLogger(logger) 56 | klog.SetLevel(conf.LogLevel()) 57 | asyncWriter := &zapcore.BufferedWriteSyncer{ 58 | WS: zapcore.AddSync(&lumberjack.Logger{ 59 | Filename: conf.GetConf().Kitex.LogFileName, 60 | MaxSize: conf.GetConf().Kitex.LogMaxSize, 61 | MaxBackups: conf.GetConf().Kitex.LogMaxBackups, 62 | MaxAge: conf.GetConf().Kitex.LogMaxAge, 63 | }), 64 | FlushInterval: time.Minute, 65 | } 66 | klog.SetOutput(asyncWriter) 67 | server.RegisterShutdownHook(func() { 68 | asyncWriter.Sync() 69 | }) 70 | return 71 | } 72 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/mysql.yaml: -------------------------------------------------------------------------------- 1 | path: biz/dal/mysql/init.go 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | package mysql 6 | 7 | import ( 8 | "{{.Module}}/conf" 9 | 10 | "gorm.io/driver/mysql" 11 | "gorm.io/gorm" 12 | ) 13 | 14 | var ( 15 | DB *gorm.DB 16 | err error 17 | ) 18 | 19 | func Init() { 20 | DB, err = gorm.Open(mysql.Open(conf.GetConf().MySQL.DSN), 21 | &gorm.Config{ 22 | PrepareStmt: true, 23 | SkipDefaultTransaction: true, 24 | }, 25 | ) 26 | if err != nil { 27 | panic(err) 28 | } 29 | } -------------------------------------------------------------------------------- /tpl/kitex/server/standard/readme_tpl.yaml: -------------------------------------------------------------------------------- 1 | path: readme.md 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | # *** Project 6 | 7 | ## introduce 8 | 9 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 10 | - Generating the base code for unit tests. 11 | - Provides basic config functions 12 | - Provides the most basic MVC code hierarchy. 13 | 14 | ## Directory structure 15 | 16 | | catalog | introduce | 17 | | ---- | ---- | 18 | | conf | Configuration files | 19 | | main.go | Startup file | 20 | | handler.go | Used for request processing return of response. | 21 | | kitex_gen | kitex generated code | 22 | | biz/service | The actual business logic. | 23 | | biz/dal | Logic for operating the storage layer | 24 | 25 | ## How to run 26 | 27 | ```shell 28 | sh build.sh 29 | sh output/bootstrap.sh 30 | ``` -------------------------------------------------------------------------------- /tpl/kitex/server/standard/redis.yaml: -------------------------------------------------------------------------------- 1 | path: biz/dal/redis/init.go 2 | update_behavior: 3 | type: skip 4 | body: |- 5 | package redis 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/redis/go-redis/v9" 11 | "{{.Module}}/conf" 12 | ) 13 | 14 | var ( 15 | RedisClient *redis.Client 16 | ) 17 | 18 | func Init() { 19 | RedisClient = redis.NewClient(&redis.Options{ 20 | Addr: conf.GetConf().Redis.Address, 21 | Username: conf.GetConf().Redis.Username, 22 | Password: conf.GetConf().Redis.Password, 23 | DB: conf.GetConf().Redis.DB, 24 | }) 25 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 26 | panic(err) 27 | } 28 | } -------------------------------------------------------------------------------- /tpl/kitex/server/standard/service.yaml: -------------------------------------------------------------------------------- 1 | path: biz/service/{{ SnakeString (index .Methods 0).Name }}.go 2 | loop_method: true 3 | update_behavior: 4 | type: skip 5 | body: |- 6 | package service 7 | 8 | import ( 9 | "context" 10 | 11 | {{- range $path, $aliases := ( FilterImports .Imports .Methods )}} 12 | {{- if not $aliases }} 13 | "{{$path}}" 14 | {{- else if or (eq $path "github.com/cloudwego/kitex/client") (eq $path "github.com/cloudwego/kitex/pkg/serviceinfo")}} 15 | {{- else}} 16 | {{- range $alias, $is := $aliases}} 17 | {{$alias}} "{{$path}}" 18 | {{- end}} 19 | {{- end}} 20 | {{- end}} 21 | ) 22 | 23 | {{range .Methods}} 24 | 25 | type {{.Name}}Service struct { 26 | ctx context.Context 27 | } 28 | 29 | {{- if or .ClientStreaming .ServerStreaming}} 30 | 31 | // New{{.Name}}Service new {{.Name}}Service 32 | func New{{.Name}}Service(ctx context.Context) *{{.Name}}Service { 33 | return &{{.Name}}Service{ctx: ctx} 34 | } 35 | 36 | func (s *{{.Name}}Service) Run({{if not .ClientStreaming}}{{range .Args}}{{LowerFirst .Name}} {{.Type}}, {{end}}{{end}}stream {{.PkgRefName}}.{{.ServiceName}}_{{.RawName}}Server) (err error) { 37 | return 38 | } 39 | {{- else}} 40 | {{- if .Void}} 41 | {{- if .Oneway}} 42 | {{- end}} 43 | 44 | // New{{.Name}}Service new {{.Name}}Service 45 | func New{{.Name}}Service(ctx context.Context) *{{.Name}}Service { 46 | return &{{.Name}}Service{ctx: ctx} 47 | } 48 | 49 | // Run create note info 50 | func (s *{{.Name}}Service) Run({{range .Args}}{{LowerFirst .Name}} {{.Type}}, {{end}}) error { 51 | // Finish your business logic. 52 | 53 | return nil 54 | } 55 | {{else}} 56 | 57 | // New{{.Name}}Service new {{.Name}}Service 58 | func New{{.Name}}Service(ctx context.Context) *{{.Name}}Service { 59 | return &{{.Name}}Service{ctx: ctx} 60 | } 61 | 62 | // Run create note info 63 | func (s *{{.Name}}Service) Run({{range .Args}}{{LowerFirst .Name}} {{.Type}}, {{end}}) (resp {{.Resp.Type}}, err error) { 64 | // Finish your business logic. 65 | 66 | return 67 | } 68 | {{end}} 69 | {{end}} 70 | {{end}} 71 | -------------------------------------------------------------------------------- /tpl/kitex/server/standard/service_test.yaml: -------------------------------------------------------------------------------- 1 | path: biz/service/{{ SnakeString (index .Methods 0).Name }}_test.go 2 | loop_method: true 3 | update_behavior: 4 | type: skip 5 | body: |- 6 | package service 7 | 8 | import ( 9 | "context" 10 | "testing" 11 | 12 | {{- range $path, $aliases := ( FilterImports .Imports .Methods )}} 13 | {{- if not $aliases }} 14 | "{{$path}}" 15 | {{- else if or (eq $path "github.com/cloudwego/kitex/client") (eq $path "github.com/cloudwego/kitex/pkg/serviceinfo")}} 16 | {{- else}} 17 | {{- range $alias, $is := $aliases}} 18 | {{$alias}} "{{$path}}" 19 | {{- end}} 20 | {{- end}} 21 | {{- end}} 22 | ) 23 | 24 | {{range .Methods}} 25 | 26 | func Test{{.Name}}_Run(t *testing.T) { 27 | {{- if or .ClientStreaming .ServerStreaming}} 28 | // todo: edit your unit test 29 | {{- else}} 30 | ctx := context.Background() 31 | s := New{{.Name}}Service(ctx) 32 | // init req and assert value 33 | {{range .Args}} 34 | {{LowerFirst .Name}} := &{{NotPtr .Type}}{} 35 | {{end}} 36 | 37 | {{- if .Void}} 38 | {{- if .Oneway}} 39 | {{- end}} 40 | 41 | err := s.Run({{range .Args}}{{LowerFirst .Name}}, {{end}}) 42 | if err != nil { 43 | t.Errorf("unexpected error: %v", err) 44 | } 45 | // todo: edit your unit test 46 | 47 | {{else -}} 48 | resp, err := s.Run({{range .Args}}{{LowerFirst .Name}}, {{end}}) 49 | t.Logf("err: %v", err) 50 | t.Logf("resp: %v", resp) 51 | 52 | // todo: edit your unit test 53 | {{end}} 54 | {{end}} 55 | 56 | } 57 | {{end}} 58 | --------------------------------------------------------------------------------