mrpy.nvim/lua/eta/gitlab.lua

150 lines
3.9 KiB
Lua

local notify = require("snacks.notifier").notify
local helpers = require("eta.helpers")
local M = {}
---@class eta.gitlab.Session: eta.Session
---@field auth string personal access token `PRIVATE_TOKEN: <auth_token>`
---@class eta.gitlab.Namespace
---@field full_path string
---@class eta.gitlab.Project
---@field id number
---@field name string
---@field path_with_namespace string
---@field tag_list string[]
---@field text? string
---@field namespace eta.gitlab.Namespace
---@field preview? {ft: string, text: string}
---@class eta.gitlab.Milestone
---@field id number
---@field title string
---@class eta.gitlab.Assignee
---@field username string
---@field id number
---@class eta.gitlab.Issue
---@field id number
---@field milestone eta.gitlab.Milestone
---@field title string
---@field assignees eta.gitlab.Assignee[]
---@field description string
---@field labels string[]
---@param session eta.gitlab.Session
---@return eta.gitlab.Project[]
M.possible_projects = function(session)
return helpers.request("get", session, "/projects", {simple="true", per_page="100"}) or {}
end
---@param prj eta.gitlab.Project
M._project_format = function(prj)
local ret = {}
ret[#ret + 1] = { prj.namespace.full_path .. "/", "SnacksPickerComment" }
ret[#ret + 1] = { prj.name }
return ret
end
---@param self eta.gitlab.Session
---@return eta.gitlab.Project | nil
M.update_current_project = function(self)
local cmd = "git remote -v | grep fetch | cut -f2 | cut -d' ' -f1 | cut -d':' -f2"
local handle, _ = io.popen(cmd, 'r')
if not handle then return nil end
local repo = handle:read("*a")
handle:close()
local prjs = M.possible_projects(self)
for _, prj in ipairs(prjs) do
if prj.path_with_namespace == repo then
M.active_project = prj
notify("selected " .. prj.path_with_namespace, "info", { title = "ETA", style = 'fancy' })
return prj
end
end
end
---@type eta.gitlab.Project
M.active_project = nil
---@param picker snacks.Picker
---@param item eta.gitlab.Project
M._on_project_select = function(picker, item)
M.active_project = item
picker:close()
notify("selected " .. item.path_with_namespace, "info", { title = "ETA", style = 'fancy' })
end
---@param self eta.gitlab.Session
M.select_project = function(self)
local prjs = M.possible_projects(self)
require("snacks.picker").pick({
title = "Select Project",
format = M._project_format,
preview = "preview",
confirm = M._on_project_select,
items = prjs
})
end
---@param self eta.gitlab.Session
---@return eta.gitlab.Issue[]
M.active_issues = function(self)
if not M.active_project then
if not M.update_current_project(self) then
M.select_project(self)
end
end
return request("get", self, "/projects/" .. tostring(M.active_project.id) .. "/issues", {})
end
---@param self eta.gitlab.Session
---@param name string
---@param clickup_task_id string
---@param tags string[]
M.new_issue = function(self, name, clickup_task_id, tags)
if not M.active_project then
if not M.update_current_project(self) then
M.select_project(self)
end
end
local description = "%23" .. clickup_task_id
local title = name:gsub("%s", "%20")
return request("post", self, "/projects/" ..
tostring(M.active_project.id) ..
"/issues", {
title=title, description=description, labels=table.concat(tags, ",")
})
end
---@param self eta.gitlab.Session
---@param name string
---@param issue number
---@param clickup_task_id string
---@param tags string[]
M.new_mr = function(self, name, issue, clickup_task_id, tags)
if not M.active_project then
if not M.update_current_project(self) then
M.select_project(self)
end
end
local description = "Closes %23" .. tostring(issue) .. " | %23" .. clickup_task_id
local title = name:gsub("%s", "%20")
return request("post", self, "/projects/" .. tostring(M.active_project.id) .. "/merge_requests", {
title=title, description=description, labels=table.concat(tags, ",")
})
end
return M