BREAKING CHANGE: Setup refactor and code cleanup
This MR makes several major tweaks to the codebase. Primarily it adjusts the setup steps for the application so that rather than providing just the project ID in the `.gitlab.nvim` file, users can also provide a vareity of other settings, such as auth_token, base_branch, and so forth. This is to make the project more extensible in the future. This MR also fixes a variety of issues with error handling in the code, primarily in the request/response model between the Lua jobs and the Golang server. BREAKING CHANGE: Modifies `.gitlab.nvim` and setup steps
This commit is contained in:
committed by
Harrison Cramer
parent
ade9f81426
commit
4f0d4b49ef
@@ -55,8 +55,9 @@ M.confirm_create_comment = function(text)
|
||||
end
|
||||
end
|
||||
|
||||
local json = string.format('{ "line_number": %d, "file_name": "%s", "comment": "%s" }', current_line_number,
|
||||
relative_file_path, text)
|
||||
local jsonTable = { line_number = current_line_number, file_name = relative_file_path, comment = text }
|
||||
local json = vim.json.encode(jsonTable)
|
||||
|
||||
job.run_job("comment", "POST", json)
|
||||
end
|
||||
|
||||
@@ -105,10 +106,11 @@ M.delete_comment = function()
|
||||
end
|
||||
local discussion_id = node:get_id()
|
||||
discussion_id = string.sub(discussion_id, 2) -- Remove the "-" at the start
|
||||
note_id = string.sub(note_id, 2) -- Remove the "-" at the start
|
||||
note_id = tonumber(string.sub(note_id, 2)) -- Remove the "-" at the start
|
||||
|
||||
local jsonTable = { discussion_id = discussion_id, note_id = note_id }
|
||||
local json = vim.json.encode(jsonTable)
|
||||
|
||||
local json = string.format('{"discussion_id": "%s", "note_id": %d}', discussion_id, note_id)
|
||||
job.run_job("comment", "DELETE", json, function(data)
|
||||
vim.notify(data.message, vim.log.levels.INFO)
|
||||
state.tree:remove_node("-" .. note_id)
|
||||
@@ -136,9 +138,9 @@ M.edit_comment = function()
|
||||
|
||||
editPopup:mount()
|
||||
|
||||
local note_id = string.sub(node:get_id(), 2) -- Remove the "-" at the start
|
||||
local note_id = tonumber(string.sub(node:get_id(), 2)) -- Remove the "-" at the start
|
||||
local discussion_id = node:get_parent_id()
|
||||
discussion_id = string.sub(discussion_id, 2) -- Remove the "-" at the start
|
||||
discussion_id = string.sub(discussion_id, 2) -- Remove the "-" at the start
|
||||
|
||||
state.ACTIVE_DISCUSSION = discussion_id
|
||||
state.ACTIVE_NOTE = note_id
|
||||
@@ -157,8 +159,9 @@ end
|
||||
|
||||
M.send_edits = function(text)
|
||||
local escapedText = string.gsub(text, "\n", "\\n")
|
||||
local json = string.format('{"discussion_id": "%s", "note_id": %s, "comment": "%s"}', state.ACTIVE_DISCUSSION,
|
||||
state.ACTIVE_NOTE, escapedText)
|
||||
|
||||
local jsonTable = { discussion_id = state.ACTIVE_DISCUSSION, note_id = state.ACTIVE_NOTE, comment = escapedText }
|
||||
local json = vim.json.encode(jsonTable)
|
||||
|
||||
job.run_job("comment", "PATCH", json, function()
|
||||
vim.schedule(function()
|
||||
|
||||
@@ -18,7 +18,10 @@ end
|
||||
|
||||
M.send_reply = function(text)
|
||||
local escapedText = string.gsub(text, "\n", "\\n")
|
||||
local json = string.format('{"discussion_id": "%s", "reply": "%s"}', state.ACTIVE_DISCUSSION, escapedText)
|
||||
|
||||
local jsonTable = { discussion_id = state.ACTIVE_DISCUSSION, reply = escapedText }
|
||||
local json = vim.json.encode(jsonTable)
|
||||
|
||||
job.run_job("reply", "POST", json, function(data)
|
||||
local note_node = M.build_note(data.note)
|
||||
note_node:expand()
|
||||
|
||||
@@ -18,8 +18,68 @@ M.edit_comment = comment.edit_comment
|
||||
M.delete_comment = comment.delete_comment
|
||||
M.reply = discussions.reply
|
||||
|
||||
-- Builds the binary (if not built); starts the Go server; calls the /info endpoint,
|
||||
-- which sets the Gitlab project's information in gitlab.nvim's INFO module
|
||||
M.setup = function(args)
|
||||
if args == nil then args = {} end
|
||||
local file_path = u.current_file_path()
|
||||
local parent_dir = vim.fn.fnamemodify(file_path, ":h:h:h:h")
|
||||
state.BIN_PATH = parent_dir
|
||||
state.BIN = parent_dir .. "/bin"
|
||||
|
||||
local binary_exists = vim.loop.fs_stat(state.BIN)
|
||||
if binary_exists == nil then M.build() end
|
||||
|
||||
if not M.setPluginState(args) then return end -- Return if not a valid gitlab project
|
||||
|
||||
local command = state.BIN
|
||||
.. " "
|
||||
.. state.PROJECT_ID
|
||||
.. " "
|
||||
.. state.GITLAB_URL
|
||||
.. " "
|
||||
.. state.PORT
|
||||
.. " "
|
||||
.. state.AUTH_TOKEN
|
||||
.. " "
|
||||
.. state.LOG_PATH
|
||||
|
||||
vim.fn.jobstart(
|
||||
command,
|
||||
{
|
||||
on_stdout = function(job_id)
|
||||
if job_id <= 0 then
|
||||
vim.notify("Could not start gitlab.nvim binary", vim.log.levels.ERROR)
|
||||
return
|
||||
else
|
||||
local response_ok, response = pcall(
|
||||
curl.get,
|
||||
"localhost:" .. state.PORT .. "/info",
|
||||
{ timeout = 750 }
|
||||
)
|
||||
if response == nil or not response_ok then
|
||||
vim.notify("The gitlab.nvim server did not respond", vim.log.levels.ERROR)
|
||||
print("Ran command: " .. command)
|
||||
return
|
||||
end
|
||||
local body = response.body
|
||||
local parsed_ok, data = pcall(vim.json.decode, body)
|
||||
if parsed_ok ~= true then
|
||||
vim.notify("The gitlab.nvim server returned an invalid response to the /info endpoint",
|
||||
vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
state.INFO = data
|
||||
keymaps.set_keymap_keys(args.keymaps)
|
||||
keymaps.set_keymaps()
|
||||
end
|
||||
end,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
-- Builds the Go binary
|
||||
local function build_binary()
|
||||
M.build = function()
|
||||
local command = string.format("cd %s && make", state.BIN_PATH)
|
||||
local installCode = os.execute(command .. "> /dev/null")
|
||||
if installCode ~= 0 then
|
||||
@@ -29,76 +89,61 @@ local function build_binary()
|
||||
return true
|
||||
end
|
||||
|
||||
M.build = build_binary
|
||||
|
||||
-- Setups up the binary (if not built), starts the Go server, and calls the /info endpoint,
|
||||
-- which sets the Gitlab project's information in gitlab.nvim's state module
|
||||
M.setup = function(args)
|
||||
local file_path = u.current_file_path()
|
||||
local parent_dir = vim.fn.fnamemodify(file_path, ":h:h:h:h")
|
||||
state.BIN_PATH = parent_dir
|
||||
state.BIN = parent_dir .. "/bin"
|
||||
|
||||
if args == nil then args = {} end
|
||||
|
||||
local binary_exists = vim.loop.fs_stat(state.BIN)
|
||||
if binary_exists == nil then
|
||||
build_binary()
|
||||
end
|
||||
|
||||
-- Initializes state for the project based on the arguments
|
||||
-- provided in the `.gitlab.nvim` file per project, and the args provided in the setup function
|
||||
M.setPluginState = function(args)
|
||||
local config_file_path = vim.fn.getcwd() .. "/.gitlab.nvim"
|
||||
local config_file_content = u.read_file(config_file_path)
|
||||
if config_file_content == nil then
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
state.PROJECT_ID = config_file_content
|
||||
if state.PROJECT_ID == nil then
|
||||
error("No project ID provided!")
|
||||
local file = assert(io.open(config_file_path, "r"))
|
||||
local property = {}
|
||||
for line in file:lines() do
|
||||
for key, value in string.gmatch(line, "(.-)=(.-)$") do
|
||||
property[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
if type(tonumber(state.PROJECT_ID)) ~= 'number' then
|
||||
error("The .gitlab.nvim project file may only contain a project number")
|
||||
end
|
||||
local project_id = property["project_id"]
|
||||
local gitlab_url = property["gitlab_url"]
|
||||
local base_branch = property["base_branch"]
|
||||
local auth_token = property["auth_token"]
|
||||
|
||||
if args.base_branch ~= nil then
|
||||
state.BASE_BRANCH = args.base_branch
|
||||
end
|
||||
state.PROJECT_ID = project_id
|
||||
state.AUTH_TOKEN = auth_token or os.getenv("GITLAB_TOKEN")
|
||||
state.GITLAB_URL = gitlab_url or "https://gitlab.com"
|
||||
state.BASE_BRANCH = base_branch or "main"
|
||||
|
||||
local current_branch_raw = io.popen("git rev-parse --abbrev-ref HEAD"):read("*a")
|
||||
local current_branch = string.gsub(current_branch_raw, "\n", "")
|
||||
|
||||
if current_branch == state.BASE_BRANCH then
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
if u.is_gitlab_repo() then
|
||||
state.PORT = args.port or 21036
|
||||
vim.fn.jobstart(state.BIN .. " " .. state.PROJECT_ID .. " " .. state.PORT, {
|
||||
on_stdout = function(job_id)
|
||||
if job_id <= 0 then
|
||||
vim.notify("Could not start gitlab.nvim binary", vim.log.levels.ERROR)
|
||||
return
|
||||
else
|
||||
local response_ok, response = pcall(curl.get, "localhost:" .. state.PORT .. "/info",
|
||||
{ timeout = 750 })
|
||||
if response == nil or not response_ok then
|
||||
vim.notify("The gitlab.nvim server did not respond", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
local body = response.body
|
||||
local parsed_ok, data = pcall(vim.json.decode, body)
|
||||
if parsed_ok ~= true then
|
||||
vim.notify("The gitlab.nvim server returned an invalid response to the /info endpoint", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
state.INFO = data
|
||||
keymaps.set_keymap_keys(args.keymaps)
|
||||
keymaps.set_keymaps()
|
||||
end
|
||||
end
|
||||
})
|
||||
if state.AUTH_TOKEN == nil then
|
||||
error("Missing authentication token for Gitlab")
|
||||
end
|
||||
|
||||
if state.AUTH_TOKEN == nil then
|
||||
error("Missing authentication token for Gitlab")
|
||||
end
|
||||
|
||||
if state.PROJECT_ID == nil then
|
||||
error("Missing project ID in .gitlab.nvim file.")
|
||||
end
|
||||
|
||||
if type(tonumber(state.PROJECT_ID)) ~= "number" then
|
||||
error("The .gitlab.nvim project file's 'project_id' must be number")
|
||||
end
|
||||
|
||||
-- Configuration for the plugin, such as port of server
|
||||
state.PORT = args.port or 21036
|
||||
state.LOG_PATH = args.log_path or (vim.fn.stdpath("cache") .. "/gitlab.nvim.log")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -9,25 +9,31 @@ M.run_job = function(endpoint, method, body, callback)
|
||||
table.insert(args, 1, "-d")
|
||||
table.insert(args, 2, body)
|
||||
end
|
||||
|
||||
-- This handler will handle all responses from the Go server. Anything with a successful
|
||||
-- status will call the callback (if it is supplied for the job). Otherwise, it will print out the
|
||||
-- success message or error message and details from the Go server.
|
||||
Job:new({
|
||||
command = "curl",
|
||||
args = args,
|
||||
on_stdout = function(_, output)
|
||||
local data_ok, data = pcall(vim.json.decode, output)
|
||||
if data_ok and data ~= nil then
|
||||
local status = (data.status >= 200 and data.status < 300) and "success" or "error"
|
||||
if callback ~= nil then
|
||||
callback(data)
|
||||
vim.defer_fn(function()
|
||||
local data_ok, data = pcall(vim.json.decode, output)
|
||||
if data_ok and data ~= nil then
|
||||
local status = (data.status >= 200 and data.status < 300) and "success" or "error"
|
||||
if status == "success" and callback ~= nil then
|
||||
callback(data)
|
||||
elseif status == "success" then
|
||||
local message = string.format("%s", data.message)
|
||||
vim.notify(message, vim.log.levels.INFO)
|
||||
else
|
||||
local message = string.format("%s: %s", data.message, data.details)
|
||||
vim.notify(message, vim.log.levels.DEBUG)
|
||||
end
|
||||
else
|
||||
vim.defer_fn(function()
|
||||
vim.notify(data.message, vim.log.levels.DEBUG)
|
||||
end, 0)
|
||||
end
|
||||
else
|
||||
vim.defer_fn(function()
|
||||
vim.notify("Could not parse command output!", vim.log.levels.ERROR)
|
||||
end, 0)
|
||||
end
|
||||
end
|
||||
end, 0)
|
||||
end,
|
||||
on_stderr = function(_, output)
|
||||
vim.defer_fn(function()
|
||||
|
||||
@@ -87,7 +87,9 @@ local base_invalid = function()
|
||||
local base = state.BASE_BRANCH
|
||||
local hasBaseBranch = feature_branch_exists(base)
|
||||
if not hasBaseBranch then
|
||||
vim.notify('No base branch. If this is a Gitlab repository, please check your setup function!', vim.log.levels.ERROR)
|
||||
vim.notify(
|
||||
'Could not fetch feature branch. Please check that you have the correct base_branch value set in your .gitlab.nvim configuration file',
|
||||
vim.log.levels.ERROR)
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -107,29 +109,6 @@ local add_comment_sign = function(line_number)
|
||||
vim.fn.sign_place(0, "piet", "piet", bufnr, { lnum = line_number })
|
||||
end
|
||||
|
||||
local function is_gitlab_repo()
|
||||
local current_dir = vim.fn.getcwd()
|
||||
|
||||
-- check if it contains a .git folder
|
||||
local git_dir = current_dir .. "/.git"
|
||||
if vim.fn.isdirectory(git_dir) == 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
local git_cmd = 'git remote get-url origin'
|
||||
local handle = io.popen(git_cmd)
|
||||
local result = handle:read("*a")
|
||||
handle:close()
|
||||
|
||||
-- check if the remote URL is a Gitlab URL
|
||||
if string.match(result, "gitlab%.com") then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function jump_to_file(filename, line_number)
|
||||
if line_number == nil then line_number = 1 end
|
||||
vim.api.nvim_command("wincmd l")
|
||||
@@ -255,7 +234,6 @@ M.format_date = format_date
|
||||
M.add_comment_sign = add_comment_sign
|
||||
M.jump_to_file = jump_to_file
|
||||
M.find_value_by_id = find_value_by_id
|
||||
M.is_gitlab_repo = is_gitlab_repo
|
||||
M.darken_metadata = darken_metadata
|
||||
M.print_success = print_success
|
||||
M.print_error = print_error
|
||||
|
||||
Reference in New Issue
Block a user