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:
Harrison (Harry) Cramer
2023-08-06 11:21:39 -04:00
committed by Harrison Cramer
parent ade9f81426
commit 4f0d4b49ef
16 changed files with 281 additions and 293 deletions

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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