Files
gitlab.nvim/cmd/app/client.go
Harrison (Harry) Cramer e29909cd10 Bugfixes, Etc. (#502)
* Fix: Jumping to renamed files (#484)

* fix: prevent "cursor position outside buffer" error

* fix: swap file_name and old_file_name in reviewer data

`old_file_name` is not set to the empty string for un-renamed files anymore, because then we can
remove the empty-line check in `comment_helpers.go` which was used to replace the empty string with
the current file name anyway.

* fix: add old_file_name to discussion root node data

* fix: also consider old_file_name when jumping to the reviewer

This fixes jumping to renamed files, however, may not work for comments that
were created on renamed files with the previous version of `gitlab.nvim` as
that version assigned the `file_name` and `old_file_name` incorrectly.

* refactor: don't shadow variable

* fix: check file_name or old_file_name based on which SHA comment belongs to

* Fix: Store reviewer data before creating comment popup (#476)

* Fix: Make publishing drafts more robust (#483)

* Fix: Swap file_name and old_file_name in reviewer data (#485)

* Feat: Enable toggling date format between relative and absolute (#491)

* Fix: Add opts to help popup (#492)

* Fix: Force start_line for jumping to diagnostic to be inside buffer (#494)

* fix: redefine colors after reloading colorscheme (#500)

* Fix: Use path instead of oldpath as fallback for unrenamed files (#496)

* Fix: Use file_name when old_file_name is not set (#495)

* fix(ci): fix lua tests (#501)

* Proxy Support (#499)

This is a #MINOR release.

---------

Co-authored-by: Jakub F. Bortlík <jakub.bortlik@proton.me>
Co-authored-by: Jonathan Duck <Duckbrain30@gmail.com>
2025-06-24 20:53:51 -04:00

138 lines
3.7 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"
"github.com/xanzy/go-gitlab"
)
type ProjectInfo struct {
ProjectId string
MergeId int
}
/* The Client struct embeds all the methods from Gitlab for the different services */
type Client struct {
*gitlab.MergeRequestsService
*gitlab.MergeRequestApprovalsService
*gitlab.DiscussionsService
*gitlab.ProjectsService
*gitlab.ProjectMembersService
*gitlab.JobsService
*gitlab.PipelinesService
*gitlab.LabelsService
*gitlab.AwardEmojiService
*gitlab.UsersService
*gitlab.DraftNotesService
}
/* 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{
MergeRequestsService: client.MergeRequests,
MergeRequestApprovalsService: client.MergeRequestApprovals,
DiscussionsService: client.Discussions,
ProjectsService: client.Projects,
ProjectMembersService: client.ProjectMembers,
JobsService: client.Jobs,
PipelinesService: client.Pipelines,
LabelsService: client.Labels,
AwardEmojiService: client.AwardEmoji,
UsersService: client.Users,
DraftNotesService: client.DraftNotes,
}, 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)
}
}