hashtag - Initial commit of hashtag code.
Bug: skia:9559
Change-Id: I1ee3ebd7ac620d6ccdd2640e3c6733c63ea3daed
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/247300
Commit-Queue: Joe Gregorio <jcgregorio@google.com>
Reviewed-by: Ben Wagner aka dogben <benjaminwagner@google.com>
diff --git a/go.mod b/go.mod
index 6008b70..476da6b 100644
--- a/go.mod
+++ b/go.mod
@@ -70,6 +70,7 @@
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5 // indirect
+ github.com/spf13/viper v1.3.2
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.4.0
github.com/syndtr/goleveldb v1.0.0
diff --git a/go.sum b/go.sum
index 748e152..7009f18 100644
--- a/go.sum
+++ b/go.sum
@@ -202,6 +202,7 @@
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -250,6 +251,7 @@
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/luci/gtreap v0.0.0-20161228054646-35df89791e8f h1:Kkxfmkf53vnIADWIhzvJ0GvwVR/gz9U7F7Wqofqd7dU=
github.com/luci/gtreap v0.0.0-20161228054646-35df89791e8f/go.mod h1:OjKOY0UvVOOH5nWXSIWTbQWESn8dDiGlaEZx6IAsWhU=
+github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -261,6 +263,7 @@
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
@@ -295,6 +298,7 @@
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
@@ -347,10 +351,13 @@
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
@@ -359,6 +366,7 @@
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
diff --git a/go/androidbuildinternal/v2beta1/rebuild.sh b/go/androidbuildinternal/v2beta1/rebuild.sh
index 63e560b..97b0f23 100755
--- a/go/androidbuildinternal/v2beta1/rebuild.sh
+++ b/go/androidbuildinternal/v2beta1/rebuild.sh
@@ -2,8 +2,8 @@
# Script to rebuild the androidbuildinternal.go file.
-# Get an updated generator.
-go get -u google.golang.org/api/google-api-go-generator
+# Get an updated generator. Pin to v0.10.0 because https://github.com/googleapis/google-api-go-client/issues/416.
+go get -u google.golang.org/api/google-api-go-generator@v0.10.0
# Retrieve the discovery document for the API.
wget https://www.googleapis.com/discovery/v1/apis/androidbuildinternal/v2beta1/rest
diff --git a/go/codesearch/codesearch.go b/go/codesearch/codesearch.go
new file mode 100644
index 0000000..9d8dd2e
--- /dev/null
+++ b/go/codesearch/codesearch.go
@@ -0,0 +1,168 @@
+// Package codesearch wraps up the codesearch JSON API.
+//
+// Notes about the codesearch REST API:
+//
+// The query needs to be bracketed by search_request=[b|e] query parameters.
+//
+// For example:
+// https://cs.chromium.org/codesearch/json/search_request:1
+// ?search_request=b
+// &query=file%3A.md+file%3A%5Esrc%2Fthird_party%2Fskia%2F+package%3A%5Echromium%24
+// &max_num_results=20
+// &results_offset=0
+// &search_request=e
+//
+// The URL for a file.name of "src/third_party/skia/site/roles.md" is
+//
+// https://cs.chromium.org/chromium/src/third_party/skia/site/roles.md
+//
+// To jump to a specific line:
+//
+// https://cs.chromium.org/chromium/src/third_party/skia/site/roles.md?l=2
+//
+package codesearch
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "net/url"
+
+ "go.skia.org/infra/go/skerr"
+)
+
+const (
+ // origin is the site hosting codesearch.
+ origin = "https://cs.chromium.org"
+
+ // The location of the JSON codesearch API.
+ jsonQueryPath = "/codesearch/json/search_request"
+
+ // SkiaAllCode is the text to add to a search to restrict it to the Skia
+ // codebase.
+ SkiaAllCode = "file:^src/third_party/skia/ package:^chromium$"
+
+ // SkiaInfraBaseQuery is the text to add to a search to restrict it to the
+ // Skia Infra codebase.
+ SkiaInfraBaseQuery = "file:^skia/buildbot/ package:^chromium$"
+
+ // SkiaAllMarkdown is the text to add to a search to restrict it to Markdown
+ // files in either the buildbot or skia proper repo.
+ SkiaAllMarkdown = "lang:^markdown$ AND (file:^skia/buildbot/ OR file:^src/third_party/skia/) AND package:^chromium$ "
+)
+
+var (
+ defaultQueryParams = url.Values{
+ "search_request": []string{""},
+ }
+)
+
+// CodeSearch searches code.
+type CodeSearch struct {
+ c *http.Client
+ origin string
+}
+
+// New creates a new CodeSearch instance.
+func New(client *http.Client) *CodeSearch {
+ return &CodeSearch{
+ c: client,
+ origin: origin,
+ }
+}
+
+// Origin allows over-riding the default origin.
+func (cs *CodeSearch) Origin(origin string) {
+ cs.origin = origin
+}
+
+// File is a file in a search result.
+type File struct {
+ Name string `json:"name"`
+ PackageName string `json:"package_name"`
+}
+
+// TopFile is the best matching file in a search result.
+type TopFile struct {
+ File File `json:"file"`
+ Size int `json:"size"`
+}
+
+// Text is the text of a snippet.
+type Text struct {
+ Text string `json:"text"`
+}
+
+// Snippet is a matching snippet of code in a search result.
+type Snippet struct {
+ Text Text `json:"text"`
+ FirstLineNumber int `json:"first_line_number"`
+}
+
+// SearchResult is a single result from a search.
+type SearchResult struct {
+ TopFile TopFile `json:"top_file"`
+ NumDuplicates int `json:"num_duplicates"`
+ NumMatches int `json:"num_matches"`
+ Language string `json:"language"`
+ BestMatchingLineNumber int `json:"best_matching_line_number"`
+ Snippet []Snippet `json:"snippet"`
+}
+
+// SearchResponse is the response from CodeSearch.Query.
+type SearchResponse struct {
+ Status int `json:"status"`
+ StatusMessage string `json:"status_message"`
+ EstimatedTotalNumberOfResults int `json:"estimated_total_number_of_results"`
+ ResultsOffset int `json:"results_offset"`
+ NextPageToken string `json:"next_page_token"`
+ SearchResult []SearchResult `json:"search_result"`
+}
+
+// CompoundSearchResponse represents multiple search responses.
+type CompoundSearchResponse struct {
+ Response []SearchResponse `json:"search_response"`
+}
+
+func (cs *CodeSearch) urlForQuery(q string, params url.Values) string {
+ if params == nil {
+ params = url.Values{}
+ }
+ params["query"] = []string{q}
+ encodedQuery := params.Encode()
+ return fmt.Sprintf("%s%s?search_request=b&%s&search_request=e", cs.origin, jsonQueryPath, encodedQuery)
+}
+
+// Query runs a search against the given search service.
+//
+// The query string should conform to any query you would use on
+// https://cs.chromium.org/.
+func (cs CodeSearch) Query(ctx context.Context, q string, params url.Values) (SearchResponse, error) {
+ req, err := http.NewRequest("GET", cs.urlForQuery(q, params), nil)
+ if err != nil {
+ return SearchResponse{}, err
+ }
+ req = req.WithContext(ctx)
+ resp, err := cs.c.Do(req)
+ if err != nil {
+ return SearchResponse{}, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return SearchResponse{}, skerr.Fmt("Bad status code: %d", resp.StatusCode)
+ }
+ var csr CompoundSearchResponse
+ if err := json.NewDecoder(resp.Body).Decode(&csr); err != nil {
+ return SearchResponse{}, err
+ }
+ if len(csr.Response) < 1 {
+ return SearchResponse{}, skerr.Fmt("No results body found")
+ }
+ return csr.Response[0], nil
+}
+
+// URL returns the link to display the TopFile in the SearchResult.
+func (cs CodeSearch) URL(r SearchResult) string {
+ return fmt.Sprintf("%s/%s/%s", cs.origin, r.TopFile.File.PackageName, r.TopFile.File.Name)
+}
diff --git a/go/codesearch/codesearch_test.go b/go/codesearch/codesearch_test.go
new file mode 100644
index 0000000..c48414e
--- /dev/null
+++ b/go/codesearch/codesearch_test.go
@@ -0,0 +1,103 @@
+package codesearch
+
+import (
+ "encoding/json"
+ "net/url"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "go.skia.org/infra/go/testutils/unittest"
+)
+
+const searchResponseBody = `{
+ "search_response": [
+ {
+ "status": 0,
+ "estimated_total_number_of_results": 174,
+ "maybe_skipped_documents": false,
+ "results_offset": 0,
+ "hit_max_results": false,
+ "hit_max_to_score": false,
+ "status_message": "",
+ "percent_shards_skipped": 0,
+ "called_local_augmentation": false,
+ "next_page_token": "CJv...wE=",
+ "search_result": [
+ {
+ "top_file": {
+ "file": {
+ "name": "src/third_party/skia/site/roles.md",
+ "package_name": "chromium"
+ }
+ },
+ "num_duplicates": 0,
+ "num_matches": 0,
+ "language": "markdown",
+ "docid": "svr-40oKURY",
+ "has_unshown_matches": false,
+ "is_augmented": false,
+ "match_reason": {},
+ "full_history_search": false
+ },
+ {
+ "top_file": {
+ "file": {
+ "name": "src/third_party/skia/site/index.md",
+ "package_name": "chromium"
+ }
+ },
+ "num_duplicates": 0,
+ "num_matches": 0,
+ "language": "markdown",
+ "docid": "vAHsr5oQ12k",
+ "has_unshown_matches": false,
+ "is_augmented": false,
+ "match_reason": {},
+ "full_history_search": false
+ }
+ ]
+ }
+ ]
+}`
+
+func TestParse(t *testing.T) {
+ unittest.SmallTest(t)
+
+ var resp CompoundSearchResponse
+ err := json.Unmarshal([]byte(searchResponseBody), &resp)
+ assert.NoError(t, err)
+ assert.Equal(t, 174, resp.Response[0].EstimatedTotalNumberOfResults)
+ assert.Equal(t, "src/third_party/skia/site/roles.md", resp.Response[0].SearchResult[0].TopFile.File.Name)
+ assert.Equal(t, "CJv...wE=", resp.Response[0].NextPageToken)
+}
+
+func TestCodeSearch_urlForQuery(t *testing.T) {
+ unittest.SmallTest(t)
+
+ tests := []struct {
+ name string
+ q string
+ params url.Values
+ want string
+ }{
+ {
+ name: "nil params",
+ q: "file:.md",
+ params: nil,
+ want: "https://cs.chromium.org/codesearch/json/search_request?search_request=b&query=file%3A.md&search_request=e",
+ },
+ {
+ name: "extra params",
+ q: "file:.md",
+ params: url.Values{"foo": []string{"bar"}},
+ want: "https://cs.chromium.org/codesearch/json/search_request?search_request=b&foo=bar&query=file%3A.md&search_request=e",
+ },
+ }
+ cs := New(nil)
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := cs.urlForQuery(tt.q, tt.params)
+ assert.Equal(t, tt.want, got, tt.name)
+ })
+ }
+}
diff --git a/go/issues/issues.go b/go/issues/issues.go
index b52a7dc..1cf6d6b 100644
--- a/go/issues/issues.go
+++ b/go/issues/issues.go
@@ -130,7 +130,7 @@
func get(client *http.Client, u string) ([]Issue, error) {
resp, err := client.Get(u)
if err != nil || resp == nil || resp.StatusCode != 200 {
- return nil, fmt.Errorf("Failed to retrieve issue tracker response: %s", err)
+ return nil, fmt.Errorf("Failed to retrieve issue tracker response: %s Status Code: %d", err, resp.StatusCode)
}
defer util.Close(resp.Body)
diff --git a/go/monorail/v1/monorail.go b/go/monorail/v1/monorail.go
new file mode 100644
index 0000000..b53d089
--- /dev/null
+++ b/go/monorail/v1/monorail.go
@@ -0,0 +1,4691 @@
+// Copyright 2019 Google LLC.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated file. DO NOT EDIT.
+
+// Package monorail provides access to the .
+//
+// For product documentation, see: https://chromium.googlesource.com/infra/infra/+/master/appengine/monorail/doc/api.md
+//
+// Creating a client
+//
+// Usage example:
+//
+// import "go.skia.org/infra/go/monorail/v1"
+// ...
+// ctx := context.Background()
+// monorailService, err := monorail.NewService(ctx)
+//
+// In this example, Google Application Default Credentials are used for authentication.
+//
+// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
+//
+// Other authentication options
+//
+// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
+//
+// monorailService, err := monorail.NewService(ctx, option.WithAPIKey("AIza..."))
+//
+// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
+//
+// config := &oauth2.Config{...}
+// // ...
+// token, err := config.Exchange(ctx, ...)
+// monorailService, err := monorail.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
+//
+// See https://godoc.org/google.golang.org/api/option/ for details on options.
+package monorail // import "go.skia.org/infra/go/monorail/v1"
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+
+ gensupport "google.golang.org/api/gensupport"
+ googleapi "google.golang.org/api/googleapi"
+ option "google.golang.org/api/option"
+ htransport "google.golang.org/api/transport/http"
+)
+
+// Always reference these packages, just in case the auto-generated code
+// below doesn't.
+var _ = bytes.NewBuffer
+var _ = strconv.Itoa
+var _ = fmt.Sprintf
+var _ = json.NewDecoder
+var _ = io.Copy
+var _ = url.Parse
+var _ = gensupport.MarshalJSON
+var _ = googleapi.Version
+var _ = errors.New
+var _ = strings.Replace
+var _ = context.Canceled
+
+const apiId = "monorail:v1"
+const apiName = "monorail"
+const apiVersion = "v1"
+const basePath = "https://monorail-prod.appspot.com/_ah/api/monorail/v1/"
+
+// OAuth2 scopes used by this API.
+const (
+ // https://www.googleapis.com/auth/userinfo.email
+ UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"
+)
+
+// NewService creates a new Service.
+func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
+ scopesOption := option.WithScopes(
+ "https://www.googleapis.com/auth/userinfo.email",
+ )
+ // NOTE: prepend, so we don't override user-specified scopes.
+ opts = append([]option.ClientOption{scopesOption}, opts...)
+ client, endpoint, err := htransport.NewClient(ctx, opts...)
+ if err != nil {
+ return nil, err
+ }
+ s, err := New(client)
+ if err != nil {
+ return nil, err
+ }
+ if endpoint != "" {
+ s.BasePath = endpoint
+ }
+ return s, nil
+}
+
+// New creates a new Service. It uses the provided http.Client for requests.
+//
+// Deprecated: please use NewService instead.
+// To provide a custom HTTP client, use option.WithHTTPClient.
+// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
+func New(client *http.Client) (*Service, error) {
+ if client == nil {
+ return nil, errors.New("client is nil")
+ }
+ s := &Service{client: client, BasePath: basePath}
+ s.Approvals = NewApprovalsService(s)
+ s.Components = NewComponentsService(s)
+ s.Groups = NewGroupsService(s)
+ s.Issues = NewIssuesService(s)
+ s.Users = NewUsersService(s)
+ return s, nil
+}
+
+type Service struct {
+ client *http.Client
+ BasePath string // API endpoint base URL
+ UserAgent string // optional additional User-Agent fragment
+
+ Approvals *ApprovalsService
+
+ Components *ComponentsService
+
+ Groups *GroupsService
+
+ Issues *IssuesService
+
+ Users *UsersService
+}
+
+func (s *Service) userAgent() string {
+ if s.UserAgent == "" {
+ return googleapi.UserAgent
+ }
+ return googleapi.UserAgent + " " + s.UserAgent
+}
+
+func NewApprovalsService(s *Service) *ApprovalsService {
+ rs := &ApprovalsService{s: s}
+ rs.Comments = NewApprovalsCommentsService(s)
+ return rs
+}
+
+type ApprovalsService struct {
+ s *Service
+
+ Comments *ApprovalsCommentsService
+}
+
+func NewApprovalsCommentsService(s *Service) *ApprovalsCommentsService {
+ rs := &ApprovalsCommentsService{s: s}
+ return rs
+}
+
+type ApprovalsCommentsService struct {
+ s *Service
+}
+
+func NewComponentsService(s *Service) *ComponentsService {
+ rs := &ComponentsService{s: s}
+ return rs
+}
+
+type ComponentsService struct {
+ s *Service
+}
+
+func NewGroupsService(s *Service) *GroupsService {
+ rs := &GroupsService{s: s}
+ rs.Settings = NewGroupsSettingsService(s)
+ return rs
+}
+
+type GroupsService struct {
+ s *Service
+
+ Settings *GroupsSettingsService
+}
+
+func NewGroupsSettingsService(s *Service) *GroupsSettingsService {
+ rs := &GroupsSettingsService{s: s}
+ return rs
+}
+
+type GroupsSettingsService struct {
+ s *Service
+}
+
+func NewIssuesService(s *Service) *IssuesService {
+ rs := &IssuesService{s: s}
+ rs.Comments = NewIssuesCommentsService(s)
+ return rs
+}
+
+type IssuesService struct {
+ s *Service
+
+ Comments *IssuesCommentsService
+}
+
+func NewIssuesCommentsService(s *Service) *IssuesCommentsService {
+ rs := &IssuesCommentsService{s: s}
+ return rs
+}
+
+type IssuesCommentsService struct {
+ s *Service
+}
+
+func NewUsersService(s *Service) *UsersService {
+ rs := &UsersService{s: s}
+ return rs
+}
+
+type UsersService struct {
+ s *Service
+}
+
+// ProtoApiPb2V1Approval: Approval Value details
+type ProtoApiPb2V1Approval struct {
+ ApprovalName string `json:"approvalName,omitempty"`
+
+ // Approvers: Atomic person.
+ Approvers []*ProtoApiPb2V1AtomPerson `json:"approvers,omitempty"`
+
+ PhaseName string `json:"phaseName,omitempty"`
+
+ SetOn string `json:"setOn,omitempty"`
+
+ // Setter: Atomic person.
+ Setter *ProtoApiPb2V1AtomPerson `json:"setter,omitempty"`
+
+ // Possible values:
+ // "approved"
+ // "nA"
+ // "needInfo"
+ // "needsReview"
+ // "notApproved"
+ // "notSet"
+ // "reviewRequested"
+ // "reviewStarted"
+ Status string `json:"status,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "ApprovalName") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ApprovalName") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Approval) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Approval
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ApprovalCommentWrapper: Approval comment details.
+type ProtoApiPb2V1ApprovalCommentWrapper struct {
+ // ApprovalUpdates: Approval update.
+ ApprovalUpdates *ProtoApiPb2V1ApprovalUpdate `json:"approvalUpdates,omitempty"`
+
+ // Attachments: Issue attachment.
+ Attachments []*ProtoApiPb2V1Attachment `json:"attachments,omitempty"`
+
+ // Author: Atomic person.
+ Author *ProtoApiPb2V1AtomPerson `json:"author,omitempty"`
+
+ CanDelete bool `json:"canDelete,omitempty"`
+
+ Content string `json:"content,omitempty"`
+
+ // DeletedBy: Atomic person.
+ DeletedBy *ProtoApiPb2V1AtomPerson `json:"deletedBy,omitempty"`
+
+ Id int64 `json:"id,omitempty"`
+
+ IsDescription bool `json:"is_description,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Published string `json:"published,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "ApprovalUpdates") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ApprovalUpdates") to
+ // include in API requests with the JSON null value. By default, fields
+ // with empty values are omitted from API requests. However, any field
+ // with an empty value appearing in NullFields will be sent to the
+ // server as null. It is an error if a field in this list has a
+ // non-empty value. This may be used to include null fields in Patch
+ // requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ApprovalCommentWrapper) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ApprovalCommentWrapper
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ApprovalUpdate: Approval update.
+type ProtoApiPb2V1ApprovalUpdate struct {
+ Approvers []string `json:"approvers,omitempty"`
+
+ // FieldValues: Custom field values.
+ FieldValues []*ProtoApiPb2V1FieldValue `json:"fieldValues,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Status string `json:"status,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Approvers") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Approvers") to include in
+ // API requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ApprovalUpdate) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ApprovalUpdate
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ApprovalsCommentsInsertResponse: Response message of
+// request to insert an isuse's comments.
+type ProtoApiPb2V1ApprovalsCommentsInsertResponse struct {
+ ApprovalName string `json:"approvalName,omitempty"`
+
+ // ApprovalUpdates: Approval update.
+ ApprovalUpdates *ProtoApiPb2V1ApprovalUpdate `json:"approvalUpdates,omitempty"`
+
+ // Author: Atomic person.
+ Author *ProtoApiPb2V1AtomPerson `json:"author,omitempty"`
+
+ CanDelete bool `json:"canDelete,omitempty"`
+
+ Content string `json:"content,omitempty"`
+
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ Id int64 `json:"id,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Published string `json:"published,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "ApprovalName") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ApprovalName") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ApprovalsCommentsInsertResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ApprovalsCommentsInsertResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ApprovalsCommentsListResponse: Response message of
+// request to list an approval's comments.
+type ProtoApiPb2V1ApprovalsCommentsListResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // Items: Approval comment details.
+ Items []*ProtoApiPb2V1ApprovalCommentWrapper `json:"items,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ TotalResults int64 `json:"totalResults,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ApprovalsCommentsListResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ApprovalsCommentsListResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1AtomPerson: Atomic person.
+type ProtoApiPb2V1AtomPerson struct {
+ EmailBouncing bool `json:"email_bouncing,omitempty"`
+
+ HtmlLink string `json:"htmlLink,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ LastVisitDaysAgo int64 `json:"last_visit_days_ago,omitempty,string"`
+
+ Name string `json:"name,omitempty"`
+
+ VacationMessage string `json:"vacation_message,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "EmailBouncing") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "EmailBouncing") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1AtomPerson) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1AtomPerson
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Attachment: Issue attachment.
+type ProtoApiPb2V1Attachment struct {
+ AttachmentId int64 `json:"attachmentId,omitempty,string"`
+
+ FileName string `json:"fileName,omitempty"`
+
+ FileSize int64 `json:"fileSize,omitempty"`
+
+ IsDeleted bool `json:"isDeleted,omitempty"`
+
+ Mimetype string `json:"mimetype,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "AttachmentId") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "AttachmentId") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Attachment) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Attachment
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Component: Component PB.
+type ProtoApiPb2V1Component struct {
+ Admin []string `json:"admin,omitempty"`
+
+ Cc []string `json:"cc,omitempty"`
+
+ ComponentId int64 `json:"componentId,omitempty"`
+
+ ComponentPath string `json:"componentPath,omitempty"`
+
+ Created string `json:"created,omitempty"`
+
+ Creator string `json:"creator,omitempty"`
+
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ Description string `json:"description,omitempty"`
+
+ Modified string `json:"modified,omitempty"`
+
+ Modifier string `json:"modifier,omitempty"`
+
+ ProjectName string `json:"projectName,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Admin") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Admin") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Component) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Component
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ComponentCreateRequestBody: Request body to create a
+// component.
+type ProtoApiPb2V1ComponentCreateRequestBody struct {
+ Admin []string `json:"admin,omitempty"`
+
+ Cc []string `json:"cc,omitempty"`
+
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ Description string `json:"description,omitempty"`
+
+ ParentPath string `json:"parentPath,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Admin") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Admin") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ComponentCreateRequestBody) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ComponentCreateRequestBody
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ComponentUpdate: Component update.
+type ProtoApiPb2V1ComponentUpdate struct {
+ Admin []string `json:"admin,omitempty"`
+
+ Cc []string `json:"cc,omitempty"`
+
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ Description string `json:"description,omitempty"`
+
+ // Possible values:
+ // "ADMIN"
+ // "CC"
+ // "DEPRECATED"
+ // "DESCRIPTION"
+ // "LEAF_NAME"
+ Field string `json:"field,omitempty"`
+
+ LeafName string `json:"leafName,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Admin") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Admin") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ComponentUpdate) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ComponentUpdate
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ComponentUpdateRequestBody: Request body to update a
+// component.
+type ProtoApiPb2V1ComponentUpdateRequestBody struct {
+ // Updates: Component update.
+ Updates []*ProtoApiPb2V1ComponentUpdate `json:"updates,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Updates") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Updates") to include in
+ // API requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ComponentUpdateRequestBody) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ComponentUpdateRequestBody
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ComponentsListResponse: Response to list components.
+type ProtoApiPb2V1ComponentsListResponse struct {
+ // Components: Component PB.
+ Components []*ProtoApiPb2V1Component `json:"components,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Components") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Components") to include in
+ // API requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ComponentsListResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ComponentsListResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ErrorMessage: Request error.
+type ProtoApiPb2V1ErrorMessage struct {
+ Code int64 `json:"code,omitempty"`
+
+ Message string `json:"message,omitempty"`
+
+ Reason string `json:"reason,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Code") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Code") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ErrorMessage) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ErrorMessage
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1FieldValue: Custom field values.
+type ProtoApiPb2V1FieldValue struct {
+ ApprovalName string `json:"approvalName,omitempty"`
+
+ Derived bool `json:"derived,omitempty"`
+
+ FieldName string `json:"fieldName,omitempty"`
+
+ FieldValue string `json:"fieldValue,omitempty"`
+
+ // Possible values:
+ // "add" (default)
+ // "clear"
+ // "remove"
+ Operator string `json:"operator,omitempty"`
+
+ PhaseName string `json:"phaseName,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "ApprovalName") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ApprovalName") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1FieldValue) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1FieldValue
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1GroupCitizens: Group members and owners.
+type ProtoApiPb2V1GroupCitizens struct {
+ GroupMembers []string `json:"groupMembers,omitempty"`
+
+ GroupOwners []string `json:"groupOwners,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "GroupMembers") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "GroupMembers") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1GroupCitizens) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1GroupCitizens
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1GroupsCreateResponse: Response message of request to
+// create a group.
+type ProtoApiPb2V1GroupsCreateResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ GroupID int64 `json:"groupID,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1GroupsCreateResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1GroupsCreateResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1GroupsGetResponse: Response message of request to create
+// a group.
+type ProtoApiPb2V1GroupsGetResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ GroupID int64 `json:"groupID,omitempty"`
+
+ GroupMembers []string `json:"groupMembers,omitempty"`
+
+ GroupOwners []string `json:"groupOwners,omitempty"`
+
+ // GroupSettings: User group settings.
+ GroupSettings *ProtoApiPb2V1UserGroupSettingsWrapper `json:"groupSettings,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1GroupsGetResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1GroupsGetResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1GroupsSettingsListResponse: Response message of request
+// to list group settings.
+type ProtoApiPb2V1GroupsSettingsListResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // GroupSettings: User group settings.
+ GroupSettings []*ProtoApiPb2V1UserGroupSettingsWrapper `json:"groupSettings,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1GroupsSettingsListResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1GroupsSettingsListResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1GroupsUpdateResponse: Response message of request to
+// update a group.
+type ProtoApiPb2V1GroupsUpdateResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1GroupsUpdateResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1GroupsUpdateResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssueCommentWrapper: Issue comment details.
+type ProtoApiPb2V1IssueCommentWrapper struct {
+ // Attachments: Issue attachment.
+ Attachments []*ProtoApiPb2V1Attachment `json:"attachments,omitempty"`
+
+ // Author: Atomic person.
+ Author *ProtoApiPb2V1AtomPerson `json:"author,omitempty"`
+
+ CanDelete bool `json:"canDelete,omitempty"`
+
+ Content string `json:"content,omitempty"`
+
+ // DeletedBy: Atomic person.
+ DeletedBy *ProtoApiPb2V1AtomPerson `json:"deletedBy,omitempty"`
+
+ Id int64 `json:"id,omitempty"`
+
+ IsDescription bool `json:"is_description,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Published string `json:"published,omitempty"`
+
+ // Updates: Issue update.
+ Updates *ProtoApiPb2V1Update `json:"updates,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Attachments") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Attachments") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssueCommentWrapper) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssueCommentWrapper
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssueRef: Issue reference.
+type ProtoApiPb2V1IssueRef struct {
+ IssueId int64 `json:"issueId,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ ProjectId string `json:"projectId,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "IssueId") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "IssueId") to include in
+ // API requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssueRef) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssueRef
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssueWrapper: Issue details.
+type ProtoApiPb2V1IssueWrapper struct {
+ // ApprovalValues: Approval Value details
+ ApprovalValues []*ProtoApiPb2V1Approval `json:"approvalValues,omitempty"`
+
+ // Author: Atomic person.
+ Author *ProtoApiPb2V1AtomPerson `json:"author,omitempty"`
+
+ // BlockedOn: Issue reference.
+ BlockedOn []*ProtoApiPb2V1IssueRef `json:"blockedOn,omitempty"`
+
+ // Blocking: Issue reference.
+ Blocking []*ProtoApiPb2V1IssueRef `json:"blocking,omitempty"`
+
+ CanComment bool `json:"canComment,omitempty"`
+
+ CanEdit bool `json:"canEdit,omitempty"`
+
+ // Cc: Atomic person.
+ Cc []*ProtoApiPb2V1AtomPerson `json:"cc,omitempty"`
+
+ Closed string `json:"closed,omitempty"`
+
+ ComponentModified string `json:"component_modified,omitempty"`
+
+ Components []string `json:"components,omitempty"`
+
+ Description string `json:"description,omitempty"`
+
+ // FieldValues: Custom field values.
+ FieldValues []*ProtoApiPb2V1FieldValue `json:"fieldValues,omitempty"`
+
+ Id int64 `json:"id,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Labels []string `json:"labels,omitempty"`
+
+ // MergedInto: Issue reference.
+ MergedInto *ProtoApiPb2V1IssueRef `json:"mergedInto,omitempty"`
+
+ // Owner: Atomic person.
+ Owner *ProtoApiPb2V1AtomPerson `json:"owner,omitempty"`
+
+ OwnerModified string `json:"owner_modified,omitempty"`
+
+ // Phases: Issue phase details.
+ Phases []*ProtoApiPb2V1Phase `json:"phases,omitempty"`
+
+ ProjectId string `json:"projectId,omitempty"`
+
+ Published string `json:"published,omitempty"`
+
+ Starred bool `json:"starred,omitempty"`
+
+ Stars int64 `json:"stars,omitempty"`
+
+ // Possible values:
+ // "closed"
+ // "open"
+ State string `json:"state,omitempty"`
+
+ Status string `json:"status,omitempty"`
+
+ StatusModified string `json:"status_modified,omitempty"`
+
+ Summary string `json:"summary,omitempty"`
+
+ Title string `json:"title,omitempty"`
+
+ Updated string `json:"updated,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "ApprovalValues") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ApprovalValues") to
+ // include in API requests with the JSON null value. By default, fields
+ // with empty values are omitted from API requests. However, any field
+ // with an empty value appearing in NullFields will be sent to the
+ // server as null. It is an error if a field in this list has a
+ // non-empty value. This may be used to include null fields in Patch
+ // requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssueWrapper) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssueWrapper
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssuesCommentsDeleteResponse: Response message of
+// request to delete/undelete an issue's comments.
+type ProtoApiPb2V1IssuesCommentsDeleteResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssuesCommentsDeleteResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssuesCommentsDeleteResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssuesCommentsInsertResponse: Response message of
+// request to insert an issue's comments.
+type ProtoApiPb2V1IssuesCommentsInsertResponse struct {
+ // Author: Atomic person.
+ Author *ProtoApiPb2V1AtomPerson `json:"author,omitempty"`
+
+ CanDelete bool `json:"canDelete,omitempty"`
+
+ Content string `json:"content,omitempty"`
+
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ Id int64 `json:"id,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Published string `json:"published,omitempty"`
+
+ // Updates: Issue update.
+ Updates *ProtoApiPb2V1Update `json:"updates,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Author") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Author") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssuesCommentsInsertResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssuesCommentsInsertResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssuesCommentsListResponse: Response message of request
+// to list an issue's comments.
+type ProtoApiPb2V1IssuesCommentsListResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // Items: Issue comment details.
+ Items []*ProtoApiPb2V1IssueCommentWrapper `json:"items,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ TotalResults int64 `json:"totalResults,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssuesCommentsListResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssuesCommentsListResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssuesGetInsertResponse: Response message of request to
+// get/insert an issue.
+type ProtoApiPb2V1IssuesGetInsertResponse struct {
+ // ApprovalValues: Approval Value details
+ ApprovalValues []*ProtoApiPb2V1Approval `json:"approvalValues,omitempty"`
+
+ // Author: Atomic person.
+ Author *ProtoApiPb2V1AtomPerson `json:"author,omitempty"`
+
+ // BlockedOn: Issue reference.
+ BlockedOn []*ProtoApiPb2V1IssueRef `json:"blockedOn,omitempty"`
+
+ // Blocking: Issue reference.
+ Blocking []*ProtoApiPb2V1IssueRef `json:"blocking,omitempty"`
+
+ CanComment bool `json:"canComment,omitempty"`
+
+ CanEdit bool `json:"canEdit,omitempty"`
+
+ // Cc: Atomic person.
+ Cc []*ProtoApiPb2V1AtomPerson `json:"cc,omitempty"`
+
+ Closed string `json:"closed,omitempty"`
+
+ ComponentModified string `json:"component_modified,omitempty"`
+
+ Components []string `json:"components,omitempty"`
+
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // FieldValues: Custom field values.
+ FieldValues []*ProtoApiPb2V1FieldValue `json:"fieldValues,omitempty"`
+
+ Id int64 `json:"id,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Labels []string `json:"labels,omitempty"`
+
+ // MergedInto: Issue reference.
+ MergedInto *ProtoApiPb2V1IssueRef `json:"mergedInto,omitempty"`
+
+ // Owner: Atomic person.
+ Owner *ProtoApiPb2V1AtomPerson `json:"owner,omitempty"`
+
+ OwnerModified string `json:"owner_modified,omitempty"`
+
+ // Phases: Issue phase details.
+ Phases []*ProtoApiPb2V1Phase `json:"phases,omitempty"`
+
+ ProjectId string `json:"projectId,omitempty"`
+
+ Published string `json:"published,omitempty"`
+
+ Starred bool `json:"starred,omitempty"`
+
+ Stars int64 `json:"stars,omitempty"`
+
+ // Possible values:
+ // "closed"
+ // "open"
+ State string `json:"state,omitempty"`
+
+ Status string `json:"status,omitempty"`
+
+ StatusModified string `json:"status_modified,omitempty"`
+
+ Summary string `json:"summary,omitempty"`
+
+ Title string `json:"title,omitempty"`
+
+ Updated string `json:"updated,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "ApprovalValues") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ApprovalValues") to
+ // include in API requests with the JSON null value. By default, fields
+ // with empty values are omitted from API requests. However, any field
+ // with an empty value appearing in NullFields will be sent to the
+ // server as null. It is an error if a field in this list has a
+ // non-empty value. This may be used to include null fields in Patch
+ // requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssuesGetInsertResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssuesGetInsertResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1IssuesListResponse: Response message of request to list
+// issues.
+type ProtoApiPb2V1IssuesListResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ // Items: Issue details.
+ Items []*ProtoApiPb2V1IssueWrapper `json:"items,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ TotalResults int64 `json:"totalResults,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1IssuesListResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1IssuesListResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Label: Issue label.
+type ProtoApiPb2V1Label struct {
+ Description string `json:"description,omitempty"`
+
+ Label string `json:"label,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Description") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Description") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Label) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Label
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Phase: Issue phase details.
+type ProtoApiPb2V1Phase struct {
+ PhaseName string `json:"phaseName,omitempty"`
+
+ Rank int64 `json:"rank,omitempty,string"`
+
+ // ForceSendFields is a list of field names (e.g. "PhaseName") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "PhaseName") to include in
+ // API requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Phase) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Phase
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ProjectIssueConfig: Issue configuration of project.
+type ProtoApiPb2V1ProjectIssueConfig struct {
+ DefaultColumns []string `json:"defaultColumns,omitempty"`
+
+ DefaultPromptForMembers int64 `json:"defaultPromptForMembers,omitempty"`
+
+ DefaultPromptForNonMembers int64 `json:"defaultPromptForNonMembers,omitempty"`
+
+ DefaultSorting []string `json:"defaultSorting,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ // Labels: Issue label.
+ Labels []*ProtoApiPb2V1Label `json:"labels,omitempty"`
+
+ // Prompts: Default issue template values.
+ Prompts []*ProtoApiPb2V1Prompt `json:"prompts,omitempty"`
+
+ RestrictToKnown bool `json:"restrictToKnown,omitempty"`
+
+ // Statuses: Issue status.
+ Statuses []*ProtoApiPb2V1Status `json:"statuses,omitempty"`
+
+ UsersCanSetLabels bool `json:"usersCanSetLabels,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "DefaultColumns") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "DefaultColumns") to
+ // include in API requests with the JSON null value. By default, fields
+ // with empty values are omitted from API requests. However, any field
+ // with an empty value appearing in NullFields will be sent to the
+ // server as null. It is an error if a field in this list has a
+ // non-empty value. This may be used to include null fields in Patch
+ // requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ProjectIssueConfig) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ProjectIssueConfig
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1ProjectWrapper: Project details.
+type ProtoApiPb2V1ProjectWrapper struct {
+ Description string `json:"description,omitempty"`
+
+ ExternalId string `json:"externalId,omitempty"`
+
+ HtmlLink string `json:"htmlLink,omitempty"`
+
+ // IssuesConfig: Issue configuration of project.
+ IssuesConfig *ProtoApiPb2V1ProjectIssueConfig `json:"issuesConfig,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ // Members: Atomic person.
+ Members []*ProtoApiPb2V1AtomPerson `json:"members,omitempty"`
+
+ Name string `json:"name,omitempty"`
+
+ RepositoryUrls []string `json:"repositoryUrls,omitempty"`
+
+ // Possible values:
+ // "contributor"
+ // "member"
+ // "owner"
+ Role string `json:"role,omitempty"`
+
+ Summary string `json:"summary,omitempty"`
+
+ VersionControlSystem string `json:"versionControlSystem,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Description") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Description") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1ProjectWrapper) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1ProjectWrapper
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Prompt: Default issue template values.
+type ProtoApiPb2V1Prompt struct {
+ ComponentRequired bool `json:"componentRequired,omitempty"`
+
+ DefaultToMember bool `json:"defaultToMember,omitempty"`
+
+ Description string `json:"description,omitempty"`
+
+ Labels []string `json:"labels,omitempty"`
+
+ MembersOnly bool `json:"membersOnly,omitempty"`
+
+ Name string `json:"name,omitempty"`
+
+ Status string `json:"status,omitempty"`
+
+ Title string `json:"title,omitempty"`
+
+ TitleMustBeEdited bool `json:"titleMustBeEdited,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "ComponentRequired")
+ // to unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ComponentRequired") to
+ // include in API requests with the JSON null value. By default, fields
+ // with empty values are omitted from API requests. However, any field
+ // with an empty value appearing in NullFields will be sent to the
+ // server as null. It is an error if a field in this list has a
+ // non-empty value. This may be used to include null fields in Patch
+ // requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Prompt) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Prompt
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Status: Issue status.
+type ProtoApiPb2V1Status struct {
+ Description string `json:"description,omitempty"`
+
+ MeansOpen bool `json:"meansOpen,omitempty"`
+
+ Status string `json:"status,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "Description") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Description") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Status) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Status
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1Update: Issue update.
+type ProtoApiPb2V1Update struct {
+ BlockedOn []string `json:"blockedOn,omitempty"`
+
+ Blocking []string `json:"blocking,omitempty"`
+
+ Cc []string `json:"cc,omitempty"`
+
+ Components []string `json:"components,omitempty"`
+
+ // FieldValues: Custom field values.
+ FieldValues []*ProtoApiPb2V1FieldValue `json:"fieldValues,omitempty"`
+
+ IsDescription bool `json:"is_description,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ Labels []string `json:"labels,omitempty"`
+
+ MergedInto string `json:"mergedInto,omitempty"`
+
+ MoveToProject string `json:"moveToProject,omitempty"`
+
+ Owner string `json:"owner,omitempty"`
+
+ Status string `json:"status,omitempty"`
+
+ Summary string `json:"summary,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "BlockedOn") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "BlockedOn") to include in
+ // API requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1Update) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1Update
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1UserGroupSettingsWrapper: User group settings.
+type ProtoApiPb2V1UserGroupSettingsWrapper struct {
+ // Possible values:
+ // "BAGGINS"
+ // "CHROME_INFRA_AUTH"
+ // "COMPUTED"
+ // "MDB"
+ ExtGroupType string `json:"ext_group_type,omitempty"`
+
+ GroupName string `json:"groupName,omitempty"`
+
+ LastSyncTime int64 `json:"last_sync_time,omitempty"`
+
+ // Possible values:
+ // "ANYONE"
+ // "MEMBERS" (default)
+ // "OWNERS"
+ WhoCanViewMembers string `json:"who_can_view_members,omitempty"`
+
+ // ForceSendFields is a list of field names (e.g. "ExtGroupType") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "ExtGroupType") to include
+ // in API requests with the JSON null value. By default, fields with
+ // empty values are omitted from API requests. However, any field with
+ // an empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1UserGroupSettingsWrapper) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1UserGroupSettingsWrapper
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// ProtoApiPb2V1UsersGetResponse: Response message of request to get a
+// user.
+type ProtoApiPb2V1UsersGetResponse struct {
+ // Error: Request error.
+ Error *ProtoApiPb2V1ErrorMessage `json:"error,omitempty"`
+
+ Id string `json:"id,omitempty"`
+
+ Kind string `json:"kind,omitempty"`
+
+ // Projects: Project details.
+ Projects []*ProtoApiPb2V1ProjectWrapper `json:"projects,omitempty"`
+
+ // ServerResponse contains the HTTP response code and headers from the
+ // server.
+ googleapi.ServerResponse `json:"-"`
+
+ // ForceSendFields is a list of field names (e.g. "Error") to
+ // unconditionally include in API requests. By default, fields with
+ // empty values are omitted from API requests. However, any non-pointer,
+ // non-interface field appearing in ForceSendFields will be sent to the
+ // server regardless of whether the field is empty or not. This may be
+ // used to include empty fields in Patch requests.
+ ForceSendFields []string `json:"-"`
+
+ // NullFields is a list of field names (e.g. "Error") to include in API
+ // requests with the JSON null value. By default, fields with empty
+ // values are omitted from API requests. However, any field with an
+ // empty value appearing in NullFields will be sent to the server as
+ // null. It is an error if a field in this list has a non-empty value.
+ // This may be used to include null fields in Patch requests.
+ NullFields []string `json:"-"`
+}
+
+func (s *ProtoApiPb2V1UsersGetResponse) MarshalJSON() ([]byte, error) {
+ type NoMethod ProtoApiPb2V1UsersGetResponse
+ raw := NoMethod(*s)
+ return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
+}
+
+// method id "monorail.approvals.comments.insert":
+
+type ApprovalsCommentsInsertCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ approvalName string
+ protoapipb2v1approvalcommentwrapper *ProtoApiPb2V1ApprovalCommentWrapper
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Insert: Add an approval comment.
+func (r *ApprovalsCommentsService) Insert(projectId string, issueId int64, approvalName string, protoapipb2v1approvalcommentwrapper *ProtoApiPb2V1ApprovalCommentWrapper) *ApprovalsCommentsInsertCall {
+ c := &ApprovalsCommentsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ c.approvalName = approvalName
+ c.protoapipb2v1approvalcommentwrapper = protoapipb2v1approvalcommentwrapper
+ return c
+}
+
+// SendEmail sets the optional parameter "sendEmail":
+func (c *ApprovalsCommentsInsertCall) SendEmail(sendEmail bool) *ApprovalsCommentsInsertCall {
+ c.urlParams_.Set("sendEmail", fmt.Sprint(sendEmail))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ApprovalsCommentsInsertCall) Fields(s ...googleapi.Field) *ApprovalsCommentsInsertCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ApprovalsCommentsInsertCall) Context(ctx context.Context) *ApprovalsCommentsInsertCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ApprovalsCommentsInsertCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *ApprovalsCommentsInsertCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ body, err := googleapi.WithoutDataWrapper.JSONReader(c.protoapipb2v1approvalcommentwrapper)
+ if err != nil {
+ return nil, err
+ }
+ reqHeaders.Set("Content-Type", "application/json")
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}/approvals/{approvalName}/comments")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ "approvalName": c.approvalName,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.approvals.comments.insert" call.
+// Exactly one of *ProtoApiPb2V1ApprovalsCommentsInsertResponse or error
+// will be non-nil. Any non-2xx status code is an error. Response
+// headers are in either
+// *ProtoApiPb2V1ApprovalsCommentsInsertResponse.ServerResponse.Header
+// or (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *ApprovalsCommentsInsertCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1ApprovalsCommentsInsertResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1ApprovalsCommentsInsertResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Add an approval comment.",
+ // "httpMethod": "POST",
+ // "id": "monorail.approvals.comments.insert",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId",
+ // "approvalName"
+ // ],
+ // "parameters": {
+ // "approvalName": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "sendEmail": {
+ // "location": "query",
+ // "type": "boolean"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}/approvals/{approvalName}/comments",
+ // "request": {
+ // "$ref": "ProtoApiPb2V1ApprovalCommentWrapper",
+ // "parameterName": "resource"
+ // },
+ // "response": {
+ // "$ref": "ProtoApiPb2V1ApprovalsCommentsInsertResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.approvals.comments.list":
+
+type ApprovalsCommentsListCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ approvalName string
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// List: List all comments for an issue approval.
+func (r *ApprovalsCommentsService) List(projectId string, issueId int64, approvalName string) *ApprovalsCommentsListCall {
+ c := &ApprovalsCommentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ c.approvalName = approvalName
+ return c
+}
+
+// MaxResults sets the optional parameter "maxResults":
+func (c *ApprovalsCommentsListCall) MaxResults(maxResults int64) *ApprovalsCommentsListCall {
+ c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
+ return c
+}
+
+// StartIndex sets the optional parameter "startIndex":
+func (c *ApprovalsCommentsListCall) StartIndex(startIndex int64) *ApprovalsCommentsListCall {
+ c.urlParams_.Set("startIndex", fmt.Sprint(startIndex))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ApprovalsCommentsListCall) Fields(s ...googleapi.Field) *ApprovalsCommentsListCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *ApprovalsCommentsListCall) IfNoneMatch(entityTag string) *ApprovalsCommentsListCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ApprovalsCommentsListCall) Context(ctx context.Context) *ApprovalsCommentsListCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ApprovalsCommentsListCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *ApprovalsCommentsListCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}/approvals/{approvalName}/comments")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ "approvalName": c.approvalName,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.approvals.comments.list" call.
+// Exactly one of *ProtoApiPb2V1ApprovalsCommentsListResponse or error
+// will be non-nil. Any non-2xx status code is an error. Response
+// headers are in either
+// *ProtoApiPb2V1ApprovalsCommentsListResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *ApprovalsCommentsListCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1ApprovalsCommentsListResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1ApprovalsCommentsListResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "List all comments for an issue approval.",
+ // "httpMethod": "GET",
+ // "id": "monorail.approvals.comments.list",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId",
+ // "approvalName"
+ // ],
+ // "parameters": {
+ // "approvalName": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "maxResults": {
+ // "default": "100",
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "startIndex": {
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}/approvals/{approvalName}/comments",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1ApprovalsCommentsListResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.components.create":
+
+type ComponentsCreateCall struct {
+ s *Service
+ projectId string
+ protoapipb2v1componentcreaterequestbody *ProtoApiPb2V1ComponentCreateRequestBody
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Create: Create a component.
+func (r *ComponentsService) Create(projectId string, componentName string, protoapipb2v1componentcreaterequestbody *ProtoApiPb2V1ComponentCreateRequestBody) *ComponentsCreateCall {
+ c := &ComponentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.urlParams_.Set("componentName", componentName)
+ c.protoapipb2v1componentcreaterequestbody = protoapipb2v1componentcreaterequestbody
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ComponentsCreateCall) Fields(s ...googleapi.Field) *ComponentsCreateCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ComponentsCreateCall) Context(ctx context.Context) *ComponentsCreateCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ComponentsCreateCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *ComponentsCreateCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ body, err := googleapi.WithoutDataWrapper.JSONReader(c.protoapipb2v1componentcreaterequestbody)
+ if err != nil {
+ return nil, err
+ }
+ reqHeaders.Set("Content-Type", "application/json")
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/components")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.components.create" call.
+// Exactly one of *ProtoApiPb2V1Component or error will be non-nil. Any
+// non-2xx status code is an error. Response headers are in either
+// *ProtoApiPb2V1Component.ServerResponse.Header or (if a response was
+// returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *ComponentsCreateCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1Component, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1Component{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Create a component.",
+ // "httpMethod": "POST",
+ // "id": "monorail.components.create",
+ // "parameterOrder": [
+ // "projectId",
+ // "componentName"
+ // ],
+ // "parameters": {
+ // "componentName": {
+ // "location": "query",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/components",
+ // "request": {
+ // "$ref": "ProtoApiPb2V1ComponentCreateRequestBody",
+ // "parameterName": "resource"
+ // },
+ // "response": {
+ // "$ref": "ProtoApiPb2V1Component"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.components.delete":
+
+type ComponentsDeleteCall struct {
+ s *Service
+ projectId string
+ componentPath string
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Delete: Delete a component.
+func (r *ComponentsService) Delete(projectId string, componentPath string) *ComponentsDeleteCall {
+ c := &ComponentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.componentPath = componentPath
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ComponentsDeleteCall) Fields(s ...googleapi.Field) *ComponentsDeleteCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ComponentsDeleteCall) Context(ctx context.Context) *ComponentsDeleteCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ComponentsDeleteCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *ComponentsDeleteCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/components/{componentPath}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("DELETE", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "componentPath": c.componentPath,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.components.delete" call.
+func (c *ComponentsDeleteCall) Do(opts ...googleapi.CallOption) error {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if err != nil {
+ return err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return err
+ }
+ return nil
+ // {
+ // "description": "Delete a component.",
+ // "httpMethod": "DELETE",
+ // "id": "monorail.components.delete",
+ // "parameterOrder": [
+ // "projectId",
+ // "componentPath"
+ // ],
+ // "parameters": {
+ // "componentPath": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/components/{componentPath}",
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.components.list":
+
+type ComponentsListCall struct {
+ s *Service
+ projectId string
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// List: List all components of a given project.
+func (r *ComponentsService) List(projectId string) *ComponentsListCall {
+ c := &ComponentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ComponentsListCall) Fields(s ...googleapi.Field) *ComponentsListCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *ComponentsListCall) IfNoneMatch(entityTag string) *ComponentsListCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ComponentsListCall) Context(ctx context.Context) *ComponentsListCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ComponentsListCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *ComponentsListCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/components")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.components.list" call.
+// Exactly one of *ProtoApiPb2V1ComponentsListResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1ComponentsListResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *ComponentsListCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1ComponentsListResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1ComponentsListResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "List all components of a given project.",
+ // "httpMethod": "GET",
+ // "id": "monorail.components.list",
+ // "parameterOrder": [
+ // "projectId"
+ // ],
+ // "parameters": {
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/components",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1ComponentsListResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.components.update":
+
+type ComponentsUpdateCall struct {
+ s *Service
+ projectId string
+ componentPath string
+ protoapipb2v1componentupdaterequestbody *ProtoApiPb2V1ComponentUpdateRequestBody
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Update: Update a component.
+func (r *ComponentsService) Update(projectId string, componentPath string, protoapipb2v1componentupdaterequestbody *ProtoApiPb2V1ComponentUpdateRequestBody) *ComponentsUpdateCall {
+ c := &ComponentsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.componentPath = componentPath
+ c.protoapipb2v1componentupdaterequestbody = protoapipb2v1componentupdaterequestbody
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *ComponentsUpdateCall) Fields(s ...googleapi.Field) *ComponentsUpdateCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *ComponentsUpdateCall) Context(ctx context.Context) *ComponentsUpdateCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *ComponentsUpdateCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *ComponentsUpdateCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ body, err := googleapi.WithoutDataWrapper.JSONReader(c.protoapipb2v1componentupdaterequestbody)
+ if err != nil {
+ return nil, err
+ }
+ reqHeaders.Set("Content-Type", "application/json")
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/components/{componentPath}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "componentPath": c.componentPath,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.components.update" call.
+func (c *ComponentsUpdateCall) Do(opts ...googleapi.CallOption) error {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if err != nil {
+ return err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return err
+ }
+ return nil
+ // {
+ // "description": "Update a component.",
+ // "httpMethod": "POST",
+ // "id": "monorail.components.update",
+ // "parameterOrder": [
+ // "projectId",
+ // "componentPath"
+ // ],
+ // "parameters": {
+ // "componentPath": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/components/{componentPath}",
+ // "request": {
+ // "$ref": "ProtoApiPb2V1ComponentUpdateRequestBody",
+ // "parameterName": "resource"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.groups.create":
+
+type GroupsCreateCall struct {
+ s *Service
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Create: Create a new user group.
+func (r *GroupsService) Create(groupName string, whoCanViewMembers string) *GroupsCreateCall {
+ c := &GroupsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.urlParams_.Set("groupName", groupName)
+ c.urlParams_.Set("who_can_view_members", whoCanViewMembers)
+ return c
+}
+
+// ExtGroupType sets the optional parameter "ext_group_type":
+//
+// Possible values:
+// "BAGGINS"
+// "CHROME_INFRA_AUTH"
+// "COMPUTED"
+// "MDB"
+func (c *GroupsCreateCall) ExtGroupType(extGroupType string) *GroupsCreateCall {
+ c.urlParams_.Set("ext_group_type", extGroupType)
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *GroupsCreateCall) Fields(s ...googleapi.Field) *GroupsCreateCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *GroupsCreateCall) Context(ctx context.Context) *GroupsCreateCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *GroupsCreateCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *GroupsCreateCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "groups")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.groups.create" call.
+// Exactly one of *ProtoApiPb2V1GroupsCreateResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1GroupsCreateResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *GroupsCreateCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1GroupsCreateResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1GroupsCreateResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Create a new user group.",
+ // "httpMethod": "POST",
+ // "id": "monorail.groups.create",
+ // "parameterOrder": [
+ // "groupName",
+ // "who_can_view_members"
+ // ],
+ // "parameters": {
+ // "ext_group_type": {
+ // "enum": [
+ // "BAGGINS",
+ // "CHROME_INFRA_AUTH",
+ // "COMPUTED",
+ // "MDB"
+ // ],
+ // "enumDescriptions": [
+ // "",
+ // "",
+ // "",
+ // ""
+ // ],
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "groupName": {
+ // "location": "query",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "who_can_view_members": {
+ // "default": "MEMBERS",
+ // "enum": [
+ // "ANYONE",
+ // "MEMBERS",
+ // "OWNERS"
+ // ],
+ // "enumDescriptions": [
+ // "",
+ // "",
+ // ""
+ // ],
+ // "location": "query",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "groups",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1GroupsCreateResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.groups.get":
+
+type GroupsGetCall struct {
+ s *Service
+ groupName string
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Get: Get a group's settings and users.
+func (r *GroupsService) Get(groupName string) *GroupsGetCall {
+ c := &GroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.groupName = groupName
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *GroupsGetCall) Fields(s ...googleapi.Field) *GroupsGetCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *GroupsGetCall) IfNoneMatch(entityTag string) *GroupsGetCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *GroupsGetCall) Context(ctx context.Context) *GroupsGetCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *GroupsGetCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *GroupsGetCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "groups/{groupName}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "groupName": c.groupName,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.groups.get" call.
+// Exactly one of *ProtoApiPb2V1GroupsGetResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1GroupsGetResponse.ServerResponse.Header or (if a
+// response was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *GroupsGetCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1GroupsGetResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1GroupsGetResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Get a group's settings and users.",
+ // "httpMethod": "GET",
+ // "id": "monorail.groups.get",
+ // "parameterOrder": [
+ // "groupName"
+ // ],
+ // "parameters": {
+ // "groupName": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "groups/{groupName}",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1GroupsGetResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.groups.update":
+
+type GroupsUpdateCall struct {
+ s *Service
+ groupName string
+ protoapipb2v1groupcitizens *ProtoApiPb2V1GroupCitizens
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Update: Update a group's settings and users.
+func (r *GroupsService) Update(groupName string, protoapipb2v1groupcitizens *ProtoApiPb2V1GroupCitizens) *GroupsUpdateCall {
+ c := &GroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.groupName = groupName
+ c.protoapipb2v1groupcitizens = protoapipb2v1groupcitizens
+ return c
+}
+
+// ExtGroupType sets the optional parameter "ext_group_type":
+//
+// Possible values:
+// "BAGGINS"
+// "CHROME_INFRA_AUTH"
+// "COMPUTED"
+// "MDB"
+func (c *GroupsUpdateCall) ExtGroupType(extGroupType string) *GroupsUpdateCall {
+ c.urlParams_.Set("ext_group_type", extGroupType)
+ return c
+}
+
+// FriendProjects sets the optional parameter "friend_projects":
+func (c *GroupsUpdateCall) FriendProjects(friendProjects ...string) *GroupsUpdateCall {
+ c.urlParams_.SetMulti("friend_projects", append([]string{}, friendProjects...))
+ return c
+}
+
+// LastSyncTime sets the optional parameter "last_sync_time":
+func (c *GroupsUpdateCall) LastSyncTime(lastSyncTime int64) *GroupsUpdateCall {
+ c.urlParams_.Set("last_sync_time", fmt.Sprint(lastSyncTime))
+ return c
+}
+
+// WhoCanViewMembers sets the optional parameter "who_can_view_members":
+//
+// Possible values:
+// "ANYONE"
+// "MEMBERS"
+// "OWNERS"
+func (c *GroupsUpdateCall) WhoCanViewMembers(whoCanViewMembers string) *GroupsUpdateCall {
+ c.urlParams_.Set("who_can_view_members", whoCanViewMembers)
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *GroupsUpdateCall) Fields(s ...googleapi.Field) *GroupsUpdateCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *GroupsUpdateCall) Context(ctx context.Context) *GroupsUpdateCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *GroupsUpdateCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *GroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ body, err := googleapi.WithoutDataWrapper.JSONReader(c.protoapipb2v1groupcitizens)
+ if err != nil {
+ return nil, err
+ }
+ reqHeaders.Set("Content-Type", "application/json")
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "groups/{groupName}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "groupName": c.groupName,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.groups.update" call.
+// Exactly one of *ProtoApiPb2V1GroupsUpdateResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1GroupsUpdateResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *GroupsUpdateCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1GroupsUpdateResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1GroupsUpdateResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Update a group's settings and users.",
+ // "httpMethod": "POST",
+ // "id": "monorail.groups.update",
+ // "parameterOrder": [
+ // "groupName"
+ // ],
+ // "parameters": {
+ // "ext_group_type": {
+ // "enum": [
+ // "BAGGINS",
+ // "CHROME_INFRA_AUTH",
+ // "COMPUTED",
+ // "MDB"
+ // ],
+ // "enumDescriptions": [
+ // "",
+ // "",
+ // "",
+ // ""
+ // ],
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "friend_projects": {
+ // "location": "query",
+ // "repeated": true,
+ // "type": "string"
+ // },
+ // "groupName": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "last_sync_time": {
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // },
+ // "who_can_view_members": {
+ // "enum": [
+ // "ANYONE",
+ // "MEMBERS",
+ // "OWNERS"
+ // ],
+ // "enumDescriptions": [
+ // "",
+ // "",
+ // ""
+ // ],
+ // "location": "query",
+ // "type": "string"
+ // }
+ // },
+ // "path": "groups/{groupName}",
+ // "request": {
+ // "$ref": "ProtoApiPb2V1GroupCitizens",
+ // "parameterName": "resource"
+ // },
+ // "response": {
+ // "$ref": "ProtoApiPb2V1GroupsUpdateResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.groups.settings.list":
+
+type GroupsSettingsListCall struct {
+ s *Service
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// List: List all group settings.
+func (r *GroupsSettingsService) List() *GroupsSettingsListCall {
+ c := &GroupsSettingsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ return c
+}
+
+// ImportedGroupsOnly sets the optional parameter "importedGroupsOnly":
+func (c *GroupsSettingsListCall) ImportedGroupsOnly(importedGroupsOnly bool) *GroupsSettingsListCall {
+ c.urlParams_.Set("importedGroupsOnly", fmt.Sprint(importedGroupsOnly))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *GroupsSettingsListCall) Fields(s ...googleapi.Field) *GroupsSettingsListCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *GroupsSettingsListCall) IfNoneMatch(entityTag string) *GroupsSettingsListCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *GroupsSettingsListCall) Context(ctx context.Context) *GroupsSettingsListCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *GroupsSettingsListCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *GroupsSettingsListCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "groupsettings")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.groups.settings.list" call.
+// Exactly one of *ProtoApiPb2V1GroupsSettingsListResponse or error will
+// be non-nil. Any non-2xx status code is an error. Response headers are
+// in either
+// *ProtoApiPb2V1GroupsSettingsListResponse.ServerResponse.Header or (if
+// a response was returned at all) in error.(*googleapi.Error).Header.
+// Use googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *GroupsSettingsListCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1GroupsSettingsListResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1GroupsSettingsListResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "List all group settings.",
+ // "httpMethod": "GET",
+ // "id": "monorail.groups.settings.list",
+ // "parameters": {
+ // "importedGroupsOnly": {
+ // "location": "query",
+ // "type": "boolean"
+ // }
+ // },
+ // "path": "groupsettings",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1GroupsSettingsListResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.get":
+
+type IssuesGetCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Get: Get an issue.
+func (r *IssuesService) Get(projectId string, issueId int64) *IssuesGetCall {
+ c := &IssuesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesGetCall) Fields(s ...googleapi.Field) *IssuesGetCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *IssuesGetCall) IfNoneMatch(entityTag string) *IssuesGetCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesGetCall) Context(ctx context.Context) *IssuesGetCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesGetCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesGetCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.get" call.
+// Exactly one of *ProtoApiPb2V1IssuesGetInsertResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1IssuesGetInsertResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *IssuesGetCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesGetInsertResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesGetInsertResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Get an issue.",
+ // "httpMethod": "GET",
+ // "id": "monorail.issues.get",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId"
+ // ],
+ // "parameters": {
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesGetInsertResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.insert":
+
+type IssuesInsertCall struct {
+ s *Service
+ projectId string
+ protoapipb2v1issuewrapper *ProtoApiPb2V1IssueWrapper
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Insert: Add a new issue.
+func (r *IssuesService) Insert(projectId string, protoapipb2v1issuewrapper *ProtoApiPb2V1IssueWrapper) *IssuesInsertCall {
+ c := &IssuesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.protoapipb2v1issuewrapper = protoapipb2v1issuewrapper
+ return c
+}
+
+// SendEmail sets the optional parameter "sendEmail":
+func (c *IssuesInsertCall) SendEmail(sendEmail bool) *IssuesInsertCall {
+ c.urlParams_.Set("sendEmail", fmt.Sprint(sendEmail))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesInsertCall) Fields(s ...googleapi.Field) *IssuesInsertCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesInsertCall) Context(ctx context.Context) *IssuesInsertCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesInsertCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesInsertCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ body, err := googleapi.WithoutDataWrapper.JSONReader(c.protoapipb2v1issuewrapper)
+ if err != nil {
+ return nil, err
+ }
+ reqHeaders.Set("Content-Type", "application/json")
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.insert" call.
+// Exactly one of *ProtoApiPb2V1IssuesGetInsertResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1IssuesGetInsertResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *IssuesInsertCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesGetInsertResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesGetInsertResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Add a new issue.",
+ // "httpMethod": "POST",
+ // "id": "monorail.issues.insert",
+ // "parameterOrder": [
+ // "projectId"
+ // ],
+ // "parameters": {
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "sendEmail": {
+ // "default": "true",
+ // "location": "query",
+ // "type": "boolean"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues",
+ // "request": {
+ // "$ref": "ProtoApiPb2V1IssueWrapper",
+ // "parameterName": "resource"
+ // },
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesGetInsertResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.list":
+
+type IssuesListCall struct {
+ s *Service
+ projectId string
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// List: List issues for projects.
+func (r *IssuesService) List(projectId string) *IssuesListCall {
+ c := &IssuesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ return c
+}
+
+// AdditionalProject sets the optional parameter "additionalProject":
+func (c *IssuesListCall) AdditionalProject(additionalProject ...string) *IssuesListCall {
+ c.urlParams_.SetMulti("additionalProject", append([]string{}, additionalProject...))
+ return c
+}
+
+// Can sets the optional parameter "can":
+//
+// Possible values:
+// "all" (default)
+// "new"
+// "open"
+// "owned"
+// "reported"
+// "starred"
+// "to_verify"
+func (c *IssuesListCall) Can(can string) *IssuesListCall {
+ c.urlParams_.Set("can", can)
+ return c
+}
+
+// Label sets the optional parameter "label":
+func (c *IssuesListCall) Label(label string) *IssuesListCall {
+ c.urlParams_.Set("label", label)
+ return c
+}
+
+// MaxResults sets the optional parameter "maxResults":
+func (c *IssuesListCall) MaxResults(maxResults int64) *IssuesListCall {
+ c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
+ return c
+}
+
+// Owner sets the optional parameter "owner":
+func (c *IssuesListCall) Owner(owner string) *IssuesListCall {
+ c.urlParams_.Set("owner", owner)
+ return c
+}
+
+// PublishedMax sets the optional parameter "publishedMax":
+func (c *IssuesListCall) PublishedMax(publishedMax int64) *IssuesListCall {
+ c.urlParams_.Set("publishedMax", fmt.Sprint(publishedMax))
+ return c
+}
+
+// PublishedMin sets the optional parameter "publishedMin":
+func (c *IssuesListCall) PublishedMin(publishedMin int64) *IssuesListCall {
+ c.urlParams_.Set("publishedMin", fmt.Sprint(publishedMin))
+ return c
+}
+
+// Q sets the optional parameter "q":
+func (c *IssuesListCall) Q(q string) *IssuesListCall {
+ c.urlParams_.Set("q", q)
+ return c
+}
+
+// Sort sets the optional parameter "sort":
+func (c *IssuesListCall) Sort(sort string) *IssuesListCall {
+ c.urlParams_.Set("sort", sort)
+ return c
+}
+
+// StartIndex sets the optional parameter "startIndex":
+func (c *IssuesListCall) StartIndex(startIndex int64) *IssuesListCall {
+ c.urlParams_.Set("startIndex", fmt.Sprint(startIndex))
+ return c
+}
+
+// Status sets the optional parameter "status":
+func (c *IssuesListCall) Status(status string) *IssuesListCall {
+ c.urlParams_.Set("status", status)
+ return c
+}
+
+// UpdatedMax sets the optional parameter "updatedMax":
+func (c *IssuesListCall) UpdatedMax(updatedMax int64) *IssuesListCall {
+ c.urlParams_.Set("updatedMax", fmt.Sprint(updatedMax))
+ return c
+}
+
+// UpdatedMin sets the optional parameter "updatedMin":
+func (c *IssuesListCall) UpdatedMin(updatedMin int64) *IssuesListCall {
+ c.urlParams_.Set("updatedMin", fmt.Sprint(updatedMin))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesListCall) Fields(s ...googleapi.Field) *IssuesListCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *IssuesListCall) IfNoneMatch(entityTag string) *IssuesListCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesListCall) Context(ctx context.Context) *IssuesListCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesListCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesListCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.list" call.
+// Exactly one of *ProtoApiPb2V1IssuesListResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1IssuesListResponse.ServerResponse.Header or (if
+// a response was returned at all) in error.(*googleapi.Error).Header.
+// Use googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *IssuesListCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesListResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesListResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "List issues for projects.",
+ // "httpMethod": "GET",
+ // "id": "monorail.issues.list",
+ // "parameterOrder": [
+ // "projectId"
+ // ],
+ // "parameters": {
+ // "additionalProject": {
+ // "location": "query",
+ // "repeated": true,
+ // "type": "string"
+ // },
+ // "can": {
+ // "default": "all",
+ // "enum": [
+ // "all",
+ // "new",
+ // "open",
+ // "owned",
+ // "reported",
+ // "starred",
+ // "to_verify"
+ // ],
+ // "enumDescriptions": [
+ // "",
+ // "",
+ // "",
+ // "",
+ // "",
+ // "",
+ // ""
+ // ],
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "label": {
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "maxResults": {
+ // "default": "100",
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // },
+ // "owner": {
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "publishedMax": {
+ // "format": "int64",
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "publishedMin": {
+ // "format": "int64",
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "q": {
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "sort": {
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "startIndex": {
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // },
+ // "status": {
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "updatedMax": {
+ // "format": "int64",
+ // "location": "query",
+ // "type": "string"
+ // },
+ // "updatedMin": {
+ // "format": "int64",
+ // "location": "query",
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesListResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.comments.delete":
+
+type IssuesCommentsDeleteCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ commentId int64
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Delete: Delete a comment.
+func (r *IssuesCommentsService) Delete(projectId string, issueId int64, commentId int64) *IssuesCommentsDeleteCall {
+ c := &IssuesCommentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ c.commentId = commentId
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesCommentsDeleteCall) Fields(s ...googleapi.Field) *IssuesCommentsDeleteCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesCommentsDeleteCall) Context(ctx context.Context) *IssuesCommentsDeleteCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesCommentsDeleteCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesCommentsDeleteCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}/comments/{commentId}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("DELETE", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ "commentId": strconv.FormatInt(c.commentId, 10),
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.comments.delete" call.
+// Exactly one of *ProtoApiPb2V1IssuesCommentsDeleteResponse or error
+// will be non-nil. Any non-2xx status code is an error. Response
+// headers are in either
+// *ProtoApiPb2V1IssuesCommentsDeleteResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *IssuesCommentsDeleteCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesCommentsDeleteResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesCommentsDeleteResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Delete a comment.",
+ // "httpMethod": "DELETE",
+ // "id": "monorail.issues.comments.delete",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId",
+ // "commentId"
+ // ],
+ // "parameters": {
+ // "commentId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}/comments/{commentId}",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesCommentsDeleteResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.comments.insert":
+
+type IssuesCommentsInsertCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ protoapipb2v1issuecommentwrapper *ProtoApiPb2V1IssueCommentWrapper
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Insert: Add a comment.
+func (r *IssuesCommentsService) Insert(projectId string, issueId int64, protoapipb2v1issuecommentwrapper *ProtoApiPb2V1IssueCommentWrapper) *IssuesCommentsInsertCall {
+ c := &IssuesCommentsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ c.protoapipb2v1issuecommentwrapper = protoapipb2v1issuecommentwrapper
+ return c
+}
+
+// SendEmail sets the optional parameter "sendEmail":
+func (c *IssuesCommentsInsertCall) SendEmail(sendEmail bool) *IssuesCommentsInsertCall {
+ c.urlParams_.Set("sendEmail", fmt.Sprint(sendEmail))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesCommentsInsertCall) Fields(s ...googleapi.Field) *IssuesCommentsInsertCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesCommentsInsertCall) Context(ctx context.Context) *IssuesCommentsInsertCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesCommentsInsertCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesCommentsInsertCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ body, err := googleapi.WithoutDataWrapper.JSONReader(c.protoapipb2v1issuecommentwrapper)
+ if err != nil {
+ return nil, err
+ }
+ reqHeaders.Set("Content-Type", "application/json")
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}/comments")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.comments.insert" call.
+// Exactly one of *ProtoApiPb2V1IssuesCommentsInsertResponse or error
+// will be non-nil. Any non-2xx status code is an error. Response
+// headers are in either
+// *ProtoApiPb2V1IssuesCommentsInsertResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *IssuesCommentsInsertCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesCommentsInsertResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesCommentsInsertResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Add a comment.",
+ // "httpMethod": "POST",
+ // "id": "monorail.issues.comments.insert",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId"
+ // ],
+ // "parameters": {
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "sendEmail": {
+ // "location": "query",
+ // "type": "boolean"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}/comments",
+ // "request": {
+ // "$ref": "ProtoApiPb2V1IssueCommentWrapper",
+ // "parameterName": "resource"
+ // },
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesCommentsInsertResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.comments.list":
+
+type IssuesCommentsListCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// List: List all comments for an issue.
+func (r *IssuesCommentsService) List(projectId string, issueId int64) *IssuesCommentsListCall {
+ c := &IssuesCommentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ return c
+}
+
+// MaxResults sets the optional parameter "maxResults":
+func (c *IssuesCommentsListCall) MaxResults(maxResults int64) *IssuesCommentsListCall {
+ c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
+ return c
+}
+
+// StartIndex sets the optional parameter "startIndex":
+func (c *IssuesCommentsListCall) StartIndex(startIndex int64) *IssuesCommentsListCall {
+ c.urlParams_.Set("startIndex", fmt.Sprint(startIndex))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesCommentsListCall) Fields(s ...googleapi.Field) *IssuesCommentsListCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *IssuesCommentsListCall) IfNoneMatch(entityTag string) *IssuesCommentsListCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesCommentsListCall) Context(ctx context.Context) *IssuesCommentsListCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesCommentsListCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesCommentsListCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}/comments")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.comments.list" call.
+// Exactly one of *ProtoApiPb2V1IssuesCommentsListResponse or error will
+// be non-nil. Any non-2xx status code is an error. Response headers are
+// in either
+// *ProtoApiPb2V1IssuesCommentsListResponse.ServerResponse.Header or (if
+// a response was returned at all) in error.(*googleapi.Error).Header.
+// Use googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *IssuesCommentsListCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesCommentsListResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesCommentsListResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "List all comments for an issue.",
+ // "httpMethod": "GET",
+ // "id": "monorail.issues.comments.list",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId"
+ // ],
+ // "parameters": {
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "maxResults": {
+ // "default": "100",
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // },
+ // "startIndex": {
+ // "format": "int32",
+ // "location": "query",
+ // "type": "integer"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}/comments",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesCommentsListResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.issues.comments.undelete":
+
+type IssuesCommentsUndeleteCall struct {
+ s *Service
+ projectId string
+ issueId int64
+ commentId int64
+ urlParams_ gensupport.URLParams
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Undelete: Restore a deleted comment.
+func (r *IssuesCommentsService) Undelete(projectId string, issueId int64, commentId int64) *IssuesCommentsUndeleteCall {
+ c := &IssuesCommentsUndeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.projectId = projectId
+ c.issueId = issueId
+ c.commentId = commentId
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *IssuesCommentsUndeleteCall) Fields(s ...googleapi.Field) *IssuesCommentsUndeleteCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *IssuesCommentsUndeleteCall) Context(ctx context.Context) *IssuesCommentsUndeleteCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *IssuesCommentsUndeleteCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *IssuesCommentsUndeleteCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/issues/{issueId}/comments/{commentId}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("POST", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "projectId": c.projectId,
+ "issueId": strconv.FormatInt(c.issueId, 10),
+ "commentId": strconv.FormatInt(c.commentId, 10),
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.issues.comments.undelete" call.
+// Exactly one of *ProtoApiPb2V1IssuesCommentsDeleteResponse or error
+// will be non-nil. Any non-2xx status code is an error. Response
+// headers are in either
+// *ProtoApiPb2V1IssuesCommentsDeleteResponse.ServerResponse.Header or
+// (if a response was returned at all) in
+// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
+// whether the returned error was because http.StatusNotModified was
+// returned.
+func (c *IssuesCommentsUndeleteCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1IssuesCommentsDeleteResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1IssuesCommentsDeleteResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Restore a deleted comment.",
+ // "httpMethod": "POST",
+ // "id": "monorail.issues.comments.undelete",
+ // "parameterOrder": [
+ // "projectId",
+ // "issueId",
+ // "commentId"
+ // ],
+ // "parameters": {
+ // "commentId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "issueId": {
+ // "format": "int32",
+ // "location": "path",
+ // "required": true,
+ // "type": "integer"
+ // },
+ // "projectId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "projects/{projectId}/issues/{issueId}/comments/{commentId}",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1IssuesCommentsDeleteResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
+
+// method id "monorail.users.get":
+
+type UsersGetCall struct {
+ s *Service
+ userId string
+ urlParams_ gensupport.URLParams
+ ifNoneMatch_ string
+ ctx_ context.Context
+ header_ http.Header
+}
+
+// Get: Get a user.
+func (r *UsersService) Get(userId string) *UsersGetCall {
+ c := &UsersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
+ c.userId = userId
+ return c
+}
+
+// OwnerProjectsOnly sets the optional parameter "ownerProjectsOnly":
+func (c *UsersGetCall) OwnerProjectsOnly(ownerProjectsOnly bool) *UsersGetCall {
+ c.urlParams_.Set("ownerProjectsOnly", fmt.Sprint(ownerProjectsOnly))
+ return c
+}
+
+// Fields allows partial responses to be retrieved. See
+// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
+// for more information.
+func (c *UsersGetCall) Fields(s ...googleapi.Field) *UsersGetCall {
+ c.urlParams_.Set("fields", googleapi.CombineFields(s))
+ return c
+}
+
+// IfNoneMatch sets the optional parameter which makes the operation
+// fail if the object's ETag matches the given value. This is useful for
+// getting updates only after the object has changed since the last
+// request. Use googleapi.IsNotModified to check whether the response
+// error from Do is the result of In-None-Match.
+func (c *UsersGetCall) IfNoneMatch(entityTag string) *UsersGetCall {
+ c.ifNoneMatch_ = entityTag
+ return c
+}
+
+// Context sets the context to be used in this call's Do method. Any
+// pending HTTP request will be aborted if the provided context is
+// canceled.
+func (c *UsersGetCall) Context(ctx context.Context) *UsersGetCall {
+ c.ctx_ = ctx
+ return c
+}
+
+// Header returns an http.Header that can be modified by the caller to
+// add HTTP headers to the request.
+func (c *UsersGetCall) Header() http.Header {
+ if c.header_ == nil {
+ c.header_ = make(http.Header)
+ }
+ return c.header_
+}
+
+func (c *UsersGetCall) doRequest(alt string) (*http.Response, error) {
+ reqHeaders := make(http.Header)
+ reqHeaders.Set("x-goog-api-client", "gl-go/1.12.7 gdcl/20190905")
+ for k, v := range c.header_ {
+ reqHeaders[k] = v
+ }
+ reqHeaders.Set("User-Agent", c.s.userAgent())
+ if c.ifNoneMatch_ != "" {
+ reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
+ }
+ var body io.Reader = nil
+ c.urlParams_.Set("alt", alt)
+ c.urlParams_.Set("prettyPrint", "false")
+ urls := googleapi.ResolveRelative(c.s.BasePath, "users/{userId}")
+ urls += "?" + c.urlParams_.Encode()
+ req, err := http.NewRequest("GET", urls, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header = reqHeaders
+ googleapi.Expand(req.URL, map[string]string{
+ "userId": c.userId,
+ })
+ return gensupport.SendRequest(c.ctx_, c.s.client, req)
+}
+
+// Do executes the "monorail.users.get" call.
+// Exactly one of *ProtoApiPb2V1UsersGetResponse or error will be
+// non-nil. Any non-2xx status code is an error. Response headers are in
+// either *ProtoApiPb2V1UsersGetResponse.ServerResponse.Header or (if a
+// response was returned at all) in error.(*googleapi.Error).Header. Use
+// googleapi.IsNotModified to check whether the returned error was
+// because http.StatusNotModified was returned.
+func (c *UsersGetCall) Do(opts ...googleapi.CallOption) (*ProtoApiPb2V1UsersGetResponse, error) {
+ gensupport.SetOptions(c.urlParams_, opts...)
+ res, err := c.doRequest("json")
+ if res != nil && res.StatusCode == http.StatusNotModified {
+ if res.Body != nil {
+ res.Body.Close()
+ }
+ return nil, &googleapi.Error{
+ Code: res.StatusCode,
+ Header: res.Header,
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ defer googleapi.CloseBody(res)
+ if err := googleapi.CheckResponse(res); err != nil {
+ return nil, err
+ }
+ ret := &ProtoApiPb2V1UsersGetResponse{
+ ServerResponse: googleapi.ServerResponse{
+ Header: res.Header,
+ HTTPStatusCode: res.StatusCode,
+ },
+ }
+ target := &ret
+ if err := gensupport.DecodeResponse(target, res); err != nil {
+ return nil, err
+ }
+ return ret, nil
+ // {
+ // "description": "Get a user.",
+ // "httpMethod": "GET",
+ // "id": "monorail.users.get",
+ // "parameterOrder": [
+ // "userId"
+ // ],
+ // "parameters": {
+ // "ownerProjectsOnly": {
+ // "location": "query",
+ // "type": "boolean"
+ // },
+ // "userId": {
+ // "location": "path",
+ // "required": true,
+ // "type": "string"
+ // }
+ // },
+ // "path": "users/{userId}",
+ // "response": {
+ // "$ref": "ProtoApiPb2V1UsersGetResponse"
+ // },
+ // "scopes": [
+ // "https://www.googleapis.com/auth/userinfo.email"
+ // ]
+ // }
+
+}
diff --git a/go/monorail/v1/rebuild.sh b/go/monorail/v1/rebuild.sh
new file mode 100755
index 0000000..fd6de88
--- /dev/null
+++ b/go/monorail/v1/rebuild.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Script to rebuild the monorail.go file.
+
+# Get an updated generator. Pin to v0.10.0 because https://github.com/googleapis/google-api-go-client/issues/416.
+go get -u google.golang.org/api/google-api-go-generator@v0.10.0
+
+# Retrieve the discovery document for the API.
+wget https://monorail-prod.appspot.com/_ah/api/discovery/v1/apis/monorail/v1/rest
+
+# Generate the Go file.
+google-api-go-generator \
+ -api_json_file=rest \
+ -api_pkg_base="go.skia.org/infra/go" \
+ -output="monorail.go"
+
+# Clean up the generated file.
+goimports -w .
+
+# Cleanup.
+rm rest
diff --git a/hashtag/Dockerfile b/hashtag/Dockerfile
new file mode 100644
index 0000000..36ad6c1
--- /dev/null
+++ b/hashtag/Dockerfile
@@ -0,0 +1,7 @@
+FROM gcr.io/skia-public/basealpine:3.8
+
+COPY . /
+
+USER skia
+
+ENTRYPOINT ["/usr/local/bin/hashtag"]
\ No newline at end of file
diff --git a/hashtag/Makefile b/hashtag/Makefile
new file mode 100644
index 0000000..33ff736
--- /dev/null
+++ b/hashtag/Makefile
@@ -0,0 +1,27 @@
+default: build package-lock.json
+ npx webpack --mode=development
+
+build:
+ go install ./go/hashtag
+
+release: package-lock.json
+ npx webpack --mode=production
+ CGO_ENABLED=0 GOOS=linux go install -a ./go/hashtag
+ ./build_release
+
+push: release
+ pushk --cluster=skia-public hashtag
+
+watch: package-lock.json
+ npx webpack --mode=development --watch
+
+run: build
+ # To run locally download the whitelisted service account and point to it
+ # via the GOOGLE_APPLICATION_CREDENTIALS environment variable.
+ GOOGLE_APPLICATION_CREDENTIALS=${HOME}/.hashtag_creds hashtag --local --logtostderr
+
+test:
+ go test ./go/...
+
+package-lock.json: package.json
+ npm install
\ No newline at end of file
diff --git a/hashtag/README.md b/hashtag/README.md
new file mode 100644
index 0000000..0035aed
--- /dev/null
+++ b/hashtag/README.md
@@ -0,0 +1,10 @@
+# Project HashTag
+
+A system for gathering disparate data such as bugs, CLs, and Google Drive
+documents into a comprehensive view on project status.
+
+ * [Design Doc](http://go/skia-hashtag)
+
+## Configuration
+
+Configuration of the application is done via the `config.json` file.
\ No newline at end of file
diff --git a/hashtag/build_release b/hashtag/build_release
new file mode 100755
index 0000000..b9973d7
--- /dev/null
+++ b/hashtag/build_release
@@ -0,0 +1,17 @@
+#!/bin/bash
+APPNAME=hashtag
+
+set -x -e
+
+# Copy files into the right locations in ${ROOT}.
+copy_release_files()
+{
+INSTALL="install -D --verbose --backup=none"
+INSTALL_DIR="install -d --verbose --backup=none"
+${INSTALL} --mode=644 -T Dockerfile ${ROOT}/Dockerfile
+${INSTALL} --mode=755 -T ${GOPATH}/bin/${APPNAME} ${ROOT}/usr/local/bin/${APPNAME}
+${INSTALL_DIR} --mode=755 ${ROOT}/usr/local/share/${APPNAME}
+${INSTALL} --mode=644 ./dist/* ${ROOT}/usr/local/share/${APPNAME}
+}
+
+source ../bash/docker_build.sh
diff --git a/hashtag/config.json b/hashtag/config.json
new file mode 100644
index 0000000..792ba1b
--- /dev/null
+++ b/hashtag/config.json
@@ -0,0 +1,27 @@
+{
+ "sources": {
+ "codesearch": {
+ "prefix": "lang:^markdown$ AND (file:^skia/buildbot/ OR file:^src/third_party/skia/) AND package:^chromium$"
+ },
+ "gerrit": {
+ "url": "https://skia-review.googlesource.com",
+ "filters": [
+ "-owner:skia-autoroll@skia-public.iam.gserviceaccount.com",
+ "-owner:skia-lottie-ci-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com"
+ ]
+ },
+ "monorail": {
+ "projectID": "skia",
+ "linkFormat": "https://bugs.skia.org/%d",
+ "sort": "-Id"
+ }
+ },
+ "hashtags": [
+ "Particles", "Skottie", "SkSL", "Metal", "Vulkan", "SkQP", "Hashtag", "Forklift"
+ ],
+ "auth": {
+ "client_id": "145247227042-9dc658m0dj9mbah94kn5i3nnejirvrgl.apps.googleusercontent.com",
+ "api_key": "AIzaSyB8YZ_bFpEVOyICD-pUutJ3mxm6c1to8q0"
+ },
+ "drive_id": "0AOGploz136NUUk9PVA"
+}
\ No newline at end of file
diff --git a/hashtag/create-hashtag-sa.sh b/hashtag/create-hashtag-sa.sh
new file mode 100755
index 0000000..79fbecc
--- /dev/null
+++ b/hashtag/create-hashtag-sa.sh
@@ -0,0 +1,29 @@
+#/bin/bash
+# Creates the service account for hashtag.
+
+set -e -x
+
+source ../kube/config.sh
+source ../bash/ramdisk.sh
+
+# New service account we will create.
+SA_NAME=skia-hashtag
+
+cd /tmp/ramdisk
+gcloud iam service-accounts create "${SA_NAME}" --display-name="Skia Hashtag Service Account"
+
+gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
+ --member "serviceAccount:${SA_NAME}@${PROJECT_SUBDOMAIN}.iam.gserviceaccount.com" \
+ --role roles/datastore.user
+
+gcloud projects add-iam-policy-binding ${PROJECT_ID} \
+ --member serviceAccount:${SA_NAME}@${PROJECT_SUBDOMAIN}.iam.gserviceaccount.com \
+ --role roles/cloudtrace.agent
+
+gcloud beta iam service-accounts keys create ${SA_NAME}.json --iam-account="${SA_NAME}@${PROJECT_SUBDOMAIN}.iam.gserviceaccount.com"
+
+kubectl create secret generic "${SA_NAME}" --from-file=key.json=${SA_NAME}.json
+cd -
+
+# Should be added to Monorail whitelist:
+# https://bugs.chromium.org/p/monorail/issues/detail?id=6529
\ No newline at end of file
diff --git a/hashtag/go/codesearchsource/codesearchsource.go b/hashtag/go/codesearchsource/codesearchsource.go
new file mode 100644
index 0000000..85929b6
--- /dev/null
+++ b/hashtag/go/codesearchsource/codesearchsource.go
@@ -0,0 +1,58 @@
+package codesearchsource
+
+import (
+ "context"
+
+ "github.com/spf13/viper"
+ "go.skia.org/infra/go/codesearch"
+ "go.skia.org/infra/go/httputils"
+ "go.skia.org/infra/go/sklog"
+ "go.skia.org/infra/hashtag/go/source"
+)
+
+// codesearchSource implements source.Source.
+type codesearchSource struct {
+ cs *codesearch.CodeSearch
+
+ // prefix is added to each query.
+ prefix string
+}
+
+// New returns a new Source.
+func New() (source.Source, error) {
+ c := httputils.DefaultClientConfig().With2xxOnly().Client()
+ cs := codesearch.New(c)
+ return &codesearchSource{
+ cs: cs,
+ prefix: viper.GetString("sources.codesearch.prefix"),
+ }, nil
+}
+
+// See source.Source.
+func (cs *codesearchSource) ByHashtag(hashtag string) <-chan source.Artifact {
+ ret := make(chan source.Artifact)
+ go func() {
+ defer close(ret)
+ results, err := cs.cs.Query(context.Background(), cs.prefix+" "+hashtag, nil)
+ if err != nil {
+ sklog.Errorf("Failed to build code search: %s", err)
+ return
+ }
+ for _, r := range results.SearchResult {
+ ret <- source.Artifact{
+ Title: r.TopFile.File.Name,
+ URL: cs.cs.URL(r),
+ }
+ }
+ }()
+
+ return ret
+
+}
+
+// See source.Source.
+func (cs *codesearchSource) ByUser(hashtag string) <-chan source.Artifact {
+ ret := make(chan source.Artifact)
+ close(ret)
+ return ret
+}
diff --git a/hashtag/go/gerritsource/gerritsource.go b/hashtag/go/gerritsource/gerritsource.go
new file mode 100644
index 0000000..4cf0b40
--- /dev/null
+++ b/hashtag/go/gerritsource/gerritsource.go
@@ -0,0 +1,79 @@
+package gerritsource
+
+import (
+ "context"
+ "strings"
+
+ "github.com/spf13/viper"
+ "go.skia.org/infra/go/gerrit"
+ "go.skia.org/infra/go/httputils"
+ "go.skia.org/infra/go/skerr"
+ "go.skia.org/infra/go/sklog"
+ "go.skia.org/infra/hashtag/go/source"
+)
+
+// gerritSource implements source.Source.
+type gerritSource struct {
+ g *gerrit.Gerrit
+ terms []*gerrit.SearchTerm
+}
+
+// New returns a new Source.
+func New() (source.Source, error) {
+ c := httputils.DefaultClientConfig().With2xxOnly().Client()
+ g, err := gerrit.NewGerrit(viper.GetString("sources.gerrit.url"), "", c)
+ if err != nil {
+ return nil, skerr.Wrapf(err, "Failed to create gerrit instance")
+ }
+ terms := []*gerrit.SearchTerm{}
+ for _, filter := range viper.GetStringSlice("sources.gerrit.filters") {
+ parts := strings.SplitN(filter, ":", 2)
+ if len(parts) != 2 {
+ return nil, skerr.Fmt("All Gerrit filters must start with an operator, e.g. 'owner:'.")
+ }
+ terms = append(terms, &gerrit.SearchTerm{
+ Key: parts[0],
+ Value: parts[1],
+ })
+ }
+ return &gerritSource{
+ g: g,
+ terms: terms,
+ }, err
+}
+
+// See source.Source.
+func (g *gerritSource) ByHashtag(hashtag string) <-chan source.Artifact {
+ ret := make(chan source.Artifact)
+ go func() {
+ defer close(ret)
+ terms := []*gerrit.SearchTerm{
+ {
+ Key: "message",
+ Value: hashtag,
+ },
+ }
+ terms = append(terms, g.terms...)
+ changes, err := g.g.Search(context.Background(), gerrit.MAX_GERRIT_LIMIT, terms...)
+ if err != nil {
+ sklog.Errorf("Failed to build Gerrit search: %s", err)
+ return
+ }
+ for _, c := range changes {
+ ret <- source.Artifact{
+ Title: c.Subject,
+ URL: g.g.Url(c.Issue),
+ LastModified: c.Updated,
+ }
+ }
+ }()
+
+ return ret
+}
+
+// See source.Source.
+func (g *gerritSource) ByUser(string) <-chan source.Artifact {
+ ret := make(chan source.Artifact)
+ close(ret)
+ return ret
+}
diff --git a/hashtag/go/hashtag/main.go b/hashtag/go/hashtag/main.go
new file mode 100644
index 0000000..ddf5af6
--- /dev/null
+++ b/hashtag/go/hashtag/main.go
@@ -0,0 +1,189 @@
+package main
+
+import (
+ "net/http"
+ "path/filepath"
+ "strings"
+ "sync"
+ "text/template"
+
+ "github.com/gorilla/mux"
+ "github.com/spf13/viper"
+ "github.com/unrolled/secure"
+ "go.skia.org/infra/go/allowed"
+ "go.skia.org/infra/go/baseapp"
+ "go.skia.org/infra/go/login"
+ "go.skia.org/infra/go/sklog"
+ "go.skia.org/infra/hashtag/go/codesearchsource"
+ "go.skia.org/infra/hashtag/go/gerritsource"
+ "go.skia.org/infra/hashtag/go/monorailsource"
+ "go.skia.org/infra/hashtag/go/source"
+)
+
+// sourceDescriptor describes a single source.Source.
+type sourceDescriptor struct {
+ displayName string
+ source source.Source
+}
+
+// server implements baseapp.App.
+type server struct {
+ templates *template.Template
+ sources []sourceDescriptor
+}
+
+func newServer() (baseapp.App, error) {
+ // Setup auth.
+ var allow allowed.Allow
+ if !*baseapp.Local {
+ allow = allowed.NewAllowedFromList([]string{"google.com"})
+ } else {
+ allow = allowed.NewAllowedFromList([]string{"fred@example.org", "barney@example.org", "wilma@example.org"})
+ }
+ login.SimpleInitWithAllow(*baseapp.Port, *baseapp.Local, nil, nil, allow)
+
+ viper.SetConfigName("config") // name of config file (without extension)
+ viper.AddConfigPath(*baseapp.ResourcesDir)
+ err := viper.ReadInConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ // Create our Sources.
+ gs, err := gerritsource.New()
+ if err != nil {
+ return nil, err
+ }
+ ms, err := monorailsource.New()
+ if err != nil {
+ return nil, err
+ }
+ cs, err := codesearchsource.New()
+ if err != nil {
+ return nil, err
+ }
+
+ ret := &server{
+ sources: []sourceDescriptor{
+ {
+ displayName: "Documents",
+ source: cs,
+ },
+ {
+ displayName: "Bugs",
+ source: ms,
+ },
+ {
+ displayName: "CLs",
+ source: gs,
+ },
+ },
+ }
+ ret.loadTemplates()
+
+ return ret, nil
+}
+
+func (srv *server) loadTemplates() {
+ srv.templates = template.Must(template.New("").Delims("{%", "%}").ParseFiles(
+ filepath.Join(*baseapp.ResourcesDir, "index.html"),
+ ))
+}
+
+// result of a singe source search.
+type result struct {
+ DisplayName string
+ Artifacts []source.Artifact
+}
+
+// TemplateContext is the context for the index.html template.
+type TemplateContext struct {
+ // Nonce is the CSP Nonce. Look in webpack.config.js for where the nonce
+ // templates are injected.
+ Nonce string
+
+ // IsSearch is true if we contain search results.
+ IsSearch bool
+
+ // HashTag is the search query made if IsSearch is true.
+ Hashtag string
+
+ // Hashtags is the list of "official" hashtags.
+ Hashtags []string
+
+ // Results of the search.
+ Results []result
+
+ // The Google Team Drive ID.
+ DriveID string
+
+ // OAuth 2.0 client id.
+ ClientID string
+
+ // JS API Key.
+ APIKey string
+}
+
+func (srv *server) indexHandler(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "text/html")
+ if *baseapp.Local {
+ srv.loadTemplates()
+ }
+
+ templateContext := TemplateContext{
+ // Look in webpack.config.js for where the nonce templates are injected.
+ Nonce: secure.CSPNonce(r.Context()),
+ Hashtags: viper.GetStringSlice("hashtags"),
+ DriveID: viper.GetString("drive_id"),
+ ClientID: viper.GetString("auth.client_id"),
+ APIKey: viper.GetString("auth.api_key"),
+ }
+
+ hashtag := strings.TrimSpace(r.FormValue("hashtag"))
+ if hashtag != "" {
+ templateContext.Hashtag = hashtag
+ templateContext.IsSearch = true
+ templateContext.Results = make([]result, len(srv.sources))
+
+ // Do searches in parallel.
+ var wg sync.WaitGroup
+ for i, s := range srv.sources {
+ wg.Add(1)
+ go func(i int, s sourceDescriptor) {
+ defer wg.Done()
+ results := []source.Artifact{}
+ for artifact := range s.source.ByHashtag(hashtag) {
+ results = append(results, artifact)
+ }
+ templateContext.Results[i] = result{
+ DisplayName: s.displayName,
+ Artifacts: results,
+ }
+ }(i, s)
+ }
+ wg.Wait()
+ }
+
+ if err := srv.templates.ExecuteTemplate(w, "index.html", templateContext); err != nil {
+ sklog.Errorf("Failed to expand template: %s", err)
+ }
+}
+
+// See baseapp.App.
+func (srv *server) AddHandlers(r *mux.Router) {
+ r.HandleFunc("/", srv.indexHandler)
+ r.HandleFunc("/loginstatus/", login.StatusHandler).Methods("GET")
+}
+
+// See baseapp.App.
+func (srv *server) AddMiddleware() []mux.MiddlewareFunc {
+ ret := []mux.MiddlewareFunc{}
+ if !*baseapp.Local {
+ ret = append(ret, login.ForceAuthMiddleware(login.DEFAULT_REDIRECT_URL), login.RestrictViewer)
+ }
+ return ret
+}
+
+func main() {
+ baseapp.Serve(newServer, []string{"hashtag.skia.org"})
+}
diff --git a/hashtag/go/monorailsource/monorailsource.go b/hashtag/go/monorailsource/monorailsource.go
new file mode 100644
index 0000000..14166d2
--- /dev/null
+++ b/hashtag/go/monorailsource/monorailsource.go
@@ -0,0 +1,72 @@
+package monorailsource
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ "github.com/spf13/viper"
+ "go.skia.org/infra/go/monorail/v1"
+ "go.skia.org/infra/go/skerr"
+ "go.skia.org/infra/go/sklog"
+ "go.skia.org/infra/hashtag/go/source"
+)
+
+const monorailTimeFormat = "2006-01-02T15:04:05"
+
+// monorailSource implements source.Source.
+type monorailSource struct {
+ m *monorail.Service
+ projectID string
+ linkFormat string
+ sort string
+}
+
+// New returns a new Source.
+func New() (source.Source, error) {
+ m, err := monorail.NewService(context.Background())
+ if err != nil {
+ return nil, skerr.Wrapf(err, "Unable to create monorail service.")
+ }
+
+ return &monorailSource{
+ m: m,
+ projectID: viper.GetString("sources.monorail.projectID"),
+ linkFormat: viper.GetString("sources.monorail.linkFormat"),
+ sort: viper.GetString("sources.monorail.sort"),
+ }, nil
+}
+
+// See source.Source.
+func (m *monorailSource) ByHashtag(hashtag string) <-chan source.Artifact {
+ ret := make(chan source.Artifact)
+ go func() {
+ defer close(ret)
+ matchingIssues, err := m.m.Issues.List(m.projectID).Q(hashtag).Sort(m.sort).Do()
+ if err != nil {
+ sklog.Errorf("Failed to build Monorail search: %s", err)
+ return
+ }
+ for _, issue := range matchingIssues.Items {
+ ts, err := time.Parse(monorailTimeFormat, issue.StatusModified)
+ if err != nil {
+ sklog.Errorf("Can't parse %q at time: %s", issue.StatusModified, err)
+ ts = time.Now()
+ }
+ ret <- source.Artifact{
+ Title: issue.Title,
+ URL: fmt.Sprintf(m.linkFormat, issue.Id),
+ LastModified: ts,
+ }
+ }
+ }()
+
+ return ret
+}
+
+// See source.Source.
+func (m *monorailSource) ByUser(string) <-chan source.Artifact {
+ ret := make(chan source.Artifact)
+ close(ret)
+ return ret
+}
diff --git a/hashtag/go/source/source.go b/hashtag/go/source/source.go
new file mode 100644
index 0000000..8cbc84c
--- /dev/null
+++ b/hashtag/go/source/source.go
@@ -0,0 +1,23 @@
+package source
+
+import "time"
+
+// Artifact is a single item we found during a search.
+type Artifact struct {
+ Title string `json:"title"`
+ URL string `json:"url"`
+ Hashtags []string `json:"hashtags"`
+ LastModified time.Time `json:"last_modified"`
+}
+
+// Source is the interface each source of data must implement, i.e. Gerrit,
+// Monorail, Drive, etc.
+type Source interface {
+ // ByHashtag returns a channel that produces Artifacts that match the given
+ // hashtag.
+ ByHashtag(hashtag string) <-chan Artifact
+
+ // ByUSer returns a channel that produces Artifacts that match the given
+ // email.
+ ByUser(email string) <-chan Artifact
+}
diff --git a/hashtag/modules/team-drive-sk/index.js b/hashtag/modules/team-drive-sk/index.js
new file mode 100644
index 0000000..b19dfbd
--- /dev/null
+++ b/hashtag/modules/team-drive-sk/index.js
@@ -0,0 +1,2 @@
+import './team-drive-sk.js'
+import './team-drive-sk.scss'
\ No newline at end of file
diff --git a/hashtag/modules/team-drive-sk/team-drive-sk.js b/hashtag/modules/team-drive-sk/team-drive-sk.js
new file mode 100644
index 0000000..6b2bda0
--- /dev/null
+++ b/hashtag/modules/team-drive-sk/team-drive-sk.js
@@ -0,0 +1,134 @@
+/**
+ * @module modules/team-drive-sk
+ * @description <h2><code>team-drive-sk</code></h2>
+ *
+ * Lists all the files that match the query in the team drive.
+ *
+ * @attr query - The hashtag to search for.
+ *
+ * @attr client_id - The OAuth 2.0 Client ID.
+ *
+ * @attr api_key - The API Key.
+ *
+ * @attr drive_id - The Google Teams Drive ID.
+ *
+ */
+import { html, render } from 'lit-html'
+import { ElementSk } from '../../../infra-sk/modules/ElementSk'
+import { errorMessage } from 'elements-sk/errorMessage'
+import 'elements-sk/spinner-sk'
+import 'elements-sk/error-toast-sk'
+import 'elements-sk/styles/buttons'
+
+// Full list of mime-types: https://developers.google.com/drive/api/v3/mime-types
+const mimeTypesToPath = {
+ 'application/vnd.google-apps.presentation': 'presentation',
+ 'application/vnd.google-apps.spreadsheet': 'spreadsheets',
+ 'application/vnd.google-apps.document': 'document',
+ 'application/vnd.google-apps.drawing': 'drawings',
+};
+
+function linkFromFile(file) {
+ return `https://docs.google.com/${mimeTypesToPath[file.mimeType]}/d/${file.id}`
+}
+
+const template = (ele) => html`
+ ${ele._isSignedIn() ? html`` : html`<button @click=${() => ele._signIn()}>Authorize</button>`}
+ <spinner-sk ?active=${ele._loading}></spinner-sk>
+ <ul>
+ ${(!ele._loading && ele._files.length === 0) ? html`<p>None found.</p>` : html``}
+ ${ele._files.map((file) => html`<li><a href='${linkFromFile(file)}'>${file.name}</a></li>`)}
+ </ul>
+`;
+
+// Array of API discovery doc URLs for APIs used by the quickstart
+const DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"];
+
+// Authorization scopes required by the API; multiple scopes can be included,
+// separated by spaces.
+const SCOPES = 'https://www.googleapis.com/auth/drive.readonly';
+
+class TeamDriveSk extends ElementSk {
+ constructor() {
+ super(template);
+ this._files = [];
+ this._loading = true;
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._render();
+ gapi.load('client:auth2', () => this._initClient());
+ }
+
+ _initClient() {
+ gapi.client.init({
+ // Client ID and API key from the Developer Console
+ apiKey: this.getAttribute("api_key"),
+ clientId: this.getAttribute("client_id"),
+ discoveryDocs: DISCOVERY_DOCS,
+ scope: SCOPES
+ }).then(() => {
+ // Listen for sign-in state changes.
+ gapi.auth2.getAuthInstance().isSignedIn.listen(() => this._listFiles());
+
+ // Handle the initial sign-in state.
+ this._listFiles();
+ }).catch(errorMessage);
+ }
+
+ _signIn() {
+ gapi.auth2.getAuthInstance().signIn();
+ }
+
+ _isSignedIn() {
+ // Protect against being called before the gapi library is loaded.
+ // Default to true which will hide the login button and this avoids a
+ // flash of the button if the lib is slow to load but the user is logged
+ // in.
+ if (!gapi.auth2) {
+ return true;
+ }
+ return gapi.auth2.getAuthInstance().isSignedIn.get();
+ }
+
+ _listFiles() {
+ if (this._isSignedIn()) {
+ this._files = [];
+
+ // TODO(jcgregorio): iterate the pages of the response.
+ //'fields': "nextPageToken, files(id, name)"
+ gapi.client.drive.files.list({
+ 'pageSize': 30,
+ 'corpora': 'drive',
+ // The Google Team Drive ID.
+ 'driveId': this.getAttribute("drive_id"),
+ 'includeItemsFromAllDrives': true,
+ 'q': `fullText contains \"${this.getAttribute('query')}\"`,
+ 'supportsAllDrives': true,
+ }).then((response) => {
+ var files = response.result.files;
+ if (files && files.length > 0) {
+ this._files = files;
+ } else {
+ // None found.
+ }
+ this._loading = false;
+ this._render();
+ }).catch(errorMessage);
+ } else {
+ this._render();
+ }
+ }
+}
+
+// This element requires the Google JS API Client to be loaded, so don't
+// register the element until the library is loaded.
+if (window.gapi) {
+ window.customElements.define('team-drive-sk', TeamDriveSk);
+} else {
+ // Look in index.html for the code that generates the event.
+ document.addEventListener('gapi-loaded', () => {
+ window.customElements.define('team-drive-sk', TeamDriveSk);
+ });
+}
diff --git a/hashtag/modules/team-drive-sk/team-drive-sk.scss b/hashtag/modules/team-drive-sk/team-drive-sk.scss
new file mode 100644
index 0000000..37f744e
--- /dev/null
+++ b/hashtag/modules/team-drive-sk/team-drive-sk.scss
@@ -0,0 +1,5 @@
+spinner-sk {
+ width: 16px;
+ height: 16px;
+ margin: 1rem;
+}
\ No newline at end of file
diff --git a/hashtag/package.json b/hashtag/package.json
new file mode 100644
index 0000000..c5ae144
--- /dev/null
+++ b/hashtag/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "hashtag",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "SEE LICENSE IN LICENSE",
+ "devDependencies": {
+ "chai": "~4.2.0",
+ "copy-webpack-plugin": "~5.0.4",
+ "elements-sk": "^3.0.1",
+ "html-webpack-inject-attributes-plugin": "^1.0.1",
+ "html-webpack-plugin": "^3.2.0",
+ "karma": "~4.4.0",
+ "karma-chai": "~0.1.0",
+ "karma-chrome-launcher": "~3.1.0",
+ "karma-firefox-launcher": "~1.2.0",
+ "karma-mocha": "~1.3.0",
+ "karma-sinon": "~1.0.5",
+ "karma-webpack": "~4.0.2",
+ "lit-html": "^1.1.2",
+ "mocha": "~6.2.1",
+ "pulito": "~4.4.0",
+ "sinon": "~7.5.0",
+ "webpack": "~4.41.2",
+ "webpack-cli": "~3.3.9",
+ "webpack-dev-server": "~3.8.2"
+ }
+}
diff --git a/hashtag/pages/index.html b/hashtag/pages/index.html
new file mode 100644
index 0000000..4e7c67f
--- /dev/null
+++ b/hashtag/pages/index.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Hashtag</title>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <script type="text/javascript" charset="utf-8" nonce='{%.Nonce%}'>
+ // Create a callback function that sends an event when gapi is loaded.
+ function sendGapiEvent() {
+ document.dispatchEvent(new CustomEvent('gapi-loaded'));
+ }
+ </script>
+ <script src="https://apis.google.com/js/api.js?onload=sendGapiEvent" async defer nonce='{% .Nonce %}'></script>
+</head>
+
+<body>
+ {% if not .IsSearch %}
+
+ <header>Hashtag
+ <form action="" method="get" accept-charset="utf-8">
+ <input type="text" name="hashtag" value="" placeholder="search">
+ </form>
+ </header>
+ <main>
+ <section>
+ <h2>Hashtags</h2>
+ <ul>
+ {% range .Hashtags %}
+ <li><a href='?hashtag={%.%}'>{%.%}</a></li>
+ {% end %}
+ </ul>
+ </section>
+ </main>
+
+ {% else %}
+
+ <header><a href='/'>Home</a>
+ <form action="" method="get" accept-charset="utf-8">
+ <input type="text" name="hashtag" value="{% .Hashtag %}" placeholder="search">
+ </form>
+ </header>
+ <main>
+ <section>
+ <h2>Drive</h2>
+ <team-drive-sk
+ query="{% .Hashtag %}"
+ client_id="{% .ClientID %}"
+ api_key="{% .APIKey %}"
+ drive_id="{% .DriveID %}">
+ </team-drive-sk>
+ </section>
+
+ {% range .Results %}
+ <section>
+ <h2>{% .DisplayName %}</h2>
+ <ul>
+ {% range .Artifacts %}
+ <li><a href='{% .URL %}'>{% .Title %}</a></li>
+ {% else %}
+ <p>None found.</p>
+ {% end %}
+ </ul>
+ </section>
+ {% end %}
+
+ </main>
+
+ {% end %}
+
+ <error-toast-sk></error-toast-sk>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/hashtag/pages/index.js b/hashtag/pages/index.js
new file mode 100644
index 0000000..a0707ea
--- /dev/null
+++ b/hashtag/pages/index.js
@@ -0,0 +1,2 @@
+import './index.scss'
+import '../modules/team-drive-sk'
\ No newline at end of file
diff --git a/hashtag/pages/index.scss b/hashtag/pages/index.scss
new file mode 100644
index 0000000..f5bfab8
--- /dev/null
+++ b/hashtag/pages/index.scss
@@ -0,0 +1,61 @@
+
+@import '~elements-sk/colors.css';
+
+html {
+ --dark-gray: rgb(49, 49, 49);
+ --gray-text: rgb(204, 204, 204);
+ --border: rgb(120, 120, 120)
+}
+
+section {
+ margin: 1rem;
+}
+
+section li {
+ line-height: 1.4rem;
+ max-width: 30rem;
+ overflow-wrap: break-word;
+}
+
+section p {
+ font-style: italic;
+}
+
+section h2 {
+ color: var(--dark-white);
+}
+
+header,
+header a {
+ padding: 0.4rem;
+ color: var(--light-gray);
+ background: var(--gray);
+ font-size: 1.2rem;
+}
+
+header {
+ border-bottom: solid thin var(--border);
+}
+
+body {
+ background: var(--dark-gray);
+ color: var(--gray-text);
+ font-family: helvetica, 'helvetica neue', ubuntu, roboto, noto, 'segoe ui', arial, sans-serif;
+ margin: 0;
+ padding: 0;
+}
+
+a {
+ color: var(--gray-text);
+ text-decoration: underline;
+}
+
+form {
+ display: inline-block;
+}
+
+main {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+}
\ No newline at end of file
diff --git a/hashtag/webpack.config.js b/hashtag/webpack.config.js
new file mode 100644
index 0000000..394891c
--- /dev/null
+++ b/hashtag/webpack.config.js
@@ -0,0 +1,26 @@
+const commonBuilder = require('pulito');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const HtmlWebpackInjectAttributesPlugin = require('html-webpack-inject-attributes-plugin');
+const { resolve } = require('path')
+
+module.exports = (env, argv) => {
+ let config = commonBuilder(env, argv, __dirname);
+ config.output.publicPath='/static/';
+
+ config.plugins.push(
+ new CopyWebpackPlugin([
+ {
+ from: './config.json',
+ to: 'config.json'
+ },
+ ])
+ );
+ config.plugins.push(
+ new HtmlWebpackInjectAttributesPlugin({
+ nonce: "{% .Nonce %}",
+ }),
+ );
+ config.resolve = config.resolve || {};
+ config.resolve.modules = [resolve(__dirname, 'node_modules')];
+ return config;
+}
diff --git a/licenses/LICENSES.md b/licenses/LICENSES.md
index a8a3ab0..edb641a 100644
--- a/licenses/LICENSES.md
+++ b/licenses/LICENSES.md
@@ -21,6 +21,7 @@
| github.com/davecgh/go-spew/spew | ISC |
| github.com/fiorix/go-web/autogzip | BSD-3-Clause |
| github.com/flynn/json5 | BSD-3-Clause/MIT |
+| github.com/fsnotify/fsnotify | BSD-3-Clause |
| github.com/godbus/dbus | BSD-2-Clause |
| github.com/golang/ | Apache 2.0 |
| github.com/golang/mock | Apache 2.0 |
@@ -43,9 +44,12 @@
| github.com/Masterminds/goutils | Apache 2.0 |
| github.com/Masterminds/semver | MIT |
| github.com/Masterminds/sprig | MIT |
+| github.com/magiconair/properties | BSD-2-Clause |
| github.com/mattheath/base62 | MIT |
| github.com/matttproud/golang\_protobuf\_extensions | Apache 2.0 |
+| github.com/mitchellh/mapstructure | MIT |
| github.com/nfnt/resize | ISC |
+| github.com/pelletier/go-toml | MIT |
| github.com/pkg/errors | BSD-2-Clause |
| github.com/pmezard/go-difflib | BSD-3-Clause |
| github.com/prometheus/ | Apache 2.0 |
@@ -54,6 +58,11 @@
| github.com/skia-dev/go-systemd/dbus | Apache 2.0 |
| github.com/spf13/cobra | Apache 2.0 |
| github.com/spf13/pflag | BSD-3-Clause |
+| github.com/spf13/afero | Apache 2.0 |
+| github.com/spf13/afero/mem | Apache 2.0 |
+| github.com/spf13/cast | MIT |
+| github.com/spf13/jwalterweatherman | MIT |
+| github.com/spf13/viper | MIT |
| github.com/stretchr/testify | MIT |
| github.com/syndtr/goleveldb | BSD-2-Clause |
| github.com/texttheater/golang-levenshtein | MIT |
diff --git a/licenses/all_deps.txt b/licenses/all_deps.txt
index a1ae5bc..ab84490 100644
--- a/licenses/all_deps.txt
+++ b/licenses/all_deps.txt
@@ -43,6 +43,7 @@
github.com/davecgh/go-spew/spew
github.com/fiorix/go-web/autogzip
github.com/flynn/json5
+github.com/fsnotify/fsnotify
github.com/godbus/dbus
github.com/gogo/protobuf/proto
github.com/gogo/protobuf/sortkeys
@@ -77,10 +78,6 @@
github.com/gorilla/csrf
github.com/gorilla/mux
github.com/gorilla/securecookie
-github.com/hashicorp/errwrap
-github.com/hashicorp/golang-lru
-github.com/hashicorp/golang-lru/simplelru
-github.com/hashicorp/go-multierror
github.com/huandu/xstrings
github.com/huin/goserial
github.com/imdario/mergo
@@ -90,23 +87,31 @@
github.com/jmespath/go-jmespath
github.com/json-iterator/go
github.com/julienschmidt/httprouter
+github.com/magiconair/properties
github.com/Masterminds/goutils
github.com/Masterminds/semver
github.com/Masterminds/sprig
github.com/matttproud/golang_protobuf_extensions/pbutil
github.com/mitchellh/copystructure
+github.com/mitchellh/mapstructure
github.com/mitchellh/reflectwalk
github.com/modern-go/concurrent
github.com/modern-go/reflect2
github.com/nfnt/resize
github.com/patrickmn/go-cache
+github.com/pelletier/go-toml
github.com/pkg/errors
github.com/pmezard/go-difflib/difflib
github.com/russross/blackfriday/v2
github.com/shurcooL/sanitized_anchor_name
github.com/skia-dev/go-systemd/dbus
+github.com/spf13/afero
+github.com/spf13/afero/mem
+github.com/spf13/cast
github.com/spf13/cobra
+github.com/spf13/jwalterweatherman
github.com/spf13/pflag
+github.com/spf13/viper
github.com/stretchr/objx
github.com/stretchr/testify/assert
github.com/stretchr/testify/mock
diff --git a/licenses/check.sh b/licenses/check.sh
index 8c85f18..0b944b4 100755
--- a/licenses/check.sh
+++ b/licenses/check.sh
@@ -3,7 +3,7 @@
# Build the list of all recursive dependent packages, excluding the ones we
# know are going to licensed correctly.
DEPS=`go list -f '{{join .Deps "\n"}}' ../... | sort | uniq | grep "[a-zA-Z0-9]\+\." | \
- egrep -v \(cloud.google.com\|github.com/prometheus\|go.chromium.org\|go.chromium.org\|golang.org\|google.golang.org\|go.opencensus.io\|go.skia.org\|k8s.io\)`
+ egrep -v \(cloud.google.com\|github.com/prometheus\|go.chromium.org\|go.chromium.org\|golang.org\|google.golang.org\|go.opencensus.io\|go.skia.org\|k8s.io\|github.com/hashicorp\)`
if [ "$1" = "regenerate" ]; then
echo "$DEPS" > all_deps.txt