blob: 1c0e2a5de06f2d4a460b24245a528f30a6ebcbb7 [file] [log] [blame]
Ben Claytonf6660aa2021-07-20 20:25:38 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// gerrit provides helpers for obtaining information from Tint's gerrit instance
16package gerrit
17
18import (
19 "fmt"
20 "io/ioutil"
21 "os"
22 "regexp"
23 "strings"
24
25 "github.com/andygrunwald/go-gerrit"
26)
27
28const URL = "https://dawn-review.googlesource.com/"
29
30// G is the interface to gerrit
31type G struct {
32 client *gerrit.Client
33 authenticated bool
34}
35
36type Config struct {
37 Username string
38 Password string
39}
40
Ben Clayton5209a812021-07-30 16:20:46 +000041func LoadCredentials() (user, pass string) {
42 cookiesFile := os.Getenv("HOME") + "/.gitcookies"
43 if cookies, err := ioutil.ReadFile(cookiesFile); err == nil {
44 re := regexp.MustCompile(`dawn-review.googlesource.com\s+(?:FALSE|TRUE)[\s/]+(?:FALSE|TRUE)\s+[0-9]+\s+.\s+(.*)=(.*)`)
45 match := re.FindStringSubmatch(string(cookies))
46 if len(match) == 3 {
47 return match[1], match[2]
48 }
49 }
50 return "", ""
51}
52
Ben Claytonf6660aa2021-07-20 20:25:38 +000053func New(cfg Config) (*G, error) {
54 client, err := gerrit.NewClient(URL, nil)
55 if err != nil {
Ben Clayton5209a812021-07-30 16:20:46 +000056 return nil, fmt.Errorf("couldn't create gerrit client: %w", err)
Ben Claytonf6660aa2021-07-20 20:25:38 +000057 }
58
59 user, pass := cfg.Username, cfg.Password
60 if user == "" {
Ben Clayton5209a812021-07-30 16:20:46 +000061 user, pass = LoadCredentials()
Ben Claytonf6660aa2021-07-20 20:25:38 +000062 }
63
64 if user != "" {
65 client.Authentication.SetBasicAuth(user, pass)
66 }
67
68 return &G{client, user != ""}, nil
69}
70
71func (g *G) QueryChanges(queryParts ...string) (changes []gerrit.ChangeInfo, query string, err error) {
72 changes = []gerrit.ChangeInfo{}
73 query = strings.Join(queryParts, "+")
74 for {
75 batch, _, err := g.client.Changes.QueryChanges(&gerrit.QueryChangeOptions{
76 QueryOptions: gerrit.QueryOptions{Query: []string{query}},
77 Skip: len(changes),
78 })
79 if err != nil {
80 if !g.authenticated {
Ben Clayton5209a812021-07-30 16:20:46 +000081 err = fmt.Errorf(`query failed, possibly because of authentication.
Ben Claytonf6660aa2021-07-20 20:25:38 +000082 See https://dawn-review.googlesource.com/new-password for obtaining a username
83 and password which can be provided with --gerrit-user and --gerrit-pass.
84 %w`, err)
85 }
86 return nil, "", err
87 }
88
89 changes = append(changes, *batch...)
90 if len(*batch) == 0 || !(*batch)[len(*batch)-1].MoreChanges {
91 break
92 }
93 }
94 return changes, query, nil
95}