installerbuilder/doc/golang-rules.md

7.3 KiB
Raw Blame History

Go语言开发规范

本文档定义了Installer Builder项目的Go语言开发规范旨在提高代码质量、可维护性和一致性。所有项目贡献者和AI代码生成都应遵循这些规范。

1. 项目结构和代码组织

1.1 目录结构

/

├── cmd/ # 命令行入口点

│ ├── cli/ # CLI应用

│ └── gui/ # GUI应用

├── internal/ # 内部包,不对外暴露

│ ├── config/ # 配置处理

│ ├── builder/ # 构建引擎

│ ├── platform/ # 平台适配

│ ├── packager/ # 包类型构建器

│ ├── script/ # 脚本执行

│ └── plugin/ # 插件系统

├── pkg/ # 可导出的包,可能被其他项目使用

│ ├── api/ # 公共API

│ └── schema/ # 配置Schema

├── ui/ # GUI相关代码

│ ├── frontend/ # Wails前端

│ └── assets/ # UI资源

├── plugins/ # 插件目录

├── examples/ # 示例配置和项目

├── scripts/ # 构建和开发脚本

└── doc/ # 文档

1.2 包设计原则

  • 每个包应该有单一的职责
  • 避免循环依赖
  • 包名应该简短、清晰,使用小写单词
  • 内部实现细节放在internal/目录下
  • 可重用的、稳定的API放在pkg/目录下

2. 命名约定

2.1 包名

  • 使用简短、简洁、有意义的名称
  • 使用小写字母,不使用下划线或混合大小写
  • 避免使用常见变量名作为包名(如utilcommon等)

2.2 文件名

  • 使用小写字母
  • 使用下划线分隔多个单词
  • 测试文件使用_test.go后缀

2.3 变量和常量

  • 使用驼峰命名法
  • 局部变量使用简短名称
  • 全局变量和常量使用描述性名称
  • 不导出的变量和常量以小写字母开头
  • 导出的变量和常量以大写字母开头

2.4 函数和方法

  • 使用驼峰命名法
  • 不导出的函数和方法以小写字母开头
  • 导出的函数和方法以大写字母开头
  • 名称应该表明函数的作用
  • 接收器名称应该简短,通常是类型名称的首字母

2.5 接口

  • 单一方法接口名称应以方法名加er后缀命名(如ReaderWriter
  • 多方法接口应该使用描述其行为的名称

2.6 结构体

  • 使用驼峰命名法
  • 不导出的结构体以小写字母开头
  • 导出的结构体以大写字母开头
  • 结构体字段遵循与变量相同的命名规则

3. 代码风格

3.1 格式化

  • 使用gofmtgoimports自动格式化代码
  • 缩进使用制表符tab
  • 行长度建议不超过100个字符

3.2 导入

  • 按标准库、第三方包、项目内部包的顺序分组
  • 每组之间用空行分隔
  • 使用点导入(.)仅限于测试文件中导入测试包

3.3 声明

  • 变量声明尽量靠近使用位置
  • 相关的常量和变量分组声明
  • 使用var关键字声明零值变量,使用短声明:=声明并初始化变量

3.4 控制结构

  • ifforswitch等关键字与左括号之间有一个空格
  • 左大括号不换行
  • elseelse if与右大括号在同一行
  • 避免嵌套过深的控制结构,考虑提前返回

4. 错误处理

4.1 错误返回

  • 错误作为最后一个返回值
  • 使用描述性错误信息
  • 使用fmt.Errorf添加上下文信息
  • 考虑使用自定义错误类型和错误包装

4.2 错误检查

  • 立即检查错误,避免嵌套
  • 使用if err != nil模式
  • 避免使用_忽略错误,除非有明确理由

4.3 错误日志

  • 在调用栈的适当位置记录错误
  • 避免多次记录同一错误
  • 包含足够的上下文信息

4.4 错误处理策略

  • 对于库函数,通常返回错误而不是处理它
  • 对于应用程序,在适当的抽象层处理错误
  • 使用panic仅限于不可恢复的情况

5. 注释规范

5.1 包注释

  • 每个包应该有包注释,位于doc.go文件或包的主文件中
  • 包注释应该提供包的用途、用法和任何重要的注意事项

5.2 导出符号注释

  • 所有导出的函数、类型、常量和变量都应该有注释
  • 注释以符号名称开头,使用完整的句子
  • 遵循godoc约定

5.3 实现注释

  • 对于复杂的实现,添加注释解释原理和算法
  • 对于不明显的代码,解释为什么这样做,而不仅仅是做了什么

5.4 TODO和FIXME

  • 使用// TODO: 标记计划改进的地方
  • 使用// FIXME: 标记需要修复的问题
  • 包含足够的上下文信息和可能的解决方向

6. 测试要求

6.1 测试覆盖率

  • 核心功能应该有单元测试
  • 目标测试覆盖率至少70%
  • 关键路径和边界条件必须测试

6.2 测试组织

  • 使用表驱动测试
  • 测试文件与被测试文件放在同一目录
  • 使用_test.go后缀命名测试文件

6.3 测试命名

  • 测试函数命名为Test<Function>
  • 基准测试命名为Benchmark<Function>
  • 示例测试命名为Example<Function>

6.4 测试工具

  • 使用标准库的testing
  • 可以使用testify等辅助库提高测试效率
  • 使用go test -race检测竞态条件

7. 依赖管理

7.1 依赖选择

  • 优先使用标准库
  • 选择活跃维护、文档完善的第三方库
  • 避免引入过多依赖

7.2 版本控制

  • 使用Go Modules进行依赖管理
  • go.mod中明确指定依赖版本
  • 定期更新依赖以获取安全修复

7.3 依赖隔离

  • 考虑使用接口隔离第三方依赖
  • 为核心功能编写适配器,便于将来替换依赖

8. 并发处理

8.1 并发模式

  • 优先使用高级并发原语(如sync.WaitGroup、通道)
  • 避免共享内存,通过通信共享
  • 使用适当的同步机制保护共享资源

8.2 Goroutine管理

  • 确保所有启动的goroutine都能正确终止
  • 使用上下文(context.Context)传递取消信号
  • 避免goroutine泄漏

8.3 并发安全

  • 明确标记非并发安全的类型和函数
  • 使用sync/atomic包进行原子操作
  • 使用-race标志测试并发代码

9. 日志记录

9.1 日志级别

  • 使用适当的日志级别Debug、Info、Warning、Error、Fatal
  • 在开发环境和生产环境使用不同的日志级别

9.2 日志内容

  • 包含足够的上下文信息
  • 避免记录敏感信息
  • 使用结构化日志便于分析

9.3 日志接口

  • 使用抽象的日志接口,便于将来替换日志实现
  • 考虑使用uber-go/zapsirupsen/logrus等成熟的日志库

10. 代码审查清单

10.1 功能性

  • 代码是否实现了预期功能
  • 是否处理了所有边界条件
  • 错误处理是否完善

10.2 可维护性

  • 代码是否易于理解
  • 是否有适当的注释
  • 是否遵循项目的代码风格

10.3 性能

  • 是否有明显的性能问题
  • 是否有不必要的计算或内存分配
  • 并发代码是否正确且高效

10.4 安全性

  • 是否有安全漏洞
  • 是否正确处理用户输入
  • 是否泄露敏感信息

11. AI代码生成指南

11.1 代码生成原则

  • 生成的代码应遵循本文档中的所有规范
  • 优先生成简洁、可读性高的代码
  • 包含适当的注释和文档

11.2 代码生成提示

  • 明确指定需要生成的功能和接口
  • 提供足够的上下文信息
  • 指定任何特殊要求或约束

11.3 代码审查

  • 生成的代码应经过人工审查
  • 检查是否符合项目规范
  • 验证功能正确性和性能