Release 2.5.1 (#271)
* feat: Support for custom authentication provider functions (#270) * feat: Support for adding "draft" notes to the review, and publishing them, either individually or all at once. Addresses feature request #223. * feat: Lets users select + checkout a merge request directly within Neovim, without exiting to the terminal * fix: Checks that the remote feature branch exists and is up-to-date before creating a MR, starting a review, or opening the MR summary (#278) * docs: We require some state from Diffview, this shows how to load that state prior to installing w/ Packer. Fixes #94. This is a #MINOR release. --------- Co-authored-by: Jakub F. Bortlík <jakub.bortlik@proton.me> Co-authored-by: sunfuze <sunfuze.1989@gmail.com> Co-authored-by: Patrick Pichler <mail@patrickpichler.dev>
This commit is contained in:
committed by
GitHub
parent
f10c4ebb8f
commit
cf6ccddce3
@@ -5,30 +5,57 @@ local List = require("gitlab.utils.list")
|
||||
|
||||
local M = {}
|
||||
|
||||
---@class NoteWithValues
|
||||
---@field position NotePosition
|
||||
---@field resolvable boolean|nil
|
||||
---@field resolved boolean|nil
|
||||
---@field created_at string|nil
|
||||
|
||||
---@param note NoteWithValues
|
||||
---@param file string
|
||||
---@return boolean
|
||||
local filter_discussions_and_notes = function(note, file)
|
||||
---Do not include unlinked notes
|
||||
return note.position ~= nil
|
||||
and (note.position.new_path == file or note.position.old_path == file)
|
||||
---Skip resolved discussions if user wants to
|
||||
and not (state.settings.discussion_signs.skip_resolved_discussion and note.resolvable and note.resolved)
|
||||
---Skip discussions from old revisions
|
||||
and not (
|
||||
state.settings.discussion_signs.skip_old_revision_discussion
|
||||
and u.from_iso_format_date_to_timestamp(note.created_at)
|
||||
<= u.from_iso_format_date_to_timestamp(state.MR_REVISIONS[1].created_at)
|
||||
)
|
||||
end
|
||||
|
||||
---Filter all discussions which are relevant for currently visible signs and diagnostics.
|
||||
---@return Discussion[]
|
||||
M.filter_placeable_discussions = function(all_discussions)
|
||||
if type(all_discussions) ~= "table" then
|
||||
return {}
|
||||
---@return Discussion|DraftNote[]
|
||||
M.filter_placeable_discussions = function()
|
||||
local discussions = u.ensure_table(state.DISCUSSION_DATA and state.DISCUSSION_DATA.discussions or {})
|
||||
if type(discussions) ~= "table" then
|
||||
discussions = {}
|
||||
end
|
||||
|
||||
local draft_notes = u.ensure_table(state.DRAFT_NOTES)
|
||||
if type(draft_notes) ~= "table" then
|
||||
draft_notes = {}
|
||||
end
|
||||
|
||||
local file = reviewer.get_current_file()
|
||||
if not file then
|
||||
return {}
|
||||
end
|
||||
return List.new(all_discussions):filter(function(discussion)
|
||||
|
||||
local filtered_discussions = List.new(discussions):filter(function(discussion)
|
||||
local first_note = discussion.notes[1]
|
||||
return type(first_note.position) == "table"
|
||||
--Do not include unlinked notes
|
||||
and (first_note.position.new_path == file or first_note.position.old_path == file)
|
||||
--Skip resolved discussions if user wants to
|
||||
and not (state.settings.discussion_signs.skip_resolved_discussion and first_note.resolvable and first_note.resolved)
|
||||
--Skip discussions from old revisions
|
||||
and not (
|
||||
state.settings.discussion_signs.skip_old_revision_discussion
|
||||
and u.from_iso_format_date_to_timestamp(first_note.created_at)
|
||||
<= u.from_iso_format_date_to_timestamp(state.MR_REVISIONS[1].created_at)
|
||||
)
|
||||
return type(first_note.position) == "table" and filter_discussions_and_notes(first_note, file)
|
||||
end)
|
||||
|
||||
local filtered_draft_notes = List.new(draft_notes):filter(function(note)
|
||||
return filter_discussions_and_notes(note, file)
|
||||
end)
|
||||
|
||||
return u.join(filtered_discussions, filtered_draft_notes)
|
||||
end
|
||||
|
||||
M.parse_line_code = function(line_code)
|
||||
@@ -37,24 +64,24 @@ M.parse_line_code = function(line_code)
|
||||
return tonumber(old_line), tonumber(new_line)
|
||||
end
|
||||
|
||||
---@param discussion Discussion
|
||||
---@param d_or_n Discussion|DraftNote
|
||||
---@return boolean
|
||||
M.is_old_sha = function(discussion)
|
||||
local first_note = discussion.notes[1]
|
||||
M.is_old_sha = function(d_or_n)
|
||||
local first_note = M.get_first_note(d_or_n)
|
||||
return first_note.position.old_line ~= nil
|
||||
end
|
||||
|
||||
---@param discussion Discussion
|
||||
---@param discussion Discussion|DraftNote
|
||||
---@return boolean
|
||||
M.is_new_sha = function(discussion)
|
||||
return not M.is_old_sha(discussion)
|
||||
end
|
||||
|
||||
---@param discussion Discussion
|
||||
---@param d_or_n Discussion|DraftNote
|
||||
---@return boolean
|
||||
M.is_single_line = function(discussion)
|
||||
local first_note = discussion.notes[1]
|
||||
local line_range = first_note.position.line_range
|
||||
M.is_single_line = function(d_or_n)
|
||||
local first_note = M.get_first_note(d_or_n)
|
||||
local line_range = first_note.position and first_note.position.line_range
|
||||
return line_range == nil
|
||||
end
|
||||
|
||||
@@ -64,10 +91,10 @@ M.is_multi_line = function(discussion)
|
||||
return not M.is_single_line(discussion)
|
||||
end
|
||||
|
||||
---@param discussion Discussion
|
||||
---@return Note
|
||||
M.get_first_note = function(discussion)
|
||||
return discussion.notes[1]
|
||||
---@param d_or_n Discussion|DraftNote
|
||||
---@return Note|DraftNote
|
||||
M.get_first_note = function(d_or_n)
|
||||
return d_or_n.notes and d_or_n.notes[1] or d_or_n
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local u = require("gitlab.utils")
|
||||
local diffview_lib = require("diffview.lib")
|
||||
local discussion_tree = require("gitlab.actions.discussions.tree")
|
||||
local common = require("gitlab.indicators.common")
|
||||
local indicators_common = require("gitlab.indicators.common")
|
||||
local actions_common = require("gitlab.actions.common")
|
||||
local List = require("gitlab.utils.list")
|
||||
local state = require("gitlab.state")
|
||||
local discussion_sign_name = "gitlab_discussion"
|
||||
@@ -24,19 +24,23 @@ local display_opts = {
|
||||
---Takes some range information and data about a discussion
|
||||
---and creates a diagnostic to be placed in the reviewer
|
||||
---@param range_info table
|
||||
---@param discussion Discussion
|
||||
---@param d_or_n Discussion|DraftNote
|
||||
---@return Diagnostic
|
||||
local function create_diagnostic(range_info, discussion)
|
||||
local message = ""
|
||||
for _, note in ipairs(discussion.notes) do
|
||||
message = message .. discussion_tree.build_note_header(note) .. "\n" .. note.body .. "\n"
|
||||
local function create_diagnostic(range_info, d_or_n)
|
||||
local first_note = indicators_common.get_first_note(d_or_n)
|
||||
local header = actions_common.build_note_header(first_note)
|
||||
local message = header
|
||||
if d_or_n.notes then
|
||||
for _, note in ipairs(d_or_n.notes or {}) do
|
||||
message = message .. actions_common.build_note_header(note) .. "\n" .. note.body .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
local diagnostic = {
|
||||
message = message,
|
||||
col = 0,
|
||||
severity = state.settings.discussion_signs.severity,
|
||||
user_data = { discussion_id = discussion.id, header = discussion_tree.build_note_header(discussion.notes[1]) },
|
||||
user_data = { discussion_id = d_or_n.id, header = header },
|
||||
source = "gitlab",
|
||||
code = "gitlab.nvim",
|
||||
}
|
||||
@@ -44,38 +48,37 @@ local function create_diagnostic(range_info, discussion)
|
||||
end
|
||||
|
||||
---Creates a single line diagnostic
|
||||
---@param discussion Discussion
|
||||
---@param d_or_n Discussion|DraftNote
|
||||
---@return Diagnostic
|
||||
local create_single_line_diagnostic = function(discussion)
|
||||
local first_note = discussion.notes[1]
|
||||
local linnr = (common.is_new_sha(discussion) and first_note.position.new_line or first_note.position.old_line) or 1
|
||||
local create_single_line_diagnostic = function(d_or_n)
|
||||
local linnr = actions_common.get_line_number(d_or_n.id)
|
||||
return create_diagnostic({
|
||||
lnum = linnr - 1,
|
||||
}, discussion)
|
||||
}, d_or_n)
|
||||
end
|
||||
|
||||
---Creates a mutli-line line diagnostic
|
||||
---@param discussion Discussion
|
||||
---@param d_or_n Discussion|DraftNote
|
||||
---@return Diagnostic
|
||||
local create_multiline_diagnostic = function(discussion)
|
||||
local first_note = discussion.notes[1]
|
||||
local create_multiline_diagnostic = function(d_or_n)
|
||||
local first_note = indicators_common.get_first_note(d_or_n)
|
||||
local line_range = first_note.position.line_range
|
||||
if line_range == nil then
|
||||
error("Parsing multi-line comment but note does not contain line range")
|
||||
end
|
||||
|
||||
local start_old_line, start_new_line = common.parse_line_code(line_range.start.line_code)
|
||||
local start_old_line, start_new_line = indicators_common.parse_line_code(line_range.start.line_code)
|
||||
|
||||
if common.is_new_sha(discussion) then
|
||||
if indicators_common.is_new_sha(d_or_n) then
|
||||
return create_diagnostic({
|
||||
lnum = start_new_line - 1,
|
||||
end_lnum = first_note.position.new_line - 1,
|
||||
}, discussion)
|
||||
}, d_or_n)
|
||||
else
|
||||
return create_diagnostic({
|
||||
lnum = start_old_line - 1,
|
||||
end_lnum = first_note.position.old_line - 1,
|
||||
}, discussion)
|
||||
}, d_or_n)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -106,12 +109,11 @@ local set_diagnostics_in_old_sha = function(namespace, diagnostics, opts)
|
||||
end
|
||||
|
||||
---Refresh the diagnostics for the currently reviewed file
|
||||
---@param discussions Discussion[]
|
||||
M.refresh_diagnostics = function(discussions)
|
||||
M.refresh_diagnostics = function()
|
||||
local ok, err = pcall(function()
|
||||
require("gitlab.indicators.signs").clear_signs()
|
||||
M.clear_diagnostics()
|
||||
local filtered_discussions = common.filter_placeable_discussions(discussions)
|
||||
local filtered_discussions = indicators_common.filter_placeable_discussions()
|
||||
if filtered_discussions == nil then
|
||||
return
|
||||
end
|
||||
@@ -133,9 +135,9 @@ end
|
||||
---@param discussions Discussion[]
|
||||
---@return DiagnosticTable[]
|
||||
M.parse_new_diagnostics = function(discussions)
|
||||
local new_diagnostics = List.new(discussions):filter(common.is_new_sha)
|
||||
local single_line = new_diagnostics:filter(common.is_single_line):map(create_single_line_diagnostic)
|
||||
local multi_line = new_diagnostics:filter(common.is_multi_line):map(create_multiline_diagnostic)
|
||||
local new_diagnostics = List.new(discussions):filter(indicators_common.is_new_sha)
|
||||
local single_line = new_diagnostics:filter(indicators_common.is_single_line):map(create_single_line_diagnostic)
|
||||
local multi_line = new_diagnostics:filter(indicators_common.is_multi_line):map(create_multiline_diagnostic)
|
||||
return u.combine(single_line, multi_line)
|
||||
end
|
||||
|
||||
@@ -144,9 +146,9 @@ end
|
||||
---@param discussions Discussion[]
|
||||
---@return DiagnosticTable[]
|
||||
M.parse_old_diagnostics = function(discussions)
|
||||
local old_diagnostics = List.new(discussions):filter(common.is_old_sha)
|
||||
local single_line = old_diagnostics:filter(common.is_single_line):map(create_single_line_diagnostic)
|
||||
local multi_line = old_diagnostics:filter(common.is_multi_line):map(create_multiline_diagnostic)
|
||||
local old_diagnostics = List.new(discussions):filter(indicators_common.is_old_sha)
|
||||
local single_line = old_diagnostics:filter(indicators_common.is_single_line):map(create_single_line_diagnostic)
|
||||
local multi_line = old_diagnostics:filter(indicators_common.is_multi_line):map(create_multiline_diagnostic)
|
||||
return u.combine(single_line, multi_line)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user