golang Gerrit代码审查系统客户端插件库go-gerrit的使用

Golang Gerrit代码审查系统客户端插件库go-gerrit的使用

简介

go-gerrit是一个用于Gerrit代码审查系统的Go客户端库。

go-gerrit - Go client/library for Gerrit Code Review

功能特性

  • 认证方式支持(HTTP Basic、HTTP Digest、HTTP Cookie)
  • 支持所有Gerrit API端点
    • /access/
    • /accounts/
    • /changes/
    • /config/
    • /groups/
    • /plugins/
    • /projects/
  • 支持可选插件API如events-log

安装

go-gerrit遵循Go发布策略,支持当前版本及前两个Go版本。

安装命令:

$ go get github.com/andygrunwald/go-gerrit

API使用

认证方式

HTTP Basic认证

instance := "https://review.typo3.org/"
client, _ := gerrit.NewClient(instance, nil)
client.Authentication.SetBasicAuth("andy.grunwald", "my secrect password")

self, _, _ := client.Accounts.GetAccount("self")

fmt.Printf("Username: %s", self.Name)

// 输出: Username: Andy Grunwald

如果收到401未授权错误,请检查账户设置中的HTTP密码配置。

HTTP Digest认证

instance := "https://gerrit.wikimedia.org/r/"
client, _ := gerrit.NewClient(instance, nil)
client.Authentication.SetDigestAuth("andy.grunwald", "my secrect http password")

self, resp, err := client.Accounts.GetAccount("self")

fmt.Printf("Username: %s", self.Name)

// 输出: Username: Andy Grunwald

HTTP Cookie认证

instance := "https://gerrit-review.googlesource.com/"
client, _ := gerrit.NewClient(instance, nil)
client.Authentication.SetCookieAuth("o", "my-cookie-secret")

self, _, _ := client.Accounts.GetAccount("self")

fmt.Printf("Username: %s", self.Name)

// 输出: Username: Andy G.

示例代码

获取Gerrit实例版本

package main

import (
	"fmt"

	"github.com/andygrunwald/go-gerrit"
)

func main() {
	instance := "https://gerrit-review.googlesource.com/"
	client, err := gerrit.NewClient(instance, nil)
	if err != nil {
		panic(err)
	}

	v, _, err := client.Config.GetVersion()
	if err != nil {
		panic(err)
	}

	fmt.Printf("Version: %s", v)

	// 输出: Version: 3.4.1-2066-g8db5605430
}

获取所有公开项目

package main

import (
	"fmt"

	"github.com/andygrunwald/go-gerrit"
)

func main() {
	instance := "https://chromium-review.googlesource.com/"
	client, err := gerrit.NewClient(instance, nil)
	if err != nil {
		panic(err)
	}

	opt := &gerrit.ProjectOptions{
		Description: true,
	}
	projects, _, err := client.Projects.ListProjects(opt)
	if err != nil {
		panic(err)
	}

	for name, p := range *projects {
		fmt.Printf("%s - State: %s\n", name, p.State)
	}

	// 输出示例:
	// chromiumos/third_party/bluez - State: ACTIVE
	// external/github.com/Polymer/ShadowDOM - State: ACTIVE
	// external/github.com/domokit/mojo_sdk - State: ACTIVE
}

查询变更

package main

import (
	"fmt"

	"github.com/andygrunwald/go-gerrit"
)

func main() {
	instance := "https://android-review.googlesource.com/"
	client, err := gerrit.NewClient(instance, nil)
	if err != nil {
		panic(err)
	}

	opt := &gerrit.QueryChangeOptions{}
	opt.Query = []string{"project:kernel/common"}
	opt.AdditionalFields = []string{"LABELS"}
	changes, _, err := client.Changes.QueryChanges(opt)
	if err != nil {
		panic(err)
	}

	for _, change := range *changes {
		fmt.Printf("Project: %s -> %s -> %s%d\n", change.Project, change.Subject, instance, change.Number)
	}

	// 输出示例:
	// Project: kernel/common -> ANDROID: GKI: Update symbols to symbol list -> https://android-review.googlesource.com/1830553
	// Project: kernel/common -> ANDROID: db845c_gki.fragment: Remove CONFIG_USB_NET_AX8817X from fragment -> https://android-review.googlesource.com/1830439
}

开发

运行测试和检查

运行测试:

$ make test

运行检查、测试和静态分析:

$ make vet staticcheck test

本地Gerrit设置

建议使用官方Gerrit Code Review docker镜像:

$ docker run -ti -p 8080:8080 -p 29418:29418 gerritcodereview/gerrit:3.4.1

认证

对于本地开发设置,可以生成密码后使用:

client.Authentication.SetBasicAuth("admin", "secret")

常见问题

源代码如何组织?

源代码组织受Google的go-github启发。每个REST API端点(如/access/, /changes/)都在一个服务中实现(如access.go中的AccessService, changes.go中的ChangesService)。

与Gerrit版本的兼容性如何?

该库基于Gerrit版本2.11.3-1230-gb8336f1的REST API实现并测试。可能也适用于旧版本。

如何添加对可选插件REST API的支持?

取决于具体插件,可以先提出问题和用例。例如events-log插件因其流行而被支持。

许可证

本项目采用MIT许可证。


更多关于golang Gerrit代码审查系统客户端插件库go-gerrit的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang Gerrit代码审查系统客户端插件库go-gerrit的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-gerrit:Golang Gerrit客户端库使用指南

go-gerrit 是一个用于与 Gerrit 代码审查系统交互的 Golang 客户端库。它提供了方便的 API 来执行各种 Gerrit 操作,如查询变更、提交评论、管理账户等。

安装

首先安装 go-gerrit 库:

go get github.com/andygrunwald/go-gerrit

基本使用

1. 创建客户端连接

package main

import (
	"fmt"
	"log"
	"github.com/andygrunwald/go-gerrit"
)

func main() {
	// 创建匿名客户端
	client, err := gerrit.NewClient("https://gerrit-review.googlesource.com", nil)
	if err != nil {
		log.Fatal(err)
	}

	// 或者使用基本认证
	client, err = gerrit.NewClient(
		"https://your-gerrit-instance.com",
		&gerrit.BasicAuth{
			Username: "your-username",
			Password: "your-password-or-http-token",
		},
	)
	if err != nil {
		log.Fatal(err)
	}
}

2. 查询变更列表

func listChanges(client *gerrit.Client) {
	opt := &gerrit.QueryChangeOptions{
		QueryOptions: gerrit.QueryOptions{
			Limit: 10, // 限制返回结果数量
		},
	}
	changes, _, err := client.Changes.QueryChanges(opt)
	if err != nil {
		log.Fatal(err)
	}

	for _, change := range *changes {
		fmt.Printf("ID: %s, Project: %s, Subject: %s\n", 
			change.ID, change.Project, change.Subject)
	}
}

3. 获取特定变更详情

func getChangeDetail(client *gerrit.Client, changeID string) {
	change, _, err := client.Changes.GetChangeDetail(changeID, &gerrit.ChangeOptions{
		AdditionalFields: []string{"LABELS", "DETAILED_ACCOUNTS"},
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Change %s:\n", change.ID)
	fmt.Printf("Status: %s\n", change.Status)
	fmt.Printf("Owner: %s (%s)\n", change.Owner.Name, change.Owner.Email)
	fmt.Printf("Current Revision: %s\n", change.CurrentRevision)
}

4. 提交代码审查评论

func postReview(client *gerrit.Client, changeID, revisionID string) {
	reviewInput := &gerrit.ReviewInput{
		Message: "Looks good to me, but needs minor fixes.",
		Labels: map[string]string{
			"Code-Review": "+1",
		},
		Comments: map[string][]gerrit.CommentInput{
			"src/main.go": {
				{
					Line:    42,
					Message: "Consider using a constant here instead of magic number.",
				},
			},
		},
	}

	_, _, err := client.Changes.SetReview(changeID, revisionID, reviewInput)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Review submitted successfully")
}

5. 创建新变更

func createChange(client *gerrit.Client) {
	changeInput := &gerrit.ChangeInput{
		Project:        "my-project",
		Branch:        "master",
		Subject:       "Implement new feature X",
		Status:        "NEW",
		WorkInProgress: true,
	}

	newChange, _, err := client.Changes.CreateChange(changeInput)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Created new change: %s\n", newChange.ID)
}

高级功能

1. 使用 SSH 认证

func sshClient() {
	client, err := gerrit.NewSSHClient(
		"gerrit.example.com:29418",
		"/path/to/private/key",
		"your-username",
	)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	// 使用SSH客户端执行命令...
}

2. 处理分页结果

func paginatedChanges(client *gerrit.Client) {
	opt := &gerrit.QueryChangeOptions{
		QueryOptions: gerrit.QueryOptions{
			Limit:  50,
			Skip:   0,
			Sort:   "updated",
			Option: []string{"LABELS"},
		},
	}

	for {
		changes, resp, err := client.Changes.QueryChanges(opt)
		if err != nil {
			log.Fatal(err)
		}

		for _, change := range *changes {
			fmt.Printf("%s: %s\n", change.ID, change.Subject)
		}

		if len(*changes) < opt.Limit {
			break
		}
		opt.Skip += opt.Limit
	}
}

3. 监听事件流

func streamEvents(client *gerrit.Client) {
	events := make(chan *gerrit.Event)
	done := make(chan struct{})

	go func() {
		err := client.Events.StreamEvents(events, done, &gerrit.StreamEventsOptions{
			SSH: true, // 使用SSH流
		})
		if err != nil {
			log.Fatal(err)
		}
	}()

	for event := range events {
		switch event.Type {
		case "patchset-created":
			fmt.Printf("New patchset created for change %s\n", event.Change.Number)
		case "comment-added":
			fmt.Printf("New comment on change %s by %s\n", 
				event.Change.Number, event.Author.Name)
		}
	}
}

最佳实践

  1. 错误处理:Gerrit API 可能返回各种错误,始终检查错误响应
  2. 认证管理:使用 HTTP 令牌而非密码,并妥善保管
  3. 速率限制:避免过频繁的 API 调用,Gerrit 可能有速率限制
  4. 上下文使用:对于长时间运行的操作,使用 context 进行超时控制

go-gerrit 提供了完整的 Gerrit REST API 覆盖,更多功能可以参考其官方文档

回到顶部