142 lines
3.6 KiB
Go
142 lines
3.6 KiB
Go
package app
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/harrisoncramer/gitlab.nvim/cmd/app/git"
|
|
"github.com/hashicorp/go-retryablehttp"
|
|
gitlab "gitlab.com/gitlab-org/api/client-go"
|
|
)
|
|
|
|
type ProjectInfo struct {
|
|
ProjectId string
|
|
MergeId int64
|
|
}
|
|
|
|
/* The Client struct embeds all the methods from Gitlab for the different services */
|
|
type Client struct {
|
|
gitlab.MergeRequestsServiceInterface
|
|
gitlab.MergeRequestApprovalsServiceInterface
|
|
gitlab.DiscussionsServiceInterface
|
|
gitlab.ProjectsServiceInterface
|
|
gitlab.ProjectMembersServiceInterface
|
|
gitlab.JobsServiceInterface
|
|
gitlab.PipelinesServiceInterface
|
|
gitlab.LabelsServiceInterface
|
|
gitlab.AwardEmojiServiceInterface
|
|
gitlab.UsersServiceInterface
|
|
gitlab.DraftNotesServiceInterface
|
|
gitlab.ProjectMarkdownUploadsServiceInterface
|
|
gitlab.GraphQLInterface
|
|
}
|
|
|
|
/* NewClient parses and validates the project settings and initializes the Gitlab client. */
|
|
func NewClient() (*Client, error) {
|
|
|
|
if pluginOptions.GitlabUrl == "" {
|
|
return nil, errors.New("GitLab instance URL cannot be empty")
|
|
}
|
|
|
|
var apiCustUrl = fmt.Sprintf("%s/api/v4", pluginOptions.GitlabUrl)
|
|
|
|
gitlabOptions := []gitlab.ClientOptionFunc{
|
|
gitlab.WithBaseURL(apiCustUrl),
|
|
}
|
|
|
|
if pluginOptions.Debug.GitlabRequest {
|
|
gitlabOptions = append(gitlabOptions, gitlab.WithRequestLogHook(
|
|
func(l retryablehttp.Logger, r *http.Request, i int) {
|
|
logRequest("REQUEST TO GITLAB", r)
|
|
},
|
|
))
|
|
}
|
|
|
|
if pluginOptions.Debug.GitlabResponse {
|
|
gitlabOptions = append(gitlabOptions, gitlab.WithResponseLogHook(func(l retryablehttp.Logger, response *http.Response) {
|
|
logResponse("RESPONSE FROM GITLAB", response)
|
|
},
|
|
))
|
|
}
|
|
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: pluginOptions.ConnectionSettings.Insecure,
|
|
},
|
|
}
|
|
|
|
if proxy := pluginOptions.ConnectionSettings.Proxy; proxy != "" {
|
|
u, err := url.Parse(proxy)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parse proxy url: %w", err)
|
|
}
|
|
tr.Proxy = http.ProxyURL(u)
|
|
}
|
|
|
|
retryClient := retryablehttp.NewClient()
|
|
retryClient.HTTPClient.Transport = tr
|
|
gitlabOptions = append(gitlabOptions, gitlab.WithHTTPClient(retryClient.HTTPClient))
|
|
gitlabOptions = append(gitlabOptions, gitlab.WithoutRetries())
|
|
|
|
client, err := gitlab.NewClient(pluginOptions.AuthToken, gitlabOptions...)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create client: %v", err)
|
|
}
|
|
|
|
return &Client{
|
|
client.MergeRequests,
|
|
client.MergeRequestApprovals,
|
|
client.Discussions,
|
|
client.Projects,
|
|
client.ProjectMembers,
|
|
client.Jobs,
|
|
client.Pipelines,
|
|
client.Labels,
|
|
client.AwardEmoji,
|
|
client.Users,
|
|
client.DraftNotes,
|
|
client.ProjectMarkdownUploads,
|
|
client.GraphQL,
|
|
}, nil
|
|
}
|
|
|
|
/* InitProjectSettings fetch the project ID using the client */
|
|
func InitProjectSettings(c *Client, gitInfo git.GitData) (*ProjectInfo, error) {
|
|
|
|
opt := gitlab.GetProjectOptions{}
|
|
project, _, err := c.GetProject(gitInfo.ProjectPath(), &opt)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting project at %s: %w", gitInfo.RemoteUrl, err)
|
|
}
|
|
|
|
if project == nil {
|
|
return nil, fmt.Errorf("could not find project at %s", gitInfo.RemoteUrl)
|
|
}
|
|
|
|
projectId := fmt.Sprint(project.ID)
|
|
|
|
return &ProjectInfo{
|
|
ProjectId: projectId,
|
|
}, nil
|
|
}
|
|
|
|
/* handleError is a utililty handler that returns errors to the client along with their statuses and messages */
|
|
func handleError(w http.ResponseWriter, err error, message string, status int) {
|
|
w.WriteHeader(status)
|
|
response := ErrorResponse{
|
|
Message: message,
|
|
Details: err.Error(),
|
|
}
|
|
|
|
err = json.NewEncoder(w).Encode(response)
|
|
if err != nil {
|
|
handleError(w, err, "Could not encode error response", http.StatusInternalServerError)
|
|
}
|
|
}
|