gerritsdk

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2026 License: MIT Imports: 8 Imported by: 0

README

gerrit-sdk

[!CAUTION] Deprecated and unmaintained as of 2026-09-22. Do not use this module.

A successor that owns its own types is in progress; it is not yet published, so there is no replacement path to point at yet. This notice will be updated when there is one.

The repository stays up, read-only, so that v0.1.0 keeps resolving for anyone who already depends on it. It is not being deleted and v0.1.0 is not retracted — it works, it is merely wrong in the ways listed below.

Known defects, any of which produces a silently wrong result:

  1. Cross-host credential leak. parseGitCookies matches with strings.Contains(host, ".googlesource.com") and returns the first googlesource credential in the file regardless of which host was asked for. With cookies for more than one review host, it sends the wrong identity to the wrong server.
  2. ParseGitCookiesForHost fails on a stock Google .gitcookies. It matches only host or "."+host, so the fleet-wide .googlesource.com line that Google actually issues never matches a specific review host. It also never inspects the cookie name and never checks expiry.
  3. googlesource extensions are dropped. triplet_id, virtual_id_number and full_branch are returned by googlesource and are absent from the underlying go-gerrit types, with no DisallowUnknownFields, so they vanish without an error.
  4. _more_changes is discarded, so a caller cannot tell a truncated result set from a complete one.
  5. NewClient mutates the caller's http.Client. Two clients built from one http.Client stack auth transports and send both credentials.
  6. NewAnonymousClient accepts and silently ignores WithAuth — directly contradicting the claim below that the SDK never silently falls back to unauthenticated access.
  7. Nondeterministic output. GetChangeDetail, GetChangeFiles and ListProjects build slices by ranging over a map, so ordering changes on every call.
  8. The query builder does not quote values, so Project("my project") silently becomes two query terms, and file: is documented as a prefix match when Gerrit treats it as exact — the example below returns nothing.

A high-level Go client for Gerrit Code Review, with first-class support for Googlesource.com instances.

Built on top of andygrunwald/go-gerrit, this SDK provides:

  • Googlesource authentication via .gitcookies, HTTP Basic, or Bearer tokens
  • Fluent query builder for Gerrit's change search syntax
  • Simplified types (CL, CLFile, FileDiff, Project) mapped from go-gerrit internals
  • Diff retrieval with structured content segments

Install

go get github.com/albertocavalcante/gerrit-sdk

Usage

Anonymous access (public instances)
package main

import (
    "context"
    "fmt"

    gerritsdk "github.com/albertocavalcante/gerrit-sdk"
)

func main() {
    ctx := context.Background()
    client, err := gerritsdk.NewAnonymousClient(ctx, "bazel-review.googlesource.com")
    if err != nil {
        panic(err)
    }

    query := gerritsdk.NewQuery().
        Project("bazel").
        Status("merged").
        File("docs/").
        String()

    cls, err := client.QueryChanges(ctx, query, gerritsdk.WithLimit(10))
    if err != nil {
        panic(err)
    }

    for _, cl := range cls {
        fmt.Printf("CL/%d  %s  (%s)\n", cl.Number, cl.Subject, cl.Owner)
    }
}
Authenticated access (gitcookies)
client, err := gerritsdk.NewClient(ctx, "bazel-review.googlesource.com",
    gerritsdk.WithAuth(gerritsdk.GitCookiesAuth{}), // reads ~/.gitcookies
)
Authenticated access (HTTP Basic)
client, err := gerritsdk.NewClient(ctx, "review.example.com",
    gerritsdk.WithAuth(gerritsdk.HTTPBasicAuth{
        Username: "user",
        Password: os.Getenv("GERRIT_PASSWORD"),
    }),
)
Change details and files
cl, err := client.GetChangeDetail(ctx, "318050")
fmt.Println(cl.Subject, cl.Files)

files, err := client.GetChangeFiles(ctx, "318050")
for _, f := range files {
    fmt.Printf("  %s (+%d -%d)\n", f.Path, f.Insertions, f.Deletions)
}
File diffs
diff, err := client.GetChangeDiff(ctx, "318050", "docs/run/build.mdx")
for _, seg := range diff.Content {
    // seg.Common, seg.OldOnly, seg.NewOnly
}
Query builder
q := gerritsdk.NewQuery().
    Project("bazel").
    Status("merged").
    After(time.Now().Add(-30 * 24 * time.Hour)).
    File("docs/").
    Owner("self").
    String()
// "project:bazel status:merged after:2026-02-24 file:docs/ owner:self"

Authentication

Method Use case
GitCookiesAuth{Path: "~/.gitcookies"} Googlesource.com (default path: ~/.gitcookies)
HTTPBasicAuth{Username, Password} Standard Gerrit with HTTP auth
BearerTokenAuth{Token} OAuth2 / service accounts
None (NewAnonymousClient) Public read-only access

Auth errors are returned immediately from NewClient -- the SDK never silently falls back to unauthenticated access.

Advanced usage

Access the underlying go-gerrit client for endpoints not yet wrapped:

inner := client.Inner()
reviewers, _, err := inner.Changes.ListReviewers(ctx, "318050")

License

MIT

Documentation

Overview

Package gerritsdk provides a high-level Go client for Gerrit Code Review instances, with first-class support for Googlesource.com authentication.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseGitCookiesForHost deprecated

func ParseGitCookiesForHost(path, host string) (user, pass string, err error)

ParseGitCookiesForHost reads a .gitcookies file and returns credentials for the specified host.

Deprecated: this module is unmaintained, and this function does not work on the .gitcookies file Google actually issues. It matches only an exact host or "."+host, so the fleet-wide ".googlesource.com" line never matches a specific review host such as "chromium-review.googlesource.com". It also ignores the includeSubdomains field, never inspects the cookie name, and never checks expiry. See the README.

Types

type AuthMethod deprecated

type AuthMethod interface {
	// contains filtered or unexported methods
}

AuthMethod configures how the client authenticates with Gerrit.

Deprecated: this module is unmaintained. See the README.

type BearerTokenAuth

type BearerTokenAuth struct {
	Token string
}

BearerTokenAuth authenticates with an OAuth2 bearer token.

type BuildQuery

type BuildQuery struct {
	// contains filtered or unexported fields
}

BuildQuery is a helper for constructing Gerrit query strings.

func NewQuery deprecated

func NewQuery() *BuildQuery

NewQuery starts building a query.

Deprecated: this module is unmaintained. The builder does not quote values, so any value containing a space is silently split into two query terms, and callers can inject arbitrary Gerrit operators through Project, Owner or File. See the README.

func (*BuildQuery) After

func (q *BuildQuery) After(t time.Time) *BuildQuery

After restricts to changes updated after a time.

func (*BuildQuery) Before

func (q *BuildQuery) Before(t time.Time) *BuildQuery

Before restricts to changes updated before a time.

func (*BuildQuery) File

func (q *BuildQuery) File(path string) *BuildQuery

File restricts to changes touching a file path (prefix match).

func (*BuildQuery) Owner

func (q *BuildQuery) Owner(user string) *BuildQuery

Owner restricts to changes owned by a user.

func (*BuildQuery) Project

func (q *BuildQuery) Project(name string) *BuildQuery

Project restricts to a project.

func (*BuildQuery) Raw

func (q *BuildQuery) Raw(fragment string) *BuildQuery

Raw adds a raw query fragment.

func (*BuildQuery) Status

func (q *BuildQuery) Status(status string) *BuildQuery

Status restricts to a change status.

func (*BuildQuery) String

func (q *BuildQuery) String() string

String returns the assembled query.

type CL

type CL struct {
	Number    int       `json:"number"`
	Project   string    `json:"project"`
	Branch    string    `json:"branch"`
	ChangeID  string    `json:"change_id"`
	Subject   string    `json:"subject"`
	Status    string    `json:"status"` // NEW, MERGED, ABANDONED
	Owner     string    `json:"owner"`
	Created   time.Time `json:"created"`
	Updated   time.Time `json:"updated"`
	Submitted time.Time `json:"submitted,omitempty"`
	Mergeable bool      `json:"mergeable,omitempty"`
	URL       string    `json:"url"`
	Files     []string  `json:"files,omitempty"`
}

CL represents a Gerrit change (changelist).

type CLFile

type CLFile struct {
	Path       string `json:"path"`
	Status     string `json:"status"` // ADDED, MODIFIED, DELETED, RENAMED, COPIED
	OldPath    string `json:"old_path,omitempty"`
	Insertions int    `json:"insertions"`
	Deletions  int    `json:"deletions"`
}

CLFile represents a file changed in a CL revision.

type Client deprecated

type Client struct {
	// contains filtered or unexported fields
}

Client is a high-level Gerrit REST API client.

Deprecated: this module is unmaintained and has known defects that produce silently wrong results. See the README.

func NewAnonymousClient deprecated

func NewAnonymousClient(ctx context.Context, host string, opts ...Option) (*Client, error)

NewAnonymousClient creates an unauthenticated Gerrit client. Only public endpoints will be accessible.

Deprecated: this module is unmaintained. NewAnonymousClient also accepts and silently discards WithAuth, so a caller who passes a credential here gets anonymous requests with no error. See the README.

func NewClient deprecated

func NewClient(ctx context.Context, host string, opts ...Option) (*Client, error)

NewClient creates a Gerrit client for the given host. The host should be a bare hostname like "bazel-review.googlesource.com".

Deprecated: this module is unmaintained. NewClient also mutates the http.Client passed via WithHTTPClient, so two clients built from one http.Client stack auth transports and send both credentials. See the README.

func (*Client) GetChangeCommitMessage

func (c *Client) GetChangeCommitMessage(ctx context.Context, changeID string) (string, error)

GetChangeCommitMessage returns the commit message for a change.

func (*Client) GetChangeDetail

func (c *Client) GetChangeDetail(ctx context.Context, changeID string) (*CL, error)

GetChangeDetail returns detailed information about a single change.

func (*Client) GetChangeDiff

func (c *Client) GetChangeDiff(ctx context.Context, changeID, filePath string) (*FileDiff, error)

GetChangeDiff returns the diff for a specific file in a change.

func (*Client) GetChangeFiles

func (c *Client) GetChangeFiles(ctx context.Context, changeID string) ([]CLFile, error)

GetChangeFiles returns the list of files modified in the current patchset.

func (*Client) GetProject

func (c *Client) GetProject(ctx context.Context, name string) (*Project, error)

GetProject returns details about a specific project.

func (*Client) Host

func (c *Client) Host() string

Host returns the Gerrit instance hostname.

func (*Client) Inner

func (c *Client) Inner() *gogerrit.Client

Inner returns the underlying go-gerrit client for advanced usage.

func (*Client) ListProjectBranches

func (c *Client) ListProjectBranches(ctx context.Context, project string) ([]string, error)

ListProjectBranches returns branches for a project.

func (*Client) ListProjects

func (c *Client) ListProjects(ctx context.Context) ([]Project, error)

ListProjects returns all projects on the Gerrit instance.

func (*Client) QueryChanges

func (c *Client) QueryChanges(ctx context.Context, query string, opts ...QueryOption) ([]CL, error)

QueryChanges searches for changes matching the given Gerrit query string. Example queries:

"project:bazel status:merged file:docs/"
"status:open owner:self"

type DiffContent

type DiffContent struct {
	Common  []string `json:"ab,omitempty"` // lines common to both
	OldOnly []string `json:"a,omitempty"`  // lines only in old version
	NewOnly []string `json:"b,omitempty"`  // lines only in new version
}

DiffContent represents a segment of a unified diff returned by Gerrit.

type FileDiff

type FileDiff struct {
	Path    string        `json:"path"`
	Content []DiffContent `json:"content"`
}

FileDiff represents the diff for a single file.

type GitCookiesAuth deprecated

type GitCookiesAuth struct {
	Path string // path to .gitcookies file; empty = ~/.gitcookies
}

GitCookiesAuth authenticates using a .gitcookies file, the standard method for googlesource.com instances.

Deprecated: this module is unmaintained, and this type is the worst defect in it. Apply never receives the target host, so it calls parseGitCookies, which returns the FIRST googlesource credential in the file regardless of which host the request is for — it will send one review host's identity to another. It also does no tilde expansion, so a literal "~/.gitcookies" Path fails to open. See the README.

type HTTPBasicAuth

type HTTPBasicAuth struct {
	Username string
	Password string
}

HTTPBasicAuth authenticates with a username and password/token.

type Link struct {
	Name string `json:"name"`
	URL  string `json:"url"`
}

Link is a Gerrit web link.

type Option

type Option func(*clientConfig)

Option configures a Client.

func WithAuth

func WithAuth(a AuthMethod) Option

WithAuth sets the authentication method.

func WithHTTPClient

func WithHTTPClient(c *http.Client) Option

WithHTTPClient sets a custom http.Client for the underlying transport.

type Project

type Project struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	State       string `json:"state"` // ACTIVE, READ_ONLY, HIDDEN
	WebLinks    []Link `json:"web_links,omitempty"`
}

Project represents a Gerrit project (repository).

type QueryOption

type QueryOption func(*queryConfig)

QueryOption modifies a change query.

func WithFields

func WithFields(fields ...string) QueryOption

WithFields requests additional fields (e.g. "CURRENT_REVISION", "ALL_FILES").

func WithLimit

func WithLimit(n int) QueryOption

WithLimit sets the maximum number of results.

func WithOffset

func WithOffset(n int) QueryOption

WithOffset sets the result offset for pagination.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL