Feat: Add and Remove Labels from an MR (#159)
This MR adds the ability to add or remove labels to a merge request. These labels are visible in the summary panel and are colored the same way as they would be in the Gitlab UI. This is a MINOR release.
This commit is contained in:
committed by
GitHub
parent
67f09e559a
commit
50e06ceff6
@@ -247,6 +247,8 @@ vim.keymap.set("n", "gln", gitlab.create_note)
|
|||||||
vim.keymap.set("n", "gld", gitlab.toggle_discussions)
|
vim.keymap.set("n", "gld", gitlab.toggle_discussions)
|
||||||
vim.keymap.set("n", "glaa", gitlab.add_assignee)
|
vim.keymap.set("n", "glaa", gitlab.add_assignee)
|
||||||
vim.keymap.set("n", "glad", gitlab.delete_assignee)
|
vim.keymap.set("n", "glad", gitlab.delete_assignee)
|
||||||
|
vim.keymap.set("n", "glla", gitlab.add_label)
|
||||||
|
vim.keymap.set("n", "glld", gitlab.delete_label)
|
||||||
vim.keymap.set("n", "glra", gitlab.add_reviewer)
|
vim.keymap.set("n", "glra", gitlab.add_reviewer)
|
||||||
vim.keymap.set("n", "glrd", gitlab.delete_reviewer)
|
vim.keymap.set("n", "glrd", gitlab.delete_reviewer)
|
||||||
vim.keymap.set("n", "glp", gitlab.pipeline)
|
vim.keymap.set("n", "glp", gitlab.pipeline)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type Client struct {
|
|||||||
*gitlab.ProjectMembersService
|
*gitlab.ProjectMembersService
|
||||||
*gitlab.JobsService
|
*gitlab.JobsService
|
||||||
*gitlab.PipelinesService
|
*gitlab.PipelinesService
|
||||||
|
*gitlab.LabelsService
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initGitlabClient parses and validates the project settings and initializes the Gitlab client. */
|
/* initGitlabClient parses and validates the project settings and initializes the Gitlab client. */
|
||||||
@@ -87,6 +88,7 @@ func initGitlabClient() (error, *Client) {
|
|||||||
ProjectMembersService: client.ProjectMembers,
|
ProjectMembersService: client.ProjectMembers,
|
||||||
JobsService: client.Jobs,
|
JobsService: client.Jobs,
|
||||||
PipelinesService: client.Pipelines,
|
PipelinesService: client.Pipelines,
|
||||||
|
LabelsService: client.Labels,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
130
cmd/label.go
Normal file
130
cmd/label.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -122,6 +122,7 @@ func createRouterAndApi(client ClientInterface, optFuncs ...optFunc) (*http.Serv
|
|||||||
m.HandleFunc("/mr/reviewer", a.withMr(a.reviewersHandler))
|
m.HandleFunc("/mr/reviewer", a.withMr(a.reviewersHandler))
|
||||||
m.HandleFunc("/mr/revisions", a.withMr(a.revisionsHandler))
|
m.HandleFunc("/mr/revisions", a.withMr(a.revisionsHandler))
|
||||||
m.HandleFunc("/mr/reply", a.withMr(a.replyHandler))
|
m.HandleFunc("/mr/reply", a.withMr(a.replyHandler))
|
||||||
|
m.HandleFunc("/mr/label", a.withMr(a.labelHandler))
|
||||||
m.HandleFunc("/mr/revoke", a.withMr(a.revokeHandler))
|
m.HandleFunc("/mr/revoke", a.withMr(a.revokeHandler))
|
||||||
|
|
||||||
m.HandleFunc("/attachment", a.attachmentHandler)
|
m.HandleFunc("/attachment", a.attachmentHandler)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ type fakeClient struct {
|
|||||||
retryPipelineBuild func(pid interface{}, pipeline int, options ...gitlab.RequestOptionFunc) (*gitlab.Pipeline, *gitlab.Response, error)
|
retryPipelineBuild func(pid interface{}, pipeline int, options ...gitlab.RequestOptionFunc) (*gitlab.Pipeline, *gitlab.Response, error)
|
||||||
listPipelineJobs func(pid interface{}, pipelineID int, opts *gitlab.ListJobsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Job, *gitlab.Response, error)
|
listPipelineJobs func(pid interface{}, pipelineID int, opts *gitlab.ListJobsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Job, *gitlab.Response, error)
|
||||||
getTraceFile func(pid interface{}, jobID int, options ...gitlab.RequestOptionFunc) (*bytes.Reader, *gitlab.Response, error)
|
getTraceFile func(pid interface{}, jobID int, options ...gitlab.RequestOptionFunc) (*bytes.Reader, *gitlab.Response, error)
|
||||||
|
listLabels func(pid interface{}, opt *gitlab.ListLabelsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Label, *gitlab.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Author struct {
|
type Author struct {
|
||||||
@@ -120,6 +121,10 @@ func (f fakeClient) GetTraceFile(pid interface{}, jobID int, options ...gitlab.R
|
|||||||
return f.getTraceFile(pid, jobID, options...)
|
return f.getTraceFile(pid, jobID, options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f fakeClient) ListLabels(pid interface{}, opt *gitlab.ListLabelsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Label, *gitlab.Response, error) {
|
||||||
|
return f.listLabels(pid, opt, options...)
|
||||||
|
}
|
||||||
|
|
||||||
/* This middleware function needs to return an ID for the rest of the handlers */
|
/* This middleware function needs to return an ID for the rest of the handlers */
|
||||||
func (f fakeClient) ListProjectMergeRequests(pid interface{}, opt *gitlab.ListProjectMergeRequestsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.MergeRequest, *gitlab.Response, error) {
|
func (f fakeClient) ListProjectMergeRequests(pid interface{}, opt *gitlab.ListProjectMergeRequestsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||||
return []*gitlab.MergeRequest{{ID: 1}}, &gitlab.Response{}, nil
|
return []*gitlab.MergeRequest{{ID: 1}}, &gitlab.Response{}, nil
|
||||||
|
|||||||
@@ -54,4 +54,5 @@ type ClientInterface interface {
|
|||||||
RetryPipelineBuild(pid interface{}, pipeline int, options ...gitlab.RequestOptionFunc) (*gitlab.Pipeline, *gitlab.Response, error)
|
RetryPipelineBuild(pid interface{}, pipeline int, options ...gitlab.RequestOptionFunc) (*gitlab.Pipeline, *gitlab.Response, error)
|
||||||
ListPipelineJobs(pid interface{}, pipelineID int, opts *gitlab.ListJobsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Job, *gitlab.Response, error)
|
ListPipelineJobs(pid interface{}, pipelineID int, opts *gitlab.ListJobsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Job, *gitlab.Response, error)
|
||||||
GetTraceFile(pid interface{}, jobID int, options ...gitlab.RequestOptionFunc) (*bytes.Reader, *gitlab.Response, error)
|
GetTraceFile(pid interface{}, jobID int, options ...gitlab.RequestOptionFunc) (*bytes.Reader, *gitlab.Response, error)
|
||||||
|
ListLabels(pid interface{}, opt *gitlab.ListLabelsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Label, *gitlab.Response, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Table of Contents *gitlab.nvim.table-of-contents*
|
|||||||
- The Summary view |gitlab.nvim.the-summary-view|
|
- The Summary view |gitlab.nvim.the-summary-view|
|
||||||
- Reviewing an MR |gitlab.nvim.reviewing-an-mr|
|
- Reviewing an MR |gitlab.nvim.reviewing-an-mr|
|
||||||
- Discussions and Notes |gitlab.nvim.discussions-and-notes|
|
- Discussions and Notes |gitlab.nvim.discussions-and-notes|
|
||||||
|
- Labels |gitlab.nvim.labels|
|
||||||
- Signs and diagnostics |gitlab.nvim.signs-and-diagnostics|
|
- Signs and diagnostics |gitlab.nvim.signs-and-diagnostics|
|
||||||
- Uploading Files |gitlab.nvim.uploading-files|
|
- Uploading Files |gitlab.nvim.uploading-files|
|
||||||
- MR Approvals |gitlab.nvim.mr-approvals|
|
- MR Approvals |gitlab.nvim.mr-approvals|
|
||||||
@@ -187,6 +188,7 @@ you call this function with no values the defaults will be used:
|
|||||||
"reviewers",
|
"reviewers",
|
||||||
"branch",
|
"branch",
|
||||||
"pipeline",
|
"pipeline",
|
||||||
|
"labels",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
discussion_sign_and_diagnostic = {
|
discussion_sign_and_diagnostic = {
|
||||||
@@ -328,6 +330,15 @@ delete/edit/reply are available on the note tree.
|
|||||||
require("gitlab").create_note()
|
require("gitlab").create_note()
|
||||||
<
|
<
|
||||||
|
|
||||||
|
LABELS *gitlab.nvim.labels*
|
||||||
|
|
||||||
|
You can add or remove labels from the current MR.
|
||||||
|
>lua
|
||||||
|
require("gitlab").add_label()
|
||||||
|
require("gitlab").delete_label()
|
||||||
|
|
||||||
|
These labels will be visible in the summary panel, as long as you provide the
|
||||||
|
"fields" string in your setup function under the `setting.info.fields` block.
|
||||||
|
|
||||||
SIGNS AND DIAGNOSTICS *gitlab.nvim.signs-and-diagnostics*
|
SIGNS AND DIAGNOSTICS *gitlab.nvim.signs-and-diagnostics*
|
||||||
|
|
||||||
@@ -681,6 +692,18 @@ Opens up a select menu for adding a reviewer for the current merge request.
|
|||||||
>lua
|
>lua
|
||||||
require("gitlab").add_reviewer()
|
require("gitlab").add_reviewer()
|
||||||
|
|
||||||
|
gitlab.add_label() *gitlab.nvim.add_label*
|
||||||
|
|
||||||
|
Opens up a select menu for adding a label to the current merge request.
|
||||||
|
>lua
|
||||||
|
require("gitlab").add_label()
|
||||||
|
|
||||||
|
gitlab.delete_label() *gitlab.nvim.delete_label*
|
||||||
|
|
||||||
|
Opens up a select menu for removing an existing label from the current merge request.
|
||||||
|
>lua
|
||||||
|
require("gitlab").delete_label()
|
||||||
|
|
||||||
gitlab.delete_reviewer() *gitlab.nvim.delete_reviewer*
|
gitlab.delete_reviewer() *gitlab.nvim.delete_reviewer*
|
||||||
|
|
||||||
Opens up a select menu for removing an existing reviewer for the current merge request.
|
Opens up a select menu for removing an existing reviewer for the current merge request.
|
||||||
|
|||||||
83
lua/gitlab/actions/labels.lua
Normal file
83
lua/gitlab/actions/labels.lua
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
-- This module is responsible for the creation, deletion,
|
||||||
|
-- and assignment and removeal of labels.
|
||||||
|
local u = require("gitlab.utils")
|
||||||
|
local job = require("gitlab.job")
|
||||||
|
local state = require("gitlab.state")
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
M.add_label = function()
|
||||||
|
M.add_popup("label")
|
||||||
|
end
|
||||||
|
|
||||||
|
M.delete_label = function()
|
||||||
|
M.delete_popup("label")
|
||||||
|
end
|
||||||
|
|
||||||
|
local refresh_label_state = function(labels)
|
||||||
|
local new_labels = ""
|
||||||
|
for _, label in ipairs(labels) do
|
||||||
|
new_labels = new_labels .. "," .. label
|
||||||
|
end
|
||||||
|
state.INFO.labels = new_labels
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_current_labels = function()
|
||||||
|
local label_string = state.INFO.labels
|
||||||
|
local current_labels = {}
|
||||||
|
for value in label_string:gmatch("[^,]+") do
|
||||||
|
table.insert(current_labels, value)
|
||||||
|
end
|
||||||
|
return current_labels
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_all_labels = function()
|
||||||
|
local labels = {}
|
||||||
|
for _, label in ipairs(state.LABELS) do -- How can we use the colors??
|
||||||
|
table.insert(labels, label.Name)
|
||||||
|
end
|
||||||
|
return labels
|
||||||
|
end
|
||||||
|
|
||||||
|
M.add_popup = function(type)
|
||||||
|
local all_labels = get_all_labels()
|
||||||
|
local current_labels = get_current_labels()
|
||||||
|
local unused_labels = u.difference(all_labels, current_labels)
|
||||||
|
vim.ui.select(unused_labels, {
|
||||||
|
prompt = "Choose label to add",
|
||||||
|
}, function(choice)
|
||||||
|
if not choice then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local label_string = state.INFO.labels
|
||||||
|
local new_labels = {}
|
||||||
|
for value in label_string:gmatch("[^,]+") do
|
||||||
|
table.insert(new_labels, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(new_labels, choice)
|
||||||
|
local body = { labels = new_labels }
|
||||||
|
job.run_job("/mr/" .. type, "PUT", body, function(data)
|
||||||
|
u.notify(data.message, vim.log.levels.INFO)
|
||||||
|
refresh_label_state(data.labels)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
M.delete_popup = function(type)
|
||||||
|
local current_labels = get_current_labels()
|
||||||
|
vim.ui.select(current_labels, {
|
||||||
|
prompt = "Choose label to delete",
|
||||||
|
}, function(choice)
|
||||||
|
if not choice then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local filtered_labels = u.filter(current_labels, choice)
|
||||||
|
local body = { labels = filtered_labels }
|
||||||
|
job.run_job("/mr/" .. type, "PUT", body, function(data)
|
||||||
|
u.notify(data.message, vim.log.levels.INFO)
|
||||||
|
refresh_label_state(data.labels)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -89,6 +89,8 @@ M.summary = function()
|
|||||||
vim.api.nvim_set_option_value("readonly", false, { buf = info_popup.bufnr })
|
vim.api.nvim_set_option_value("readonly", false, { buf = info_popup.bufnr })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.color_labels(info_popup.bufnr) -- Color labels in details popup
|
||||||
|
|
||||||
state.set_popup_keymaps(
|
state.set_popup_keymaps(
|
||||||
description_popup,
|
description_popup,
|
||||||
M.edit_summary,
|
M.edit_summary,
|
||||||
@@ -128,8 +130,9 @@ M.build_info_lines = function()
|
|||||||
assignees = { title = "Assignees", content = u.make_readable_list(info.assignees, "name") },
|
assignees = { title = "Assignees", content = u.make_readable_list(info.assignees, "name") },
|
||||||
reviewers = { title = "Reviewers", content = u.make_readable_list(info.reviewers, "name") },
|
reviewers = { title = "Reviewers", content = u.make_readable_list(info.reviewers, "name") },
|
||||||
branch = { title = "Branch", content = info.source_branch },
|
branch = { title = "Branch", content = info.source_branch },
|
||||||
|
labels = { title = "Labels", content = u.make_comma_separated_readable(info.labels) },
|
||||||
pipeline = {
|
pipeline = {
|
||||||
title = "Pipeline Status:",
|
title = "Pipeline Status",
|
||||||
content = function()
|
content = function()
|
||||||
return pipeline.get_pipeline_status()
|
return pipeline.get_pipeline_status()
|
||||||
end,
|
end,
|
||||||
@@ -230,8 +233,25 @@ M.create_layout = function(info_lines)
|
|||||||
}, internal_layout)
|
}, internal_layout)
|
||||||
|
|
||||||
layout:mount()
|
layout:mount()
|
||||||
|
|
||||||
return layout, title_popup, description_popup, details_popup
|
return layout, title_popup, description_popup, details_popup
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.color_labels = function(bufnr)
|
||||||
|
local label_namespace = vim.api.nvim_create_namespace("Labels")
|
||||||
|
for i, v in ipairs(state.settings.info.fields) do
|
||||||
|
if v == "labels" then
|
||||||
|
local line_content = u.get_line_content(bufnr, i)
|
||||||
|
vim.print(line_content)
|
||||||
|
for j, label in ipairs(state.LABELS) do
|
||||||
|
local start_idx, end_idx = line_content:find(label.Name)
|
||||||
|
if start_idx ~= nil and end_idx ~= nil then
|
||||||
|
vim.cmd("highlight " .. "label" .. j .. " guifg=white")
|
||||||
|
vim.api.nvim_set_hl(0, ("label" .. j), { fg = label.Color })
|
||||||
|
vim.api.nvim_buf_add_highlight(bufnr, label_namespace, ("label" .. j), i - 1, start_idx - 1, end_idx)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ local comment = require("gitlab.actions.comment")
|
|||||||
local pipeline = require("gitlab.actions.pipeline")
|
local pipeline = require("gitlab.actions.pipeline")
|
||||||
local create_mr = require("gitlab.actions.create_mr")
|
local create_mr = require("gitlab.actions.create_mr")
|
||||||
local approvals = require("gitlab.actions.approvals")
|
local approvals = require("gitlab.actions.approvals")
|
||||||
|
local labels = require("gitlab.actions.labels")
|
||||||
|
|
||||||
local info = state.dependencies.info
|
local info = state.dependencies.info
|
||||||
|
local labels_dep = state.dependencies.labels
|
||||||
local project_members = state.dependencies.project_members
|
local project_members = state.dependencies.project_members
|
||||||
local revisions = state.dependencies.revisions
|
local revisions = state.dependencies.revisions
|
||||||
|
|
||||||
@@ -28,11 +30,13 @@ return {
|
|||||||
discussions.initialize_discussions() -- place signs / diagnostics for discussions in reviewer
|
discussions.initialize_discussions() -- place signs / diagnostics for discussions in reviewer
|
||||||
end,
|
end,
|
||||||
-- Global Actions 🌎
|
-- Global Actions 🌎
|
||||||
summary = async.sequence({ u.merge(info, { refresh = true }) }, summary.summary),
|
summary = async.sequence({ u.merge(info, { refresh = true }), labels_dep }, summary.summary),
|
||||||
approve = async.sequence({ info }, approvals.approve),
|
approve = async.sequence({ info }, approvals.approve),
|
||||||
revoke = async.sequence({ info }, approvals.revoke),
|
revoke = async.sequence({ info }, approvals.revoke),
|
||||||
add_reviewer = async.sequence({ info, project_members }, assignees_and_reviewers.add_reviewer),
|
add_reviewer = async.sequence({ info, project_members }, assignees_and_reviewers.add_reviewer),
|
||||||
delete_reviewer = async.sequence({ info, project_members }, assignees_and_reviewers.delete_reviewer),
|
delete_reviewer = async.sequence({ info, project_members }, assignees_and_reviewers.delete_reviewer),
|
||||||
|
add_label = async.sequence({ info, labels_dep }, labels.add_label),
|
||||||
|
delete_label = async.sequence({ info, labels_dep }, labels.delete_label),
|
||||||
add_assignee = async.sequence({ info, project_members }, assignees_and_reviewers.add_assignee),
|
add_assignee = async.sequence({ info, project_members }, assignees_and_reviewers.add_assignee),
|
||||||
delete_assignee = async.sequence({ info, project_members }, assignees_and_reviewers.delete_assignee),
|
delete_assignee = async.sequence({ info, project_members }, assignees_and_reviewers.delete_assignee),
|
||||||
create_comment = async.sequence({ info, revisions }, comment.create_comment),
|
create_comment = async.sequence({ info, revisions }, comment.create_comment),
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ M.settings = {
|
|||||||
"reviewers",
|
"reviewers",
|
||||||
"branch",
|
"branch",
|
||||||
"pipeline",
|
"pipeline",
|
||||||
|
"labels",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
discussion_sign_and_diagnostic = {
|
discussion_sign_and_diagnostic = {
|
||||||
@@ -293,6 +294,7 @@ end
|
|||||||
-- adding a reviewer) requires some initial state.
|
-- adding a reviewer) requires some initial state.
|
||||||
M.dependencies = {
|
M.dependencies = {
|
||||||
info = { endpoint = "/mr/info", key = "info", state = "INFO", refresh = false },
|
info = { endpoint = "/mr/info", key = "info", state = "INFO", refresh = false },
|
||||||
|
labels = { endpoint = "/mr/label", key = "labels", state = "LABELS", refresh = false },
|
||||||
revisions = { endpoint = "/mr/revisions", key = "Revisions", state = "MR_REVISIONS", refresh = false },
|
revisions = { endpoint = "/mr/revisions", key = "Revisions", state = "MR_REVISIONS", refresh = false },
|
||||||
project_members = {
|
project_members = {
|
||||||
endpoint = "/project/members",
|
endpoint = "/project/members",
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ M.get_last_word = function(sentence, divider)
|
|||||||
return words[#words] or ""
|
return words[#words] or ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.filter = function(input_table, value_to_remove)
|
||||||
|
local resultTable = {}
|
||||||
|
for _, v in ipairs(input_table) do
|
||||||
|
if v ~= value_to_remove then
|
||||||
|
table.insert(resultTable, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return resultTable
|
||||||
|
end
|
||||||
|
|
||||||
---Merges two deeply nested tables together, overriding values from the first with conflicts
|
---Merges two deeply nested tables together, overriding values from the first with conflicts
|
||||||
---@param defaults table The first table
|
---@param defaults table The first table
|
||||||
---@param overrides table The second table
|
---@param overrides table The second table
|
||||||
@@ -328,6 +338,22 @@ M.format_date = function(date_string)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.difference = function(a, b)
|
||||||
|
local set_b = {}
|
||||||
|
for _, val in ipairs(b) do
|
||||||
|
set_b[val] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local not_included = {}
|
||||||
|
for _, val in ipairs(a) do
|
||||||
|
if not set_b[val] then
|
||||||
|
table.insert(not_included, val)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return not_included
|
||||||
|
end
|
||||||
|
|
||||||
M.jump_to_file = function(filename, line_number)
|
M.jump_to_file = function(filename, line_number)
|
||||||
if line_number == nil then
|
if line_number == nil then
|
||||||
line_number = 1
|
line_number = 1
|
||||||
@@ -637,6 +663,10 @@ M.get_icon = function(filename)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.make_comma_separated_readable = function(str)
|
||||||
|
return string.gsub(str, ",", ", ")
|
||||||
|
end
|
||||||
|
|
||||||
---@param remote? boolean
|
---@param remote? boolean
|
||||||
M.get_all_git_branches = function(remote)
|
M.get_all_git_branches = function(remote)
|
||||||
local branches = {}
|
local branches = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user