go-gerrit is a Go(lang) client library for accessing the Gerrit Code Review API.
- Authentication (HTTP Basic, HTTP Digest, HTTP Cookie)
- Every API Endpoint like Gerrit
- Supports optional plugin APIs such as
It is go gettable ...
$ go get github.com/andygrunwald/go-gerrit
... (optional) to run unit / example tests:
$ cd $GOPATH/src/github.com/andygrunwald/go-gerrit
$ go test -v
Please have a look at the GoDoc documentation for a detailed API description.
The Gerrit Code Review - REST API was the base document.
Gerrit support multiple ways for authentication.
Some Gerrit instances (like TYPO3) has auth.gitBasicAuth activated. With this you can authenticate with HTTP Basic like this:
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
If you get an 401 Unauthorized
, check your Account Settings and have a look at the HTTP Password
configuration.
Some Gerrit instances (like Wikimedia) has Digest access authentication activated.
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
If digest auth is not supported by the choosen Gerrit instance, an error like WWW-Authenticate header type is not Digest
is thrown.
If you get an 401 Unauthorized
, check your Account Settings and have a look at the HTTP Password
configuration.
Some Gerrit instances hosted like the one hosted googlesource.com (e.g. Go(lang), Android or Gerrit) support HTTP Cookie authentication.
You need the cookie name and the cookie value. You can get them by click on "Settings > HTTP Password > Obtain Password" in your Gerrit instance.
There you can receive your values.
The cookie name will be (mostly) o
(if hosted on googlesource.com).
Your cookie secret will be something like [email protected]=SomeHash...
.
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.
In the examples chapter below you will find a few more examples. If you miss one or got a question how to do something please open a new issue with your question. We will be happy to answer them.
Further a few examples how the API can be used. A few more examples are available in the GoDoc examples section.
Receive the version of the Gerrit instance used by the Gerrit team for development:
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()
fmt.Printf("Version: %s", v)
// Version: 2.12.2-2512-g0b1bccd
}
List all projects from cyanogenmod:
package main
import (
"fmt"
"github.com/andygrunwald/go-gerrit"
)
func main() {
instance := "http://review.cyanogenmod.org/"
client, err := gerrit.NewClient(instance, nil)
if err != nil {
panic(err)
}
opt := &gerrit.ProjectOptions{
Description: true,
}
projects, _, err := client.Projects.ListProjects(opt)
for name, p := range *projects {
fmt.Printf("%s - State: %s\n", name, p.State)
}
// CyanogenMod/android_external_drm - State: ACTIVE
// CyanogenMod/android_external_jhead - State: ACTIVE
// CyanogenMod/android_external_libppp - State: ACTIVE
// ...
}
Get some changes of the kernel/common project from the Android Gerrit Review System.
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)
for _, change := range *changes {
fmt.Printf("Project: %s -> %s -> %s%d\n", change.Project, change.Subject, instance, change.Number)
}
// Project: kernel/common -> android: binder: Fix BR_ERROR usage and change LSM denials to use it. -> https://android-review.googlesource.com/150839
// Project: kernel/common -> android: binder: fix duplicate error return. -> https://android-review.googlesource.com/155031
// Project: kernel/common -> dm-verity: Add modes and emit uevent on corrupted blocks -> https://android-review.googlesource.com/169572
// ...
}
The source code organisation was inspired by go-github by Google.
Every REST API Endpoint (e.g. /access/ or /changes/) is coupled in a service (e.g. AccessService in access.go or ChangesService in changes.go). Every service is part of gerrit.Client as a member variable.
gerrit.Client can provide basic helper functions to avoid unnecessary code duplications such as building a new request, parse responses and so on.
Based on this structure implementing a new API functionality is straight forwarded. Here is an example of ChangeService.DeleteTopic / DELETE /changes/{change-id}/topic:
func (s *ChangesService) DeleteTopic(changeID string) (*Response, error) {
u := fmt.Sprintf("changes/%s/topic", changeID)
return s.client.DeleteRequest(u, nil)
}
The library was implemented based on the REST API of Gerrit version 2.11.3-1230-gb8336f1 and tested against this version.
This library might be working with older versions as well. If you notice an incompatibility open a new issue or try to fix it. We welcome contribution!
It will depend on the plugin, you are welcome to open a new issue first to propose the idea if you wish.
As an example the addition of support for events-log plugin was supported because the plugin itself is fairly
popular and the structures that the REST API uses could also be used by gerrit stream-events
.
This project is released under the terms of the MIT license.