mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 11:07:18 -04:00 
			
		
		
		
	Vendor Update: go-gitlab v0.22.1 -> v0.31.0 (#11136)
* vendor update: go-gitlab to v0.31.0 * migrate client init to v0.31.0 * refactor
This commit is contained in:
		
							
								
								
									
										397
									
								
								vendor/github.com/xanzy/go-gitlab/gitlab.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										397
									
								
								vendor/github.com/xanzy/go-gitlab/gitlab.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,28 +18,35 @@ | ||||
| package gitlab | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"math/rand" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/google/go-querystring/query" | ||||
| 	"github.com/hashicorp/go-cleanhttp" | ||||
| 	retryablehttp "github.com/hashicorp/go-retryablehttp" | ||||
| 	"golang.org/x/oauth2" | ||||
| 	"golang.org/x/time/rate" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	defaultBaseURL = "https://gitlab.com/" | ||||
| 	apiVersionPath = "api/v4/" | ||||
| 	userAgent      = "go-gitlab" | ||||
|  | ||||
| 	headerRateLimit = "RateLimit-Limit" | ||||
| 	headerRateReset = "RateLimit-Reset" | ||||
| ) | ||||
|  | ||||
| // authType represents an authentication type within GitLab. | ||||
| @@ -83,6 +90,7 @@ 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" | ||||
| @@ -91,6 +99,18 @@ const ( | ||||
| 	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 | ||||
|  | ||||
| @@ -215,6 +235,33 @@ const ( | ||||
| 	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/ | ||||
| @@ -281,13 +328,23 @@ const ( | ||||
| // A Client manages communication with the GitLab API. | ||||
| type Client struct { | ||||
| 	// HTTP client used to communicate with the API. | ||||
| 	client *http.Client | ||||
| 	client *retryablehttp.Client | ||||
|  | ||||
| 	// Base URL for API requests. Defaults to the public GitLab API, but can be | ||||
| 	// set to a domain endpoint to use with a self hosted GitLab server. baseURL | ||||
| 	// should always be specified with a trailing slash. | ||||
| 	baseURL *url.URL | ||||
|  | ||||
| 	// disableRetries is used to disable the default retry logic. | ||||
| 	disableRetries bool | ||||
|  | ||||
| 	// configLimiter 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 | ||||
|  | ||||
| 	// Token type used to make authenticated API calls. | ||||
| 	authType authType | ||||
|  | ||||
| @@ -302,6 +359,7 @@ type Client struct { | ||||
|  | ||||
| 	// Services used for talking to different parts of the GitLab API. | ||||
| 	AccessRequests        *AccessRequestsService | ||||
| 	Applications          *ApplicationsService | ||||
| 	AwardEmoji            *AwardEmojiService | ||||
| 	Boards                *IssueBoardsService | ||||
| 	Branches              *BranchesService | ||||
| @@ -311,6 +369,7 @@ type Client struct { | ||||
| 	ContainerRegistry     *ContainerRegistryService | ||||
| 	CustomAttribute       *CustomAttributesService | ||||
| 	DeployKeys            *DeployKeysService | ||||
| 	DeployTokens          *DeployTokensService | ||||
| 	Deployments           *DeploymentsService | ||||
| 	Discussions           *DiscussionsService | ||||
| 	Environments          *EnvironmentsService | ||||
| @@ -382,31 +441,47 @@ type ListOptions struct { | ||||
| 	PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"` | ||||
| } | ||||
|  | ||||
| // NewClient returns a new GitLab API client. If a nil httpClient is | ||||
| // provided, http.DefaultClient will be used. To use API methods which require | ||||
| // NewClient returns a new GitLab API client. To use API methods which require | ||||
| // authentication, provide a valid private or personal token. | ||||
| func NewClient(httpClient *http.Client, token string) *Client { | ||||
| 	client := newClient(httpClient) | ||||
| func NewClient(token string, options ...ClientOptionFunc) (*Client, error) { | ||||
| 	client, err := newClient(options...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	client.authType = privateToken | ||||
| 	client.token = token | ||||
| 	return client | ||||
| 	return client, nil | ||||
| } | ||||
|  | ||||
| // NewBasicAuthClient returns a new GitLab API client. If a nil httpClient is | ||||
| // provided, http.DefaultClient will be used. To use API methods which require | ||||
| // authentication, provide a valid username and password. | ||||
| func NewBasicAuthClient(httpClient *http.Client, endpoint, username, password string) (*Client, error) { | ||||
| 	client := newClient(httpClient) | ||||
| 	client.authType = basicAuth | ||||
| 	client.username = username | ||||
| 	client.password = password | ||||
| 	client.SetBaseURL(endpoint) | ||||
|  | ||||
| 	err := client.requestOAuthToken(context.TODO()) | ||||
| // NewBasicAuthClient returns a new GitLab API client. To use API methods which | ||||
| // require authentication, provide a valid username and password. | ||||
| func NewBasicAuthClient(username, password string, options ...ClientOptionFunc) (*Client, error) { | ||||
| 	client, err := newClient(options...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	client.authType = basicAuth | ||||
| 	client.username = username | ||||
| 	client.password = password | ||||
|  | ||||
| 	err = client.requestOAuthToken(context.Background()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return client, nil | ||||
| } | ||||
|  | ||||
| // NewOAuthClient returns a new GitLab API client. To use API methods which | ||||
| // require authentication, provide a valid oauth token. | ||||
| func NewOAuthClient(token string, options ...ClientOptionFunc) (*Client, error) { | ||||
| 	client, err := newClient(options...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	client.authType = oAuthToken | ||||
| 	client.token = token | ||||
| 	return client, nil | ||||
| } | ||||
|  | ||||
| @@ -426,25 +501,31 @@ func (c *Client) requestOAuthToken(ctx context.Context) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // NewOAuthClient returns a new GitLab API client. If a nil httpClient is | ||||
| // provided, http.DefaultClient will be used. To use API methods which require | ||||
| // authentication, provide a valid oauth token. | ||||
| func NewOAuthClient(httpClient *http.Client, token string) *Client { | ||||
| 	client := newClient(httpClient) | ||||
| 	client.authType = oAuthToken | ||||
| 	client.token = token | ||||
| 	return client | ||||
| } | ||||
| func newClient(options ...ClientOptionFunc) (*Client, error) { | ||||
| 	c := &Client{UserAgent: userAgent} | ||||
|  | ||||
| func newClient(httpClient *http.Client) *Client { | ||||
| 	if httpClient == nil { | ||||
| 		httpClient = http.DefaultClient | ||||
| 	// Configure the HTTP client. | ||||
| 	c.client = &retryablehttp.Client{ | ||||
| 		Backoff:      c.retryHTTPBackoff, | ||||
| 		CheckRetry:   c.retryHTTPCheck, | ||||
| 		ErrorHandler: retryablehttp.PassthroughErrorHandler, | ||||
| 		HTTPClient:   cleanhttp.DefaultPooledClient(), | ||||
| 		RetryWaitMin: 100 * time.Millisecond, | ||||
| 		RetryWaitMax: 400 * time.Millisecond, | ||||
| 		RetryMax:     5, | ||||
| 	} | ||||
|  | ||||
| 	c := &Client{client: httpClient, UserAgent: userAgent} | ||||
| 	if err := c.SetBaseURL(defaultBaseURL); err != nil { | ||||
| 		// Should never happen since defaultBaseURL is our constant. | ||||
| 		panic(err) | ||||
| 	// Set the default base URL. | ||||
| 	c.setBaseURL(defaultBaseURL) | ||||
|  | ||||
| 	// Apply any given client options. | ||||
| 	for _, fn := range options { | ||||
| 		if fn == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		if err := fn(c); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Create the internal timeStats service. | ||||
| @@ -452,6 +533,7 @@ func newClient(httpClient *http.Client) *Client { | ||||
|  | ||||
| 	// Create all the public services. | ||||
| 	c.AccessRequests = &AccessRequestsService{client: c} | ||||
| 	c.Applications = &ApplicationsService{client: c} | ||||
| 	c.AwardEmoji = &AwardEmojiService{client: c} | ||||
| 	c.Boards = &IssueBoardsService{client: c} | ||||
| 	c.Branches = &BranchesService{client: c} | ||||
| @@ -461,6 +543,7 @@ func newClient(httpClient *http.Client) *Client { | ||||
| 	c.ContainerRegistry = &ContainerRegistryService{client: c} | ||||
| 	c.CustomAttribute = &CustomAttributesService{client: c} | ||||
| 	c.DeployKeys = &DeployKeysService{client: c} | ||||
| 	c.DeployTokens = &DeployTokensService{client: c} | ||||
| 	c.Deployments = &DeploymentsService{client: c} | ||||
| 	c.Discussions = &DiscussionsService{client: c} | ||||
| 	c.Environments = &EnvironmentsService{client: c} | ||||
| @@ -521,7 +604,107 @@ func newClient(httpClient *http.Client) *Client { | ||||
| 	c.Version = &VersionService{client: c} | ||||
| 	c.Wikis = &WikisService{client: c} | ||||
|  | ||||
| 	return c | ||||
| 	return c, nil | ||||
| } | ||||
|  | ||||
| // retryHTTPCheck provides a callback for Client.CheckRetry which | ||||
| // will retry both rate limit (429) and server (>= 500) errors. | ||||
| func (c *Client) retryHTTPCheck(ctx context.Context, resp *http.Response, err error) (bool, error) { | ||||
| 	if ctx.Err() != nil { | ||||
| 		return false, ctx.Err() | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	if !c.disableRetries && (resp.StatusCode == 429 || resp.StatusCode >= 500) { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return false, nil | ||||
| } | ||||
|  | ||||
| // retryHTTPBackoff provides a generic callback for Client.Backoff which | ||||
| // will pass through all calls based on the status code of the response. | ||||
| func (c *Client) retryHTTPBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { | ||||
| 	// Use the rate limit backoff function when we are rate limited. | ||||
| 	if resp != nil && resp.StatusCode == 429 { | ||||
| 		return rateLimitBackoff(min, max, attemptNum, resp) | ||||
| 	} | ||||
|  | ||||
| 	// Set custom duration's when we experience a service interruption. | ||||
| 	min = 700 * time.Millisecond | ||||
| 	max = 900 * time.Millisecond | ||||
|  | ||||
| 	return retryablehttp.LinearJitterBackoff(min, max, attemptNum, resp) | ||||
| } | ||||
|  | ||||
| // rateLimitBackoff provides a callback for Client.Backoff which will use the | ||||
| // RateLimit-Reset header to determine the time to wait. We add some jitter | ||||
| // to prevent a thundering herd. | ||||
| // | ||||
| // min and max are mainly used for bounding the jitter that will be added to | ||||
| // the reset time retrieved from the headers. But if the final wait time is | ||||
| // less then min, min will be used instead. | ||||
| func rateLimitBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { | ||||
| 	// rnd is used to generate pseudo-random numbers. | ||||
| 	rnd := rand.New(rand.NewSource(time.Now().UnixNano())) | ||||
|  | ||||
| 	// First create some jitter bounded by the min and max durations. | ||||
| 	jitter := time.Duration(rnd.Float64() * float64(max-min)) | ||||
|  | ||||
| 	if resp != nil { | ||||
| 		if v := resp.Header.Get(headerRateReset); v != "" { | ||||
| 			if reset, _ := strconv.ParseInt(v, 10, 64); reset > 0 { | ||||
| 				// Only update min if the given time to wait is longer. | ||||
| 				if wait := time.Until(time.Unix(reset, 0)); wait > min { | ||||
| 					min = wait | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return min + jitter | ||||
| } | ||||
|  | ||||
| // configureLimiter configures the rate limiter. | ||||
| func (c *Client) configureLimiter() error { | ||||
| 	// Set default values for when rate limiting is disabled. | ||||
| 	limit := rate.Inf | ||||
| 	burst := 0 | ||||
|  | ||||
| 	defer func() { | ||||
| 		// Create a new limiter using the calculated values. | ||||
| 		c.limiter = rate.NewLimiter(limit, burst) | ||||
| 	}() | ||||
|  | ||||
| 	// Create a new request. | ||||
| 	req, err := http.NewRequest("GET", c.baseURL.String(), nil) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Make a single request to retrieve the rate limit headers. | ||||
| 	resp, err := c.client.HTTPClient.Do(req) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	resp.Body.Close() | ||||
|  | ||||
| 	if v := resp.Header.Get(headerRateLimit); v != "" { | ||||
| 		if rateLimit, _ := strconv.ParseFloat(v, 64); rateLimit > 0 { | ||||
| 			// The rate limit is based on requests per minute, so for our limiter to | ||||
| 			// work correctly we devide the limit by 60 to get the limit per second. | ||||
| 			rateLimit /= 60 | ||||
| 			// Configure the limit and burst using a split of 2/3 for the limit and | ||||
| 			// 1/3 for the burst. This enables clients to burst 1/3 of the allowed | ||||
| 			// calls before the limiter kicks in. The remaining calls will then be | ||||
| 			// spread out evenly using intervals of time.Second / limit which should | ||||
| 			// prevent hitting the rate limit. | ||||
| 			limit = rate.Limit(rateLimit * 0.66) | ||||
| 			burst = int(rateLimit * 0.33) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // BaseURL return a copy of the baseURL. | ||||
| @@ -530,9 +713,8 @@ func (c *Client) BaseURL() *url.URL { | ||||
| 	return &u | ||||
| } | ||||
|  | ||||
| // SetBaseURL sets the base URL for API requests to a custom endpoint. urlStr | ||||
| // should always be specified with a trailing slash. | ||||
| func (c *Client) SetBaseURL(urlStr string) error { | ||||
| // setBaseURL sets the base URL for API requests to a custom endpoint. | ||||
| func (c *Client) setBaseURL(urlStr string) error { | ||||
| 	// Make sure the given URL end with a slash | ||||
| 	if !strings.HasSuffix(urlStr, "/") { | ||||
| 		urlStr += "/" | ||||
| @@ -554,11 +736,11 @@ func (c *Client) SetBaseURL(urlStr string) error { | ||||
| } | ||||
|  | ||||
| // NewRequest creates an API request. A relative URL path can be provided in | ||||
| // urlStr, in which case it is resolved relative to the base URL of the Client. | ||||
| // path, in which case it is resolved relative to the base URL of the Client. | ||||
| // Relative URL paths should always be specified without a preceding slash. If | ||||
| // specified, the value pointed to by body is JSON encoded and included as the | ||||
| // request body. | ||||
| func (c *Client) NewRequest(method, path string, opt interface{}, options []OptionFunc) (*http.Request, error) { | ||||
| func (c *Client) NewRequest(method, path string, opt interface{}, options []RequestOptionFunc) (*retryablehttp.Request, error) { | ||||
| 	u := *c.baseURL | ||||
| 	unescaped, err := url.PathUnescape(path) | ||||
| 	if err != nil { | ||||
| @@ -569,7 +751,33 @@ func (c *Client) NewRequest(method, path string, opt interface{}, options []Opti | ||||
| 	u.RawPath = c.baseURL.Path + path | ||||
| 	u.Path = c.baseURL.Path + unescaped | ||||
|  | ||||
| 	if opt != nil { | ||||
| 	// Create a request specific headers map. | ||||
| 	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) | ||||
| 	} | ||||
|  | ||||
| 	var body interface{} | ||||
| 	switch { | ||||
| 	case method == "POST" || method == "PUT": | ||||
| 		reqHeaders.Set("Content-Type", "application/json") | ||||
|  | ||||
| 		if opt != nil { | ||||
| 			body, err = json.Marshal(opt) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} | ||||
| 	case opt != nil: | ||||
| 		q, err := query.Values(opt) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| @@ -577,53 +785,23 @@ func (c *Client) NewRequest(method, path string, opt interface{}, options []Opti | ||||
| 		u.RawQuery = q.Encode() | ||||
| 	} | ||||
|  | ||||
| 	req := &http.Request{ | ||||
| 		Method:     method, | ||||
| 		URL:        &u, | ||||
| 		Proto:      "HTTP/1.1", | ||||
| 		ProtoMajor: 1, | ||||
| 		ProtoMinor: 1, | ||||
| 		Header:     make(http.Header), | ||||
| 		Host:       u.Host, | ||||
| 	req, err := retryablehttp.NewRequest(method, u.String(), body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for _, fn := range options { | ||||
| 		if fn == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if err := fn(req); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if method == "POST" || method == "PUT" { | ||||
| 		bodyBytes, err := json.Marshal(opt) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		bodyReader := bytes.NewReader(bodyBytes) | ||||
|  | ||||
| 		u.RawQuery = "" | ||||
| 		req.Body = ioutil.NopCloser(bodyReader) | ||||
| 		req.GetBody = func() (io.ReadCloser, error) { | ||||
| 			return ioutil.NopCloser(bodyReader), nil | ||||
| 		} | ||||
| 		req.ContentLength = int64(bodyReader.Len()) | ||||
| 		req.Header.Set("Content-Type", "application/json") | ||||
| 	} | ||||
|  | ||||
| 	req.Header.Set("Accept", "application/json") | ||||
|  | ||||
| 	switch c.authType { | ||||
| 	case basicAuth, oAuthToken: | ||||
| 		req.Header.Set("Authorization", "Bearer "+c.token) | ||||
| 	case privateToken: | ||||
| 		req.Header.Set("PRIVATE-TOKEN", c.token) | ||||
| 	} | ||||
|  | ||||
| 	if c.UserAgent != "" { | ||||
| 		req.Header.Set("User-Agent", c.UserAgent) | ||||
| 	// Set the request specific headers. | ||||
| 	for k, v := range reqHeaders { | ||||
| 		req.Header[k] = v | ||||
| 	} | ||||
|  | ||||
| 	return req, nil | ||||
| @@ -691,7 +869,16 @@ func (r *Response) populatePageValues() { | ||||
| // error if an API error has occurred. If v implements the io.Writer | ||||
| // interface, the raw response body will be written to v, without attempting to | ||||
| // first decode it. | ||||
| func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { | ||||
| func (c *Client) Do(req *retryablehttp.Request, v interface{}) (*Response, error) { | ||||
| 	// If not yet configured, try to configure the rate limiter. Fail | ||||
| 	// silently as the limiter will be disabled in case of an 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 { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.client.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @@ -710,8 +897,8 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { | ||||
|  | ||||
| 	err = CheckResponse(resp) | ||||
| 	if err != nil { | ||||
| 		// even though there was an error, we still return the response | ||||
| 		// in case the caller wants to inspect it further | ||||
| 		// Even though there was an error, we still return the response | ||||
| 		// in case the caller wants to inspect it further. | ||||
| 		return response, err | ||||
| 	} | ||||
|  | ||||
| @@ -826,32 +1013,6 @@ func parseError(raw interface{}) string { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // OptionFunc can be passed to all API requests to make the API call as if you were | ||||
| // another user, provided your private token is from an administrator account. | ||||
| // | ||||
| // GitLab docs: https://docs.gitlab.com/ce/api/README.html#sudo | ||||
| type OptionFunc func(*http.Request) error | ||||
|  | ||||
| // WithSudo takes either a username or user ID and sets the SUDO request header | ||||
| func WithSudo(uid interface{}) OptionFunc { | ||||
| 	return func(req *http.Request) error { | ||||
| 		user, err := parseID(uid) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		req.Header.Set("SUDO", user) | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WithContext runs the request with the provided context | ||||
| func WithContext(ctx context.Context) OptionFunc { | ||||
| 	return func(req *http.Request) error { | ||||
| 		*req = *req.WithContext(ctx) | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // 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 { | ||||
| @@ -901,6 +1062,14 @@ func BuildState(v BuildStateValue) *BuildStateValue { | ||||
| 	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 { | ||||
| @@ -925,6 +1094,22 @@ func Visibility(v VisibilityValue) *VisibilityValue { | ||||
| 	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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user