├── .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 | 
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 |
--------------------------------------------------------------------------------