package main import ( "encoding/json" "fmt" "io" "net/http" "github.com/xanzy/go-gitlab" ) type LabelUpdateRequest struct { Labels []string `json:"labels"` } type Label struct { Name string Color string } type LabelUpdateResponse struct { SuccessResponse Labels gitlab.Labels `json:"labels"` } type LabelsRequestResponse struct { SuccessResponse Labels []Label `json:"labels"` } /* labelsHandler adds or removes labels from a merge request, and returns all labels for the current project */ func (a *api) labelHandler(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: a.getLabels(w, r) case http.MethodPut: a.updateLabels(w, r) default: w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Methods", fmt.Sprintf("%s, %s", http.MethodPut, http.MethodGet)) handleError(w, InvalidRequestError{}, "Expected GET or PUT", http.StatusMethodNotAllowed) } } func (a *api) getLabels(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") labels, res, err := a.client.ListLabels(a.projectInfo.ProjectId, &gitlab.ListLabelsOptions{}) if err != nil { handleError(w, err, "Could not modify merge request labels", http.StatusInternalServerError) return } if res.StatusCode >= 300 { handleError(w, GenericError{endpoint: "/mr/label"}, "Could not modify merge request labels", res.StatusCode) return } /* Hacky, but convert them to the correct response */ convertedLabels := make([]Label, len(labels)) for i, labelPtr := range labels { convertedLabels[i] = Label{ Name: labelPtr.Name, Color: labelPtr.Color, } } w.WriteHeader(http.StatusOK) response := LabelsRequestResponse{ SuccessResponse: SuccessResponse{ Message: "Labels updated", Status: http.StatusOK, }, Labels: convertedLabels, } err = json.NewEncoder(w).Encode(response) if err != nil { handleError(w, err, "Could not encode response", http.StatusInternalServerError) } } func (a *api) updateLabels(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") body, err := io.ReadAll(r.Body) if err != nil { handleError(w, err, "Could not read request body", http.StatusBadRequest) return } defer r.Body.Close() var labelUpdateRequest LabelUpdateRequest err = json.Unmarshal(body, &labelUpdateRequest) if err != nil { handleError(w, err, "Could not read JSON from request", http.StatusBadRequest) return } var labels = gitlab.Labels(labelUpdateRequest.Labels) mr, res, err := a.client.UpdateMergeRequest(a.projectInfo.ProjectId, a.projectInfo.MergeId, &gitlab.UpdateMergeRequestOptions{ Labels: &labels, }) if err != nil { handleError(w, err, "Could not modify merge request labels", http.StatusInternalServerError) return } if res.StatusCode >= 300 { handleError(w, GenericError{endpoint: "/mr/label"}, "Could not modify merge request labels", res.StatusCode) return } w.WriteHeader(http.StatusOK) response := LabelUpdateResponse{ SuccessResponse: SuccessResponse{ Message: "Labels updated", Status: http.StatusOK, }, Labels: mr.Labels, } err = json.NewEncoder(w).Encode(response) if err != nil { handleError(w, err, "Could not encode response", http.StatusInternalServerError) } }