Feat: Adds Ability to Merge MR (#147)
This adds the ability to merge an MR from within `gitlab.nvim` directly. If the reviewer is open, it'll be closed automatically. Users may configure whether they'd like to squash commits on the merge, as well as whether they'd like to delete the original source branch on a merge. If squashing, users are prompted to provide an optional custom squash message for the squash commit.
This commit is contained in:
committed by
GitHub
parent
e254100a72
commit
64b36ac51d
55
lua/gitlab/actions/merge.lua
Normal file
55
lua/gitlab/actions/merge.lua
Normal file
@@ -0,0 +1,55 @@
|
||||
local u = require("gitlab.utils")
|
||||
local Popup = require("nui.popup")
|
||||
local state = require("gitlab.state")
|
||||
local job = require("gitlab.job")
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
|
||||
local M = {}
|
||||
|
||||
local function create_squash_message_popup()
|
||||
return Popup(u.create_popup_state("Squash Commit Message", state.settings.popup.squash_message))
|
||||
end
|
||||
|
||||
---@class MergeOpts
|
||||
---@field delete_branch boolean?
|
||||
---@field squash boolean?
|
||||
---@field squash_message string?
|
||||
|
||||
---@param opts MergeOpts
|
||||
M.merge = function(opts)
|
||||
local merge_body = { squash = state.settings.merge.squash, delete_branch = state.settings.merge.delete_branch }
|
||||
if opts then
|
||||
merge_body.squash = opts.squash ~= nil and opts.squash
|
||||
merge_body.delete_branch = opts.delete_branch ~= nil and opts.delete_branch
|
||||
end
|
||||
|
||||
if state.INFO.detailed_merge_status ~= "mergeable" then
|
||||
u.notify(string.format("MR not mergeable, currently '%s'", state.INFO.detailed_merge_status), vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
if merge_body.squash then
|
||||
local squash_message_popup = create_squash_message_popup()
|
||||
squash_message_popup:mount()
|
||||
state.set_popup_keymaps(squash_message_popup, function(text)
|
||||
M.confirm_merge(merge_body, text)
|
||||
end)
|
||||
else
|
||||
M.confirm_merge(merge_body)
|
||||
end
|
||||
end
|
||||
|
||||
---@param merge_body MergeOpts
|
||||
---@param squash_message string?
|
||||
M.confirm_merge = function(merge_body, squash_message)
|
||||
if squash_message ~= nil then
|
||||
merge_body.squash_message = squash_message
|
||||
end
|
||||
|
||||
job.run_job("/merge", "POST", merge_body, function(data)
|
||||
reviewer.close()
|
||||
u.notify(data.message, vim.log.levels.INFO)
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -122,7 +122,7 @@ M.build_info_lines = function()
|
||||
author = { title = "Author", content = "@" .. info.author.username .. " (" .. info.author.name .. ")" },
|
||||
created_at = { title = "Created", content = u.format_to_local(info.created_at, vim.fn.strftime("%z")) },
|
||||
updated_at = { title = "Updated", content = u.format_to_local(info.updated_at, vim.fn.strftime("%z")) },
|
||||
merge_status = { title = "Status", content = info.detailed_merge_status },
|
||||
detailed_merge_status = { title = "Status", content = info.detailed_merge_status },
|
||||
draft = { title = "Draft", content = (info.draft and "Yes" or "No") },
|
||||
conflicts = { title = "Merge Conflicts", content = (info.has_conflicts and "Yes" or "No") },
|
||||
assignees = { title = "Assignees", content = u.make_readable_list(info.assignees, "name") },
|
||||
@@ -138,6 +138,9 @@ M.build_info_lines = function()
|
||||
|
||||
local longest_used = ""
|
||||
for _, v in ipairs(state.settings.info.fields) do
|
||||
if v == "merge_status" then
|
||||
v = "detailed_merge_status"
|
||||
end -- merge_status was deprecated, see https://gitlab.com/gitlab-org/gitlab/-/issues/3169#note_1162532204
|
||||
local title = options[v].title
|
||||
if string.len(title) > string.len(longest_used) then
|
||||
longest_used = title
|
||||
@@ -151,6 +154,9 @@ M.build_info_lines = function()
|
||||
|
||||
local lines = {}
|
||||
for _, v in ipairs(state.settings.info.fields) do
|
||||
if v == "merge_status" then
|
||||
v = "detailed_merge_status"
|
||||
end
|
||||
local row = options[v]
|
||||
local line = "* " .. row.title .. row_offset(row.title)
|
||||
if type(row.content) == "function" then
|
||||
|
||||
@@ -4,6 +4,7 @@ local server = require("gitlab.server")
|
||||
local state = require("gitlab.state")
|
||||
local reviewer = require("gitlab.reviewer")
|
||||
local discussions = require("gitlab.actions.discussions")
|
||||
local merge = require("gitlab.actions.merge")
|
||||
local summary = require("gitlab.actions.summary")
|
||||
local assignees_and_reviewers = require("gitlab.actions.assignees_and_reviewers")
|
||||
local comment = require("gitlab.actions.comment")
|
||||
@@ -27,7 +28,7 @@ return {
|
||||
discussions.initialize_discussions() -- place signs / diagnostics for discussions in reviewer
|
||||
end,
|
||||
-- Global Actions 🌎
|
||||
summary = async.sequence({ info }, summary.summary),
|
||||
summary = async.sequence({ u.merge(info, { refresh = true }) }, summary.summary),
|
||||
approve = async.sequence({ info }, approvals.approve),
|
||||
revoke = async.sequence({ info }, approvals.revoke),
|
||||
add_reviewer = async.sequence({ info, project_members }, assignees_and_reviewers.add_reviewer),
|
||||
@@ -42,7 +43,11 @@ return {
|
||||
review = async.sequence({ u.merge(info, { refresh = true }), revisions }, function()
|
||||
reviewer.open()
|
||||
end),
|
||||
close_review = function()
|
||||
reviewer.close()
|
||||
end,
|
||||
pipeline = async.sequence({ info }, pipeline.open),
|
||||
merge = async.sequence({ u.merge(info, { refresh = true }) }, merge.merge),
|
||||
-- Discussion Tree Actions 🌴
|
||||
toggle_discussions = async.sequence({ info }, discussions.toggle),
|
||||
edit_comment = async.sequence({ info }, discussions.edit_comment),
|
||||
|
||||
@@ -47,6 +47,12 @@ M.open = function()
|
||||
end
|
||||
end
|
||||
|
||||
M.close = function()
|
||||
vim.cmd("DiffviewClose")
|
||||
local discussions = require("gitlab.actions.discussions")
|
||||
discussions.close()
|
||||
end
|
||||
|
||||
M.jump = function(file_name, new_line, old_line)
|
||||
if M.tabnr == nil then
|
||||
u.notify("Can't jump to Diffvew. Is it open?", vim.log.levels.ERROR)
|
||||
|
||||
@@ -22,6 +22,9 @@ M.init = function()
|
||||
M.open = reviewer.open
|
||||
-- Opens the reviewer window
|
||||
|
||||
M.close = reviewer.close
|
||||
-- Closes the reviewer and cleans up
|
||||
|
||||
M.jump = reviewer.jump
|
||||
-- Jumps to the location provided in the reviewer window
|
||||
-- Parameters:
|
||||
|
||||
@@ -29,6 +29,7 @@ M.settings = {
|
||||
note = nil,
|
||||
help = nil,
|
||||
pipeline = nil,
|
||||
squash_message = nil,
|
||||
},
|
||||
discussion_tree = {
|
||||
auto_open = true,
|
||||
@@ -66,6 +67,10 @@ M.settings = {
|
||||
return " " .. discussions_content .. " %#Comment#| " .. notes_content
|
||||
end,
|
||||
},
|
||||
merge = {
|
||||
squash = false,
|
||||
delete_branch = false,
|
||||
},
|
||||
info = {
|
||||
enabled = true,
|
||||
horizontal = false,
|
||||
|
||||
Reference in New Issue
Block a user