版本:v1.8
代码规范
在本节中,你将学到与 KubeVela 项目相关的各种代码的代码惯例。不需要一次性学完全篇,但在编码之前,应该提前阅读编码相关的部分。
了解并避免 Go 的使用误区
代码注释
在容易让人感到疑惑的代码处写下注释将会带来很大帮助。
命令行标志应该使用破折号,而不是下划线。
API
根据 RFC3986,URLs 是“大小写敏感”的。KubeVela 对 API URLs 使用蛇形法。
- 例如:
POST /v1/cloud_clusters
- 例如:
命名
在命名接口时,请考虑包的名称,避免重复使用。
- 例如:
storage.Interface
比storage.StorageInterface
好。
- 例如:
在包名中不要使用大写字母、下划线或破折号。
在给包命名时,请考虑父目录的名称。
- 例如 pkg/controllers/autoscaler/foo.go 包名是
package autoscaler
而不是package autoscalercontroller
。 - 包名
package foo
应该和 .go 文件存在的目录名称相匹配。 - 如果引入包的使用者需要消除歧义,可以使用不同的名称来引入包。
- 例如 pkg/controllers/autoscaler/foo.go 包名是
- 锁变量应该被称为
lock
,注意不应使用嵌入结构体来使用锁(使用示例lock sync.Mutex
)。当存在多个锁时,按照 Go 的惯例给每个锁起一个独特的名称 ——stateLock
,mapLock
等。
请确保构建、发布、测试和集群管理脚本能在 macOS 上运行。
KubeVela 的 API 遵循 Kubernetes 的规范。
所有新的包和大多数新的重要功能必须有单元测试。
表驱动的测试是测试多个场景或输入的首选;例如 TestNamespaceAuthorization。
单元测试必须在 macOS 和 Windows 平台上通过,如果有使用 Linux 的独有命令,这个测试用例就必须在 windows 上跳过或输出信息(当运行 Linux 的独有命令时跳过测试用例更好,当你的代码不能在 Windows 上编译时必须输出信息)。
避免设置太短的等待时间(或不等待),通过 Expect 异步检测目标事件(例如,使用 Expect 等待 1 秒并检测 Pod 是否运行)。使用等待和重试完成测试代码。
重要的功能需要有集成(test/integration)或端到端(e2e)测试。
测试代码需要覆盖新的 vela cli 命令和现有命令的主要功能。
更多细节请参考测试原理。
避免包过度扩张。需要为新包找到一个合适的子目录。
- 没有合适的子目录的包请放到 pkg/util 的子目录中作为新的包。
避免命名为 util。 “util” 的含义模糊不清。应该使用一个描述所需功能的名字。例如,处理等待操作的实用功能在 “wait” 包中包含了 Poll 功能。所以全称是 wait.Poll。
所有的文件名都应该是小写的。
Go 源文件和目录使用下划线,而不是破折号。
- 包目录一般尽量避免使用分隔符(当包是多个单词时,通常在嵌套的子目录中)。
文档目录和文件名应该使用破折号而不是下划线。
根据针对角色,部署应用程序的用户或者集群管理员,将系统功能说明的例子放到
/docs/user-guide
或/docs/admin
下,。实际的应用案例放到/examples
目录下。- 案例还应该说明配置和使用系统的最佳做法。
第三方代码
正常的第三方依赖的 Go 代码使用 go modules 来管理。
其他第三方代码属于
/third_party
- fork 的第三方 Go 代码归入
/third_party/forked
- fork 的 golang stdlib 代码放在
/third_party/forked/golang
中。
- fork 的第三方 Go 代码归入
第三方代码必须包括许可证。
也包括修改过的第三方代码和部分摘录。
我们推荐使用 klog.InfoS
来构造日志。msg
参数的首字母要大写。而 name
参数应该始终使用小写首字母的驼峰命名法,例:lowerCamelCase
。
// func InfoS(msg string, keysAndValues ...interface{})
klog.InfoS("Reconcile traitDefinition", "traitDefinition", klog.KRef(req.Namespace, req.Name))
// outputs:
// I0605 10:10:57.308074 22276 traitdefinition_controller.go:59] "Reconcile traitDefinition" traitDefinition="vela-system/expose"
klog.KObj
和 klog.KRef
可以使 kubernetes 对象的输出一致。
klog.InfoS("Start to reconcile", "appDeployment", klog.KOObj(appDeployment))
// 在记录 Kubernetes 对象的信息时,KRef 被用来创建 ObjectRef,但不能访问 metav1.Object
klog.InfoS("Reconcile application", "application", klog.KRef(req.Namespace, req.Name))
logs.go 包含了KubeVela的日志级别,你可以通过 klog.V(level)
设置日志级别。
//你可以使用 klog.V(common.LogDebug) 来打印调试日志
klog.V(common.LogDebug).InfoS("Successfully applied components", "workloads", len(workloads))
更多细节在结构化日志指南。
为了整个 Go 代码库的一致性,所有代码都需要通过 linter 检查。
要运行所有的 linters,请使用 reviewable
的 Makefile target:
make reviewable
该命令在进行一些 lint 检查的同时会整洁代码。所以请检查命令运行完成后的所有修改。
Last updated on 2023年5月6日 by Tianxin Dong