112 lines
3.6 KiB
Lua
112 lines
3.6 KiB
Lua
local config = require("gitea.config")
|
|
local uv = vim.loop
|
|
|
|
local M = {}
|
|
local token_cached = nil
|
|
|
|
-- Read token file from disk (if present)
|
|
local function read_token_file(path)
|
|
local fd = uv.fs_open(path, "r", 438)
|
|
if not fd then return nil end
|
|
local stat = uv.fs_fstat(fd)
|
|
local data = uv.fs_read(fd, stat.size, 0)
|
|
uv.fs_close(fd)
|
|
return data
|
|
end
|
|
|
|
-- Write token file to disk with restricted permissions
|
|
local function write_token_file(path, token)
|
|
local fd = uv.fs_open(path, "w", 384) -- 0600 decimal
|
|
if not fd then
|
|
error("[gitea.nvim] Failed to open token file for writing: " .. path)
|
|
end
|
|
uv.fs_write(fd, token, -1)
|
|
uv.fs_close(fd)
|
|
end
|
|
|
|
----------------------------------------------------------------------------
|
|
--- Attempt to detect the Gitea server from remote.origin.url or fail
|
|
----------------------------------------------------------------------------
|
|
local function detect_gitea_server()
|
|
-- Use `git config remote.origin.url`
|
|
local cmd = "git config remote.origin.url"
|
|
local url = vim.fn.systemlist(cmd)[1]
|
|
if vim.v.shell_error ~= 0 or not url or url == "" then
|
|
return nil, "No valid remote.origin.url found"
|
|
end
|
|
|
|
-- Remove trailing ".git" if present
|
|
url = url:gsub("%.git$", "")
|
|
|
|
-- Check for HTTPS style: https://my.gitea.com/owner/repo
|
|
local protocol, domain_and_path = url:match("^(https?://)(.*)$")
|
|
if protocol and domain_and_path then
|
|
local server = domain_and_path:match("^([^/]+)")
|
|
if server and server ~= "" then
|
|
return protocol .. server
|
|
end
|
|
end
|
|
|
|
-- Check for SSH style: git@my.gitea.com:owner/repo
|
|
local user_host, path = url:match("^(.-):(.*)$")
|
|
if user_host and user_host:match(".*@") then
|
|
local host = user_host:match("@(.*)")
|
|
if host and host ~= "" then
|
|
-- We'll assume https for Gitea, if your instance is not https,
|
|
-- you can adapt or forcibly use "http://" below
|
|
return "https://" .. host
|
|
end
|
|
end
|
|
|
|
return nil, "Unable to parse Gitea host from remote.origin.url: " .. url
|
|
end
|
|
|
|
----------------------------------------------------------------------------
|
|
--- DO NOT PROMPT for server_url, do not fallback to "gitea.example.com"
|
|
--- If we cannot auto-detect, we throw an error.
|
|
----------------------------------------------------------------------------
|
|
local function ensure_server_url()
|
|
local server, err = detect_gitea_server()
|
|
if not server then
|
|
error(string.format("[gitea.nvim] Failed to auto-detect Gitea server: %s", err))
|
|
end
|
|
config.values.server_url = server
|
|
end
|
|
|
|
----------------------------------------------------------------------------
|
|
--- The user must have a Gitea token, we read from disk or error if missing
|
|
----------------------------------------------------------------------------
|
|
local function ensure_token_file()
|
|
local token_file = config.values.config_file
|
|
local token_data = read_token_file(token_file)
|
|
if token_data and token_data ~= "" then
|
|
-- Trim leading/trailing whitespace/newlines so we don't send a trailing "\n"
|
|
token_data = token_data:gsub("^%s+", ""):gsub("%s+$", "")
|
|
token_cached = token_data
|
|
return
|
|
end
|
|
error(
|
|
"[gitea.nvim] No token found in " .. token_file ..
|
|
". Please manually create and store your Gitea token there with mode 600."
|
|
)
|
|
end
|
|
|
|
----------------------------------------------------------------------------
|
|
--- Called by the plugin during setup or first usage
|
|
----------------------------------------------------------------------------
|
|
function M.ensure_token()
|
|
if token_cached then
|
|
return token_cached
|
|
end
|
|
|
|
ensure_server_url()
|
|
ensure_token_file()
|
|
return token_cached
|
|
end
|
|
|
|
function M.get_token()
|
|
return token_cached
|
|
end
|
|
|
|
return M
|