blob: 1c0e2a5de06f2d4a460b24245a528f30a6ebcbb7 [file] [log] [blame] [edit]
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// gerrit provides helpers for obtaining information from Tint's gerrit instance
package gerrit
import (
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
"github.com/andygrunwald/go-gerrit"
)
const URL = "https://dawn-review.googlesource.com/"
// G is the interface to gerrit
type G struct {
client *gerrit.Client
authenticated bool
}
type Config struct {
Username string
Password string
}
func LoadCredentials() (user, pass string) {
cookiesFile := os.Getenv("HOME") + "/.gitcookies"
if cookies, err := ioutil.ReadFile(cookiesFile); err == nil {
re := regexp.MustCompile(`dawn-review.googlesource.com\s+(?:FALSE|TRUE)[\s/]+(?:FALSE|TRUE)\s+[0-9]+\s+.\s+(.*)=(.*)`)
match := re.FindStringSubmatch(string(cookies))
if len(match) == 3 {
return match[1], match[2]
}
}
return "", ""
}
func New(cfg Config) (*G, error) {
client, err := gerrit.NewClient(URL, nil)
if err != nil {
return nil, fmt.Errorf("couldn't create gerrit client: %w", err)
}
user, pass := cfg.Username, cfg.Password
if user == "" {
user, pass = LoadCredentials()
}
if user != "" {
client.Authentication.SetBasicAuth(user, pass)
}
return &G{client, user != ""}, nil
}
func (g *G) QueryChanges(queryParts ...string) (changes []gerrit.ChangeInfo, query string, err error) {
changes = []gerrit.ChangeInfo{}
query = strings.Join(queryParts, "+")
for {
batch, _, err := g.client.Changes.QueryChanges(&gerrit.QueryChangeOptions{
QueryOptions: gerrit.QueryOptions{Query: []string{query}},
Skip: len(changes),
})
if err != nil {
if !g.authenticated {
err = fmt.Errorf(`query failed, possibly because of authentication.
See https://dawn-review.googlesource.com/new-password for obtaining a username
and password which can be provided with --gerrit-user and --gerrit-pass.
%w`, err)
}
return nil, "", err
}
changes = append(changes, *batch...)
if len(*batch) == 0 || !(*batch)[len(*batch)-1].MoreChanges {
break
}
}
return changes, query, nil
}