[Vendor] Update xanzy/go-gitlab v0.31.0 => v0.37.0 (#12701)

* update github.com/xanzy/go-gitlab v0.31.0 => v0.37.0

* vendor

* adapt changes

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
6543 2020-09-06 17:37:53 +02:00 committed by GitHub
parent 0ed5e103fe
commit 0c6a802731
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 2436 additions and 776 deletions

View file

@ -20,7 +20,6 @@ package gitlab
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -63,268 +62,6 @@ const (
privateToken
)
// AccessLevelValue represents a permission level within GitLab.
//
// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html
type AccessLevelValue int
// List of available access levels
//
// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html
const (
NoPermissions AccessLevelValue = 0
GuestPermissions AccessLevelValue = 10
ReporterPermissions AccessLevelValue = 20
DeveloperPermissions AccessLevelValue = 30
MaintainerPermissions AccessLevelValue = 40
OwnerPermissions AccessLevelValue = 50
// These are deprecated and should be removed in a future version
MasterPermissions AccessLevelValue = 40
OwnerPermission AccessLevelValue = 50
)
// BuildStateValue represents a GitLab build state.
type BuildStateValue string
// These constants represent all valid build states.
const (
Pending BuildStateValue = "pending"
Created BuildStateValue = "created"
Running BuildStateValue = "running"
Success BuildStateValue = "success"
Failed BuildStateValue = "failed"
Canceled BuildStateValue = "canceled"
Skipped BuildStateValue = "skipped"
Manual BuildStateValue = "manual"
)
// DeploymentStatusValue represents a Gitlab deployment status.
type DeploymentStatusValue string
// These constants represent all valid deployment statuses.
const (
DeploymentStatusCreated DeploymentStatusValue = "created"
DeploymentStatusRunning DeploymentStatusValue = "running"
DeploymentStatusSuccess DeploymentStatusValue = "success"
DeploymentStatusFailed DeploymentStatusValue = "failed"
DeploymentStatusCanceled DeploymentStatusValue = "canceled"
)
// ISOTime represents an ISO 8601 formatted date
type ISOTime time.Time
// ISO 8601 date format
const iso8601 = "2006-01-02"
// MarshalJSON implements the json.Marshaler interface
func (t ISOTime) MarshalJSON() ([]byte, error) {
if y := time.Time(t).Year(); y < 0 || y >= 10000 {
// ISO 8901 uses 4 digits for the years
return nil, errors.New("json: ISOTime year outside of range [0,9999]")
}
b := make([]byte, 0, len(iso8601)+2)
b = append(b, '"')
b = time.Time(t).AppendFormat(b, iso8601)
b = append(b, '"')
return b, nil
}
// UnmarshalJSON implements the json.Unmarshaler interface
func (t *ISOTime) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package
if string(data) == "null" {
return nil
}
isotime, err := time.Parse(`"`+iso8601+`"`, string(data))
*t = ISOTime(isotime)
return err
}
// EncodeValues implements the query.Encoder interface
func (t *ISOTime) EncodeValues(key string, v *url.Values) error {
if t == nil || (time.Time(*t)).IsZero() {
return nil
}
v.Add(key, t.String())
return nil
}
// String implements the Stringer interface
func (t ISOTime) String() string {
return time.Time(t).Format(iso8601)
}
// NotificationLevelValue represents a notification level.
type NotificationLevelValue int
// String implements the fmt.Stringer interface.
func (l NotificationLevelValue) String() string {
return notificationLevelNames[l]
}
// MarshalJSON implements the json.Marshaler interface.
func (l NotificationLevelValue) MarshalJSON() ([]byte, error) {
return json.Marshal(l.String())
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (l *NotificationLevelValue) UnmarshalJSON(data []byte) error {
var raw interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
switch raw := raw.(type) {
case float64:
*l = NotificationLevelValue(raw)
case string:
*l = notificationLevelTypes[raw]
case nil:
// No action needed.
default:
return fmt.Errorf("json: cannot unmarshal %T into Go value of type %T", raw, *l)
}
return nil
}
// List of valid notification levels.
const (
DisabledNotificationLevel NotificationLevelValue = iota
ParticipatingNotificationLevel
WatchNotificationLevel
GlobalNotificationLevel
MentionNotificationLevel
CustomNotificationLevel
)
var notificationLevelNames = [...]string{
"disabled",
"participating",
"watch",
"global",
"mention",
"custom",
}
var notificationLevelTypes = map[string]NotificationLevelValue{
"disabled": DisabledNotificationLevel,
"participating": ParticipatingNotificationLevel,
"watch": WatchNotificationLevel,
"global": GlobalNotificationLevel,
"mention": MentionNotificationLevel,
"custom": CustomNotificationLevel,
}
// VisibilityValue represents a visibility level within GitLab.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
type VisibilityValue string
// List of available visibility levels.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
const (
PrivateVisibility VisibilityValue = "private"
InternalVisibility VisibilityValue = "internal"
PublicVisibility VisibilityValue = "public"
)
// ProjectCreationLevelValue represents a project creation level within GitLab.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
type ProjectCreationLevelValue string
// List of available project creation levels.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
const (
NoOneProjectCreation ProjectCreationLevelValue = "noone"
MaintainerProjectCreation ProjectCreationLevelValue = "maintainer"
DeveloperProjectCreation ProjectCreationLevelValue = "developer"
)
// SubGroupCreationLevelValue represents a sub group creation level within GitLab.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
type SubGroupCreationLevelValue string
// List of available sub group creation levels.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
const (
OwnerSubGroupCreationLevelValue SubGroupCreationLevelValue = "owner"
MaintainerSubGroupCreationLevelValue SubGroupCreationLevelValue = "maintainer"
)
// VariableTypeValue represents a variable type within GitLab.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
type VariableTypeValue string
// List of available variable types.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/
const (
EnvVariableType VariableTypeValue = "env_var"
FileVariableType VariableTypeValue = "file"
)
// MergeMethodValue represents a project merge type within GitLab.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#project-merge-method
type MergeMethodValue string
// List of available merge type
//
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#project-merge-method
const (
NoFastForwardMerge MergeMethodValue = "merge"
FastForwardMerge MergeMethodValue = "ff"
RebaseMerge MergeMethodValue = "rebase_merge"
)
// EventTypeValue represents actions type for contribution events
type EventTypeValue string
// List of available action type
//
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#action-types
const (
CreatedEventType EventTypeValue = "created"
UpdatedEventType EventTypeValue = "updated"
ClosedEventType EventTypeValue = "closed"
ReopenedEventType EventTypeValue = "reopened"
PushedEventType EventTypeValue = "pushed"
CommentedEventType EventTypeValue = "commented"
MergedEventType EventTypeValue = "merged"
JoinedEventType EventTypeValue = "joined"
LeftEventType EventTypeValue = "left"
DestroyedEventType EventTypeValue = "destroyed"
ExpiredEventType EventTypeValue = "expired"
)
// EventTargetTypeValue represents actions type value for contribution events
type EventTargetTypeValue string
// List of available action type
//
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#target-types
const (
IssueEventTargetType EventTargetTypeValue = "issue"
MilestoneEventTargetType EventTargetTypeValue = "milestone"
MergeRequestEventTargetType EventTargetTypeValue = "merge_request"
NoteEventTargetType EventTargetTypeValue = "note"
ProjectEventTargetType EventTargetTypeValue = "project"
SnippetEventTargetType EventTargetTypeValue = "snippet"
UserEventTargetType EventTargetTypeValue = "user"
)
// A Client manages communication with the GitLab API.
type Client struct {
// HTTP client used to communicate with the API.
@ -338,12 +75,12 @@ type Client struct {
// disableRetries is used to disable the default retry logic.
disableRetries bool
// configLimiter is used to make sure the limiter is configured exactly
// configureLimiterOnce is used to make sure the limiter is configured exactly
// once and block all other calls until the initial (one) call is done.
configureLimiterOnce sync.Once
// Limiter is used to limit API calls and prevent 429 responses.
limiter *rate.Limiter
limiter RateLimiter
// Token type used to make authenticated API calls.
authType authType
@ -354,6 +91,9 @@ type Client struct {
// Token used to make authenticated API calls.
token string
// Protects the token field from concurrent read/write accesses.
tokenLock sync.RWMutex
// User agent used when communicating with the GitLab API.
UserAgent string
@ -373,6 +113,7 @@ type Client struct {
Deployments *DeploymentsService
Discussions *DiscussionsService
Environments *EnvironmentsService
EpicIssues *EpicIssuesService
Epics *EpicsService
Events *EventsService
Features *FeaturesService
@ -385,8 +126,11 @@ type Client struct {
GroupMilestones *GroupMilestonesService
GroupVariables *GroupVariablesService
Groups *GroupsService
InstanceCluster *InstanceClustersService
InstanceVariables *InstanceVariablesService
IssueLinks *IssueLinksService
Issues *IssuesService
IssuesStatistics *IssuesStatisticsService
Jobs *JobsService
Keys *KeysService
Labels *LabelsService
@ -406,6 +150,7 @@ type Client struct {
ProjectCluster *ProjectClustersService
ProjectImportExport *ProjectImportExportService
ProjectMembers *ProjectMembersService
ProjectMirrors *ProjectMirrorService
ProjectSnippets *ProjectSnippetsService
ProjectVariables *ProjectVariablesService
Projects *ProjectsService
@ -441,6 +186,11 @@ type ListOptions struct {
PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"`
}
// RateLimiter describes the interface that all (custom) rate limiters must implement.
type RateLimiter interface {
Wait(context.Context) error
}
// NewClient returns a new GitLab API client. To use API methods which require
// authentication, provide a valid private or personal token.
func NewClient(token string, options ...ClientOptionFunc) (*Client, error) {
@ -465,11 +215,6 @@ func NewBasicAuthClient(username, password string, options ...ClientOptionFunc)
client.username = username
client.password = password
err = client.requestOAuthToken(context.Background())
if err != nil {
return nil, err
}
return client, nil
}
@ -485,22 +230,6 @@ func NewOAuthClient(token string, options ...ClientOptionFunc) (*Client, error)
return client, nil
}
func (c *Client) requestOAuthToken(ctx context.Context) error {
config := &oauth2.Config{
Endpoint: oauth2.Endpoint{
AuthURL: fmt.Sprintf("%s://%s/oauth/authorize", c.BaseURL().Scheme, c.BaseURL().Host),
TokenURL: fmt.Sprintf("%s://%s/oauth/token", c.BaseURL().Scheme, c.BaseURL().Host),
},
}
ctx = context.WithValue(ctx, oauth2.HTTPClient, c.client)
t, err := config.PasswordCredentialsToken(ctx, c.username, c.password)
if err != nil {
return err
}
c.token = t.AccessToken
return nil
}
func newClient(options ...ClientOptionFunc) (*Client, error) {
c := &Client{UserAgent: userAgent}
@ -547,6 +276,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
c.Deployments = &DeploymentsService{client: c}
c.Discussions = &DiscussionsService{client: c}
c.Environments = &EnvironmentsService{client: c}
c.EpicIssues = &EpicIssuesService{client: c}
c.Epics = &EpicsService{client: c}
c.Events = &EventsService{client: c}
c.Features = &FeaturesService{client: c}
@ -559,8 +289,10 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
c.GroupMilestones = &GroupMilestonesService{client: c}
c.GroupVariables = &GroupVariablesService{client: c}
c.Groups = &GroupsService{client: c}
c.InstanceCluster = &InstanceClustersService{client: c}
c.IssueLinks = &IssueLinksService{client: c}
c.Issues = &IssuesService{client: c, timeStats: timeStats}
c.IssuesStatistics = &IssuesStatisticsService{client: c}
c.Jobs = &JobsService{client: c}
c.Keys = &KeysService{client: c}
c.Labels = &LabelsService{client: c}
@ -580,6 +312,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
c.ProjectCluster = &ProjectClustersService{client: c}
c.ProjectImportExport = &ProjectImportExportService{client: c}
c.ProjectMembers = &ProjectMembersService{client: c}
c.ProjectMirrors = &ProjectMirrorService{client: c}
c.ProjectSnippets = &ProjectSnippetsService{client: c}
c.ProjectVariables = &ProjectVariablesService{client: c}
c.Projects = &ProjectsService{client: c}
@ -755,13 +488,6 @@ func (c *Client) NewRequest(method, path string, opt interface{}, options []Requ
reqHeaders := make(http.Header)
reqHeaders.Set("Accept", "application/json")
switch c.authType {
case basicAuth, oAuthToken:
reqHeaders.Set("Authorization", "Bearer "+c.token)
case privateToken:
reqHeaders.Set("PRIVATE-TOKEN", c.token)
}
if c.UserAgent != "" {
reqHeaders.Set("User-Agent", c.UserAgent)
}
@ -875,23 +601,47 @@ func (c *Client) Do(req *retryablehttp.Request, v interface{}) (*Response, error
c.configureLimiterOnce.Do(func() { c.configureLimiter() })
// Wait will block until the limiter can obtain a new token.
if err := c.limiter.Wait(req.Context()); err != nil {
err := c.limiter.Wait(req.Context())
if err != nil {
return nil, err
}
// Set the correct authentication header. If using basic auth, then check
// if we already have a token and if not first authenticate and get one.
var basicAuthToken string
switch c.authType {
case basicAuth:
c.tokenLock.RLock()
basicAuthToken = c.token
c.tokenLock.RUnlock()
if basicAuthToken == "" {
// If we don't have a token yet, we first need to request one.
basicAuthToken, err = c.requestOAuthToken(req.Context(), basicAuthToken)
if err != nil {
return nil, err
}
}
req.Header.Set("Authorization", "Bearer "+basicAuthToken)
case oAuthToken:
req.Header.Set("Authorization", "Bearer "+c.token)
case privateToken:
req.Header.Set("PRIVATE-TOKEN", c.token)
}
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusUnauthorized && c.authType == basicAuth {
err = c.requestOAuthToken(req.Context())
if err != nil {
resp.Body.Close()
// The token most likely expired, so we need to request a new one and try again.
if _, err := c.requestOAuthToken(req.Context(), basicAuthToken); err != nil {
return nil, err
}
return c.Do(req, v)
}
defer resp.Body.Close()
response := newResponse(resp)
@ -913,6 +663,32 @@ func (c *Client) Do(req *retryablehttp.Request, v interface{}) (*Response, error
return response, err
}
func (c *Client) requestOAuthToken(ctx context.Context, token string) (string, error) {
c.tokenLock.Lock()
defer c.tokenLock.Unlock()
// Return early if the token was updated while waiting for the lock.
if c.token != token {
return c.token, nil
}
config := &oauth2.Config{
Endpoint: oauth2.Endpoint{
AuthURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/authorize",
TokenURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/token",
},
}
ctx = context.WithValue(ctx, oauth2.HTTPClient, c.client.HTTPClient)
t, err := config.PasswordCredentialsToken(ctx, c.username, c.password)
if err != nil {
return "", err
}
c.token = t.AccessToken
return c.token, nil
}
// Helper function to accept and format both the project ID or name as project
// identifier for all API calls.
func parseID(id interface{}) (string, error) {
@ -1012,129 +788,3 @@ func parseError(raw interface{}) string {
return fmt.Sprintf("failed to parse unexpected error type: %T", raw)
}
}
// Bool is a helper routine that allocates a new bool value
// to store v and returns a pointer to it.
func Bool(v bool) *bool {
p := new(bool)
*p = v
return p
}
// Int is a helper routine that allocates a new int32 value
// to store v and returns a pointer to it, but unlike Int32
// its argument value is an int.
func Int(v int) *int {
p := new(int)
*p = v
return p
}
// String is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func String(v string) *string {
p := new(string)
*p = v
return p
}
// Time is a helper routine that allocates a new time.Time value
// to store v and returns a pointer to it.
func Time(v time.Time) *time.Time {
p := new(time.Time)
*p = v
return p
}
// AccessLevel is a helper routine that allocates a new AccessLevelValue
// to store v and returns a pointer to it.
func AccessLevel(v AccessLevelValue) *AccessLevelValue {
p := new(AccessLevelValue)
*p = v
return p
}
// BuildState is a helper routine that allocates a new BuildStateValue
// to store v and returns a pointer to it.
func BuildState(v BuildStateValue) *BuildStateValue {
p := new(BuildStateValue)
*p = v
return p
}
// DeploymentStatus is a helper routine that allocates a new
// DeploymentStatusValue to store v and returns a pointer to it.
func DeploymentStatus(v DeploymentStatusValue) *DeploymentStatusValue {
p := new(DeploymentStatusValue)
*p = v
return p
}
// NotificationLevel is a helper routine that allocates a new NotificationLevelValue
// to store v and returns a pointer to it.
func NotificationLevel(v NotificationLevelValue) *NotificationLevelValue {
p := new(NotificationLevelValue)
*p = v
return p
}
// VariableType is a helper routine that allocates a new VariableTypeValue
// to store v and returns a pointer to it.
func VariableType(v VariableTypeValue) *VariableTypeValue {
p := new(VariableTypeValue)
*p = v
return p
}
// Visibility is a helper routine that allocates a new VisibilityValue
// to store v and returns a pointer to it.
func Visibility(v VisibilityValue) *VisibilityValue {
p := new(VisibilityValue)
*p = v
return p
}
// ProjectCreationLevel is a helper routine that allocates a new ProjectCreationLevelValue
// to store v and returns a pointer to it.
func ProjectCreationLevel(v ProjectCreationLevelValue) *ProjectCreationLevelValue {
p := new(ProjectCreationLevelValue)
*p = v
return p
}
// SubGroupCreationLevel is a helper routine that allocates a new SubGroupCreationLevelValue
// to store v and returns a pointer to it.
func SubGroupCreationLevel(v SubGroupCreationLevelValue) *SubGroupCreationLevelValue {
p := new(SubGroupCreationLevelValue)
*p = v
return p
}
// MergeMethod is a helper routine that allocates a new MergeMethod
// to sotre v and returns a pointer to it.
func MergeMethod(v MergeMethodValue) *MergeMethodValue {
p := new(MergeMethodValue)
*p = v
return p
}
// BoolValue is a boolean value with advanced json unmarshaling features.
type BoolValue bool
// UnmarshalJSON allows 1 and 0 to be considered as boolean values
// Needed for https://gitlab.com/gitlab-org/gitlab-ce/issues/50122
func (t *BoolValue) UnmarshalJSON(b []byte) error {
switch string(b) {
case `"1"`:
*t = true
return nil
case `"0"`:
*t = false
return nil
default:
var v bool
err := json.Unmarshal(b, &v)
*t = BoolValue(v)
return err
}
}