Change to HTTP Model (#5)

This commit is contained in:
Harrison (Harry) Cramer
2023-05-19 17:28:58 -07:00
committed by GitHub
parent fe0d09d582
commit 63fc025070
21 changed files with 689 additions and 430 deletions

View File

@@ -1,18 +1,46 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func (c *Client) Approve() error {
func (c *Client) Approve() (string, int, error) {
_, _, err := c.git.MergeRequestApprovals.ApproveMergeRequest(c.projectId, c.mergeId, nil, nil)
_, res, err := c.git.MergeRequestApprovals.ApproveMergeRequest(c.projectId, c.mergeId, nil, nil)
if err != nil {
return fmt.Errorf("Approving MR failed: %w", err)
return "", res.Response.StatusCode, fmt.Errorf("Approving MR failed: %w", err)
}
fmt.Println("Success! Approved MR.")
return nil
return "Success! Approved MR.", http.StatusOK, nil
}
func ApproveHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
client := r.Context().Value("client").(Client)
msg, status, err := client.Approve()
w.WriteHeader(status)
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: status,
}
json.NewEncoder(w).Encode(response)
return
}
response := SuccessResponse{
Message: msg,
Status: http.StatusOK,
}
json.NewEncoder(w).Encode(response)
}

View File

@@ -16,22 +16,37 @@ type Client struct {
git *gitlab.Client
}
type Logger struct {
Active bool
}
func (l Logger) Printf(s string, args ...interface{}) {
logString := fmt.Sprintf(s+"\n", args...)
file, err := os.OpenFile("./logs", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
defer file.Close()
_, err = file.Write([]byte(logString))
}
/* This will initialize the client with the token and check for the basic project ID and command arguments */
func (c *Client) Init(branchName string) error {
if len(os.Args) < 3 {
return errors.New("Must provide command and projectId")
if len(os.Args) < 2 {
return errors.New("Must provide project ID!")
}
command, projectId := os.Args[1], os.Args[2]
c.command = command
projectId := os.Args[1]
c.projectId = projectId
if projectId == "" {
return errors.New("Must provide projectId")
return errors.New("Project ID cannot be empty")
}
git, err := gitlab.NewClient(os.Getenv("GITLAB_TOKEN"))
var l Logger
git, err := gitlab.NewClient(os.Getenv("GITLAB_TOKEN"), gitlab.WithCustomLogger(l))
if err != nil {
return fmt.Errorf("Failed to create client: %v", err)
}
@@ -61,8 +76,3 @@ func (c *Client) Init(branchName string) error {
return nil
}
func (c *Client) Usage(command string) {
fmt.Printf("Usage: gitlab-nvim %s <project-id> ...args", command)
os.Exit(1)
}

View File

@@ -5,12 +5,11 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"os"
"strconv"
"time"
"github.com/xanzy/go-gitlab"
@@ -29,20 +28,192 @@ type MRVersion struct {
RealSize string `json:"real_size"`
}
func (c *Client) Comment() error {
if len(os.Args) < 6 {
c.Usage("comment")
type PostCommentRequest struct {
LineNumber int `json:"line_number"`
FileName string `json:"file_name"`
Comment string `json:"comment"`
}
type DeleteCommentRequest struct {
NoteId int `json:"note_id"`
DiscussionId string `json:"discussion_id"`
}
type EditCommentRequest struct {
Comment string `json:"comment"`
NoteId int `json:"note_id"`
DiscussionId string `json:"discussion_id"`
}
func CommentHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodDelete:
DeleteComment(w, r)
case http.MethodPost:
PostComment(w, r)
case http.MethodPatch:
EditComment(w, r)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
func DeleteComment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
c := r.Context().Value("client").(Client)
body, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not read request body"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
lineNumber, fileName, comment := os.Args[3], os.Args[4], os.Args[5]
if lineNumber == "" || fileName == "" || comment == "" {
c.Usage("comment")
defer r.Body.Close()
var deleteCommentRequest DeleteCommentRequest
err = json.Unmarshal(body, &deleteCommentRequest)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not read JSON from request"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
res, err := c.git.Discussions.DeleteMergeRequestDiscussionNote(c.projectId, c.mergeId, deleteCommentRequest.DiscussionId, deleteCommentRequest.NoteId)
w.WriteHeader(res.Response.StatusCode)
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: res.Response.StatusCode,
}
json.NewEncoder(w).Encode(response)
return
}
response := SuccessResponse{
Message: "Comment deleted succesfully",
Status: http.StatusOK,
}
json.NewEncoder(w).Encode(response)
}
func PostComment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
c := r.Context().Value("client").(Client)
body, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not read request body"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
defer r.Body.Close()
var postCommentRequest PostCommentRequest
err = json.Unmarshal(body, &postCommentRequest)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not unmarshal data from request body"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
res, err := c.PostComment(postCommentRequest)
for k, v := range res.Header {
w.Header().Set(k, v[0])
}
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: res.StatusCode,
}
json.NewEncoder(w).Encode(response)
return
}
response := SuccessResponse{
Message: "Comment created succesfully",
Status: http.StatusOK,
}
json.NewEncoder(w).Encode(response)
// w.WriteHeader(res.StatusCode)
// io.Copy(w, res.Body)
}
func EditComment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
c := r.Context().Value("client").(Client)
body, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not read request body"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
defer r.Body.Close()
var editCommentRequest EditCommentRequest
err = json.Unmarshal(body, &editCommentRequest)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not unmarshal data from request body"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
options := gitlab.UpdateMergeRequestDiscussionNoteOptions{
Body: gitlab.String(editCommentRequest.Comment),
}
_, res, err := c.git.Discussions.UpdateMergeRequestDiscussionNote(c.projectId, c.mergeId, editCommentRequest.DiscussionId, editCommentRequest.NoteId, &options)
for k, v := range res.Header {
w.Header().Set(k, v[0])
}
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: res.StatusCode,
}
json.NewEncoder(w).Encode(response)
return
}
response := SuccessResponse{
Message: "Comment edited succesfully",
Status: http.StatusOK,
}
json.NewEncoder(w).Encode(response)
}
func (c *Client) PostComment(cr PostCommentRequest) (*http.Response, error) {
err, response := getMRVersions(c.projectId, c.mergeId)
if err != nil {
log.Fatalf("Error making diff thread: %s", err)
return nil, fmt.Errorf("Error making diff thread: %e", err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
@@ -50,7 +221,7 @@ func (c *Client) Comment() error {
var diffVersionInfo []MRVersion
err = json.Unmarshal(body, &diffVersionInfo)
if err != nil {
return fmt.Errorf("Error unmarshalling version info JSON: %w", err)
return nil, fmt.Errorf("Error unmarshalling version info JSON: %w", err)
}
/* This is necessary since we do not know whether the comment is on a line that
@@ -65,14 +236,14 @@ func (c *Client) Comment() error {
See the Gitlab documentation: https://docs.gitlab.com/ee/api/discussions.html#create-a-new-thread-in-the-merge-request-diff */
for i := 0; i < 3; i++ {
ii := i
_, err := c.CommentOnDeletion(lineNumber, fileName, comment, diffVersionInfo[0], ii)
if err == nil {
fmt.Println("Left Comment: " + comment[0:min(len(comment), 25)] + "...")
return nil
res, err := c.CommentOnDeletion(cr.LineNumber, cr.FileName, cr.Comment, diffVersionInfo[0], ii)
if err == nil && res.StatusCode >= 200 && res.StatusCode <= 299 {
return res, nil
}
}
return fmt.Errorf("Could not leave comment")
return nil, fmt.Errorf("Could not leave comment")
}
@@ -115,7 +286,7 @@ func getMRVersions(projectId string, mergeId int) (e error, response *http.Respo
Creates a new merge request discussion https://docs.gitlab.com/ee/api/discussions.html#create-new-merge-request-thread
The go-gitlab client was not working for this API specifically 😢
*/
func (c *Client) CommentOnDeletion(lineNumber string, fileName string, comment string, diffVersionInfo MRVersion, i int) (*http.Response, error) {
func (c *Client) CommentOnDeletion(lineNumber int, fileName string, comment string, diffVersionInfo MRVersion, i int) (*http.Response, error) {
deletionDiscussionUrl := fmt.Sprintf("https://gitlab.com/api/v4/projects/%s/merge_requests/%d/discussions", c.projectId, c.mergeId)
@@ -132,12 +303,12 @@ func (c *Client) CommentOnDeletion(lineNumber string, fileName string, comment s
_ = writer.WriteField("position[old_path]", fileName)
_ = writer.WriteField("position[new_path]", fileName)
if i == 0 {
_ = writer.WriteField("position[old_line]", lineNumber)
_ = writer.WriteField("position[old_line]", fmt.Sprintf("%d", lineNumber))
} else if i == 1 {
_ = writer.WriteField("position[new_line]", lineNumber)
_ = writer.WriteField("position[new_line]", fmt.Sprintf("%d", lineNumber))
} else {
_ = writer.WriteField("position[old_line]", lineNumber)
_ = writer.WriteField("position[new_line]", lineNumber)
_ = writer.WriteField("position[old_line]", fmt.Sprintf("%d", lineNumber))
_ = writer.WriteField("position[new_line]", fmt.Sprintf("%d", lineNumber))
}
err := writer.Close()
@@ -152,39 +323,9 @@ func (c *Client) CommentOnDeletion(lineNumber string, fileName string, comment s
return nil, fmt.Errorf("Error building request: %w", err)
}
req.Header.Add("PRIVATE-TOKEN", os.Getenv("GITLAB_TOKEN"))
req.Header.Set("Content-Type", writer.FormDataContentType())
res, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("Error making request: %w", err)
}
defer res.Body.Close()
return res, nil
}
func (c *Client) OverviewComment() error {
lineNumber, fileName, comment, sha := os.Args[3], os.Args[4], os.Args[5], os.Args[6]
if lineNumber == "" || fileName == "" || comment == "" {
c.Usage("comment")
}
lineNumberInt, err := strconv.Atoi(lineNumber)
if err != nil {
return fmt.Errorf("Not a valid line number: %w", err)
}
postCommitCommentOptions := gitlab.PostCommitCommentOptions{
Note: gitlab.String(comment),
Path: gitlab.String(fileName),
Line: &lineNumberInt,
LineType: gitlab.String("old"),
}
_, _, err = c.git.Commits.PostCommitComment(c.projectId, sha, &postCommitCommentOptions)
if err != nil {
return fmt.Errorf("Error leaving overview comment: %w", err)
}
fmt.Println("Left Overview Comment: " + comment[0:min(len(comment), 25)] + "...")
return nil
return res, err
}

View File

@@ -1,29 +0,0 @@
package main
import (
"fmt"
"os"
"strconv"
)
func (c *Client) DeleteComment() error {
discussionId, noteId := os.Args[3], os.Args[4]
if discussionId == "" || noteId == "" {
c.Usage("deleteComment")
}
noteIdInt, err := strconv.Atoi(noteId)
if err != nil {
return fmt.Errorf("Could not convert noteId to int: %w", err)
}
_, err = c.git.Discussions.DeleteMergeRequestDiscussionNote(c.projectId, c.mergeId, discussionId, noteIdInt)
if err != nil {
return fmt.Errorf("Could not delete comment: %w", err)
}
fmt.Println("Deleted comment")
return nil
}

View File

@@ -1,46 +0,0 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
"github.com/xanzy/go-gitlab"
)
func (c *Client) EditComment() error {
if len(os.Args) < 6 {
return errors.New("Must provide commentId, noteId, and edited text")
}
discussionId, noteId, newCommentText := os.Args[3], os.Args[4], os.Args[5]
if discussionId == "" || newCommentText == "" {
return errors.New("Must provide commentId, noteId, and edited text")
}
options := gitlab.UpdateMergeRequestDiscussionNoteOptions{
Body: gitlab.String(newCommentText),
}
noteIdInt, err := strconv.Atoi(noteId)
if err != nil {
return errors.New("Not a valid noteId")
}
gitlabNote, _, err := c.git.Discussions.UpdateMergeRequestDiscussionNote(c.projectId, c.mergeId, discussionId, noteIdInt, &options)
if err != nil {
return fmt.Errorf("Failed to edit comment: %w", err)
}
note, err := json.Marshal(gitlabNote)
if err != nil {
return fmt.Errorf("Failed to marshal note: %w", err)
}
fmt.Println(string(note))
return nil
}

View File

@@ -1,6 +1,7 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"io"
@@ -10,13 +11,13 @@ import (
const mrUrl = "https://gitlab.com/api/v4/projects/%s/merge_requests/%d"
func (c *Client) Info() error {
func (c *Client) Info() ([]byte, error) {
url := fmt.Sprintf(mrUrl, c.projectId, c.mergeId)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return fmt.Errorf("Failed to build read request: %w", err)
return nil, fmt.Errorf("Failed to build read request: %w", err)
}
req.Header.Set("PRIVATE-TOKEN", os.Getenv("GITLAB_TOKEN"))
@@ -25,22 +26,42 @@ func (c *Client) Info() error {
res, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("Failed to make info request: %w", err)
return nil, fmt.Errorf("Failed to make info request: %w", err)
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode >= 300 {
return errors.New(fmt.Sprintf("Recieved non-200 response: %d", res.StatusCode))
return nil, errors.New(fmt.Sprintf("Recieved non-200 response: %d", res.StatusCode))
}
body, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("Failed to parse read response: %w", err)
return nil, fmt.Errorf("Failed to parse read response: %w", err)
}
/* This response is parsed into a table in our Lua code */
fmt.Println(string(body))
return body, nil
return nil
}
func InfoHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
client := r.Context().Value("client").(Client)
msg, err := client.Info()
if err != nil {
errResp := map[string]string{"message": err.Error()}
response, _ := json.Marshal(errResp)
w.WriteHeader(http.StatusInternalServerError)
w.Write(response)
return
}
w.WriteHeader(http.StatusOK)
w.Write(msg)
}

View File

@@ -2,6 +2,7 @@ package main
import (
"fmt"
"net/http"
"sort"
"encoding/json"
@@ -11,6 +12,11 @@ import (
type SortableDiscussions []*gitlab.Discussion
type DiscussionsResponse struct {
SuccessResponse
Discussions []*gitlab.Discussion `json:"discussions"`
}
func (n SortableDiscussions) Len() int {
return len(n)
}
@@ -26,16 +32,16 @@ func (n SortableDiscussions) Swap(i, j int) {
n[i], n[j] = n[j], n[i]
}
func (c *Client) ListDiscussions() error {
func (c *Client) ListDiscussions() ([]*gitlab.Discussion, int, error) {
mergeRequestDiscussionOptions := gitlab.ListMergeRequestDiscussionsOptions{
Page: 1,
PerPage: 250,
}
discussions, _, err := c.git.Discussions.ListMergeRequestDiscussions(c.projectId, c.mergeId, &mergeRequestDiscussionOptions, nil)
discussions, res, err := c.git.Discussions.ListMergeRequestDiscussions(c.projectId, c.mergeId, &mergeRequestDiscussionOptions, nil)
if err != nil {
return fmt.Errorf("Listing discussions failed: %w", err)
return nil, res.Response.StatusCode, fmt.Errorf("Listing discussions failed: %w", err)
}
var realDiscussions []*gitlab.Discussion
@@ -52,9 +58,35 @@ func (c *Client) ListDiscussions() error {
sortedDiscussions := SortableDiscussions(realDiscussions)
sort.Sort(sortedDiscussions)
discussionsOutput, err := json.Marshal(sortedDiscussions)
fmt.Println(string(discussionsOutput))
return nil
return sortedDiscussions, http.StatusOK, nil
}
func ListDiscussionsHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
c := r.Context().Value("client").(Client)
msg, status, err := c.ListDiscussions()
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: status,
}
json.NewEncoder(w).Encode(response)
return
}
response := DiscussionsResponse{
SuccessResponse: SuccessResponse{
Message: "Discussions successfully fetched.",
Status: http.StatusOK,
},
Discussions: msg,
}
json.NewEncoder(w).Encode(response)
}

View File

@@ -1,61 +1,59 @@
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/exec"
"strings"
)
const (
star = "star"
info = "info"
approve = "approve"
revoke = "revoke"
comment = "comment"
overviewComment = "overviewComment"
deleteComment = "deleteComment"
editComment = "editComment"
reply = "reply"
listDiscussions = "listDiscussions"
)
func main() {
branchName, err := getCurrentBranch()
errCheck(err)
if branchName == "main" || branchName == "master" {
return
log.Fatalf("Cannot run on %s branch", branchName)
}
/* Initialize Gitlab client */
var c Client
errCheck(c.Init(branchName))
switch c.command {
case star:
errCheck(c.Star())
case approve:
errCheck(c.Approve())
case revoke:
errCheck(c.Revoke())
case comment:
errCheck(c.Comment())
case deleteComment:
errCheck(c.DeleteComment())
case editComment:
errCheck(c.EditComment())
case overviewComment:
errCheck(c.OverviewComment())
case info:
errCheck(c.Info())
case reply:
errCheck(c.Reply())
case listDiscussions:
errCheck(c.ListDiscussions())
default:
c.Usage("command")
m := http.NewServeMux()
m.Handle("/approve", withGitlabContext(http.HandlerFunc(ApproveHandler), c))
m.Handle("/revoke", withGitlabContext(http.HandlerFunc(RevokeHandler), c))
m.Handle("/star", withGitlabContext(http.HandlerFunc(StarHandler), c))
m.Handle("/info", withGitlabContext(http.HandlerFunc(InfoHandler), c))
m.Handle("/discussions", withGitlabContext(http.HandlerFunc(ListDiscussionsHandler), c))
m.Handle("/comment", withGitlabContext(http.HandlerFunc(CommentHandler), c))
m.Handle("/reply", withGitlabContext(http.HandlerFunc(ReplyHandler), c))
server := &http.Server{
Addr: fmt.Sprintf(":%s", os.Args[2]),
Handler: m,
}
done := make(chan bool)
go server.ListenAndServe()
/* This print is detected by the Lua code and used to fetch project information */
fmt.Println("Server started.")
<-done
}
type ResponseError struct {
message string
}
func withGitlabContext(next http.HandlerFunc, c Client) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(context.Background(), "client", c)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func errCheck(err error) {

View File

@@ -2,40 +2,90 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"os"
"io"
"net/http"
"time"
"github.com/xanzy/go-gitlab"
)
func (c *Client) Reply() error {
type ReplyRequest struct {
DiscussionId string `json:"discussion_id"`
Reply string `json:"reply"`
}
if len(os.Args) < 5 {
return errors.New("Must provide discussionId and reply text")
}
type ReplyResponse struct {
SuccessResponse
Note *gitlab.Note `json:"note"`
}
discussionId, reply := os.Args[3], os.Args[4]
func (c *Client) Reply(r ReplyRequest) (*gitlab.Note, int, error) {
now := time.Now()
options := gitlab.AddMergeRequestDiscussionNoteOptions{
Body: gitlab.String(reply),
Body: gitlab.String(r.Reply),
CreatedAt: &now,
}
gitlabNote, _, err := c.git.Discussions.AddMergeRequestDiscussionNote(c.projectId, c.mergeId, discussionId, &options)
note, res, err := c.git.Discussions.AddMergeRequestDiscussionNote(c.projectId, c.mergeId, r.DiscussionId, &options)
if err != nil {
return fmt.Errorf("Could not leave reply: %w", err)
return nil, res.Response.StatusCode, fmt.Errorf("Could not leave reply: %w", err)
}
output, err := json.Marshal(gitlabNote)
if err != nil {
return fmt.Errorf("Could not marshal note: %w", err)
}
fmt.Println(string(output))
return nil
return note, http.StatusOK, nil
}
func ReplyHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
c := r.Context().Value("client").(Client)
body, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not read request body"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
defer r.Body.Close()
var replyRequest ReplyRequest
err = json.Unmarshal(body, &replyRequest)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
errMsg := map[string]string{"message": "Could not read JSON from request"}
jsonMsg, _ := json.Marshal(errMsg)
w.Write(jsonMsg)
return
}
note, status, err := c.Reply(replyRequest)
w.Header().Set("Content-Type", "application/json")
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: status,
}
json.NewEncoder(w).Encode(response)
return
}
response := ReplyResponse{
SuccessResponse: SuccessResponse{
Message: fmt.Sprintf("Replied: %s", note.Body),
Status: http.StatusOK,
},
Note: note,
}
json.NewEncoder(w).Encode(response)
}

View File

@@ -1,18 +1,47 @@
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func (c *Client) Revoke() error {
func (c *Client) Revoke() (string, int, error) {
_, err := c.git.MergeRequestApprovals.UnapproveMergeRequest(c.projectId, c.mergeId, nil, nil)
res, err := c.git.MergeRequestApprovals.UnapproveMergeRequest(c.projectId, c.mergeId, nil, nil)
if err != nil {
return fmt.Errorf("Revoking approval failed: %w", err)
return "", res.Response.StatusCode, fmt.Errorf("Revoking approval failed: %w", err)
}
fmt.Println("Success! Revoked MR approval.")
return "Success! Revoked MR approval.", http.StatusOK, nil
return nil
}
func RevokeHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
client := r.Context().Value("client").(Client)
msg, status, err := client.Revoke()
w.WriteHeader(status)
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: status,
}
json.NewEncoder(w).Encode(response)
return
}
response := SuccessResponse{
Message: msg,
Status: http.StatusOK,
}
json.NewEncoder(w).Encode(response)
}

View File

@@ -1,17 +1,46 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/xanzy/go-gitlab"
)
func (c *Client) Star() error {
project, _, err := c.git.Projects.StarProject(c.projectId)
func (c *Client) Star() (*gitlab.Project, int, error) {
project, res, err := c.git.Projects.StarProject(c.projectId)
if err != nil {
return fmt.Errorf("Starring project failed: %w", err)
return nil, res.Response.StatusCode, fmt.Errorf("Starring project failed: %w", err)
}
log.Printf("Success! Starred project: %s", project.Name)
return project, http.StatusOK, nil
return nil
}
func StarHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
client := r.Context().Value("client").(Client)
project, status, err := client.Star()
w.Header().Set("Content-Type", "application/json")
if err != nil {
response := ErrorResponse{
Message: err.Error(),
Status: status,
}
json.NewEncoder(w).Encode(response)
return
}
response := SuccessResponse{
Message: fmt.Sprintf("Starred project %s successfully!", project.Name),
Status: http.StatusOK,
}
json.NewEncoder(w).Encode(response)
}

12
cmd/start.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import (
"fmt"
"os"
)
func (c *Client) Start() error {
processId := os.Getpid()
fmt.Println(processId)
return nil
}

11
cmd/types.go Normal file
View File

@@ -0,0 +1,11 @@
package main
type ErrorResponse struct {
Message string `json:"message"`
Status int `json:"status"`
}
type SuccessResponse struct {
Message string `json:"message"`
Status int `json:"status"`
}