150 lines
3.9 KiB
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
|