osv-scanner开发指南:贡献代码与插件开发
1. 开发环境准备
1.1 环境依赖
osv-scanner采用Go语言开发,贡献代码前需确保本地环境满足以下要求:
| 依赖项 | 版本要求 | 验证命令 |
|---|---|---|
| Go | 1.21+ | go version |
| GoReleaser | 可选 | goreleaser --version |
| Git | 最新稳定版 | git --version |
1.2 源码获取
通过以下命令克隆项目仓库:
git clone https://gitcode.com/GitHub_Trending/os/osv-scanner.git
cd osv-scanner
1.3 构建与验证
使用项目提供的脚本完成构建和基础验证:
# 构建二进制文件
./scripts/build.sh
# 运行测试套件
./scripts/run_tests.sh
# 执行代码 lint 检查
./scripts/run_lints.sh
2. 贡献代码流程
2.1 开发流程概览
贡献代码遵循标准的Fork-PR流程,整体步骤如下:
2.2 提交规范
所有提交需遵循Conventional Commits规范,格式如下:
<类型>[可选作用域]: <描述>
[可选正文]
[可选脚注]
常见类型包括:
feat: 新功能fix: 错误修复docs: 文档更新refactor: 代码重构test: 测试相关chore: 构建/依赖管理
示例:
git commit -m "feat(scanner): 添加SBOM文件解析支持"
2.3 测试要求
提交代码前必须确保:
- 所有现有测试通过:
./scripts/run_tests.sh - 新增功能需添加对应的单元测试
- 测试覆盖率不低于80%
- 如需更新快照测试,执行:
UPDATE_SNAPS=true ./scripts/run_tests.sh
3. 插件开发指南
3.1 插件系统架构
osv-scanner采用插件化架构设计,主要包含以下组件:
插件类型分为:
- 提取器插件:负责从不同类型的文件(如lockfile、SBOM)中提取依赖信息
- 检测器插件:实现特定类型的漏洞检测逻辑
3.2 开发提取器插件
3.2.1 插件实现步骤
-
创建插件文件
在internal/scalibrextract/language/<语言>目录下创建插件文件,例如internal/scalibrextract/language/ruby/gemfileenhanceable.go -
实现Plugin接口
package ruby
import (
"github.com/google/osv-scalibr/plugin"
"github.com/google/osv-scanner/v2/pkg/models"
)
const Name = "gemfile-enhanceable"
type GemfileEnhanceablePlugin struct{}
func New() *GemfileEnhanceablePlugin {
return &GemfileEnhanceablePlugin{}
}
func (p *GemfileEnhanceablePlugin) Name() string {
return Name
}
func (p *GemfileEnhanceablePlugin) Extract(path string) ([]models.PackageInfo, error) {
// 实现依赖提取逻辑
}
- 注册插件
在internal/scalibrplugin/presets.go中注册插件:
var ExtractorPresets = map[string]extractors.InitMap{
"lockfile": {
// ... 现有插件
gemfileenhanceable.Name: {gemfileenhanceable.New},
},
// ...
}
3.2.2 插件解析流程
插件加载流程在internal/scalibrplugin/resolve.go中实现:
3.3 插件测试
为新插件编写测试需遵循以下规范:
- 测试文件位置:在插件目录下创建
*_test.go文件 - 测试数据:放入
testdata/目录 - 测试类型:
- 单元测试:验证插件独立功能
- 集成测试:验证插件与扫描器集成效果
示例测试代码:
func TestGemfileEnhanceableExtract(t *testing.T) {
plugin := New()
packages, err := plugin.Extract("testdata/Gemfile.lock")
assert.NoError(t, err)
assert.Len(t, packages, 5)
assert.Equal(t, "rails", packages[0].Name)
}
4. 高级贡献
4.1 新增命令功能
osv-scanner使用Cobra框架实现CLI命令,新增命令步骤:
- 在
cmd/osv-scanner/<命令>目录创建命令文件 - 实现
Command()方法定义命令元信息和处理逻辑 - 在
cmd/osv-scanner/main.go中注册新命令
示例结构:
// cmd/osv-scanner/analyze/command.go
package analyze
import (
"github.com/spf13/cobra"
)
func Command() *cobra.Command {
cmd := &cobra.Command{
Use: "analyze",
Short: "分析依赖项安全状态",
RunE: run,
}
// 添加标志和参数
return cmd
}
func run(cmd *cobra.Command, args []string) error {
// 命令处理逻辑
}
4.2 性能优化
贡献性能优化代码时需:
- 使用
go test -bench提供基准测试数据 - 在PR中说明优化点和性能提升数据
- 遵循项目的内存使用规范
常见优化方向:
- 依赖缓存机制改进
- 并发扫描实现
- 大型文件解析优化
5. 贡献提交检查清单
提交PR前请确保完成以下检查:
- [ ] 代码符合项目代码风格(运行`./scripts/run_formatters.sh`)
- [ ] 所有测试通过(`./scripts/run_tests.sh`)
- [ ] 新增代码包含测试用例
- [ ] 提交信息符合Conventional Commits规范
- [ ] 文档已更新(如需要)
- [ ] 已签署CLA协议
6. 社区资源
- Issue跟踪:通过项目Issue系统提交bug报告和功能建议
- 讨论交流:参与项目Discussions讨论技术问题
- 开发计划:查看项目Milestones了解开发路线图
- 代码审查:PR需至少1名核心开发者批准才能合并
7. 附录:常用开发命令
| 命令 | 用途 |
|---|---|
./scripts/build.sh | 构建二进制文件 |
./scripts/run_tests.sh | 运行所有测试 |
./scripts/run_lints.sh | 执行代码检查 |
./scripts/generate_coverage_report.sh | 生成测试覆盖率报告 |
UPDATE_SNAPS=true ./scripts/run_tests.sh | 更新快照测试 |
./scripts/run_local_docs.sh | 本地预览文档 |
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



