changes
This commit is contained in:
@@ -4,9 +4,9 @@ local uv = vim.loop
|
||||
local M = {}
|
||||
local token_cached = nil
|
||||
|
||||
-- Attempt to read the token file from disk
|
||||
-- Read token file from disk (if present)
|
||||
local function read_token_file(path)
|
||||
local fd = uv.fs_open(path, "r", 438) -- 0666 in decimal
|
||||
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)
|
||||
@@ -14,9 +14,9 @@ local function read_token_file(path)
|
||||
return data
|
||||
end
|
||||
|
||||
-- Write token file
|
||||
-- Write token file to disk with restricted permissions
|
||||
local function write_token_file(path, token)
|
||||
local fd = uv.fs_open(path, "w", 384) -- 0600 in decimal
|
||||
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
|
||||
@@ -24,137 +24,86 @@ local function write_token_file(path, token)
|
||||
uv.fs_close(fd)
|
||||
end
|
||||
|
||||
-- Checks if the token file is in .gitignore, if not ask user
|
||||
local function ensure_ignored(token_file, ignore_file)
|
||||
-- Read .gitignore lines if present
|
||||
local file = io.open(ignore_file, "r")
|
||||
local lines = {}
|
||||
if file then
|
||||
for line in file:lines() do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
file:close()
|
||||
end
|
||||
-- Check if token_file is in .gitignore
|
||||
for _, l in ipairs(lines) do
|
||||
if l == token_file then
|
||||
return
|
||||
end
|
||||
end
|
||||
-- Not in ignore, ask user
|
||||
vim.schedule(function()
|
||||
vim.cmd([[echohl WarningMsg]])
|
||||
vim.cmd([[echo "gitea.nvim: We recommend adding ']]..token_file..[[' to ']]..ignore_file..[['. Add now? (y/N)"]])
|
||||
vim.cmd([[echohl None]])
|
||||
|
||||
local ans = vim.fn.getchar()
|
||||
ans = vim.fn.nr2char(ans)
|
||||
|
||||
if ans == "y" or ans == "Y" then
|
||||
local f = io.open(ignore_file, "a")
|
||||
if f then
|
||||
f:write("\n" .. token_file .. "\n")
|
||||
f:close()
|
||||
vim.notify("Added '"..token_file.."' to '"..ignore_file.."'", vim.log.levels.INFO)
|
||||
else
|
||||
vim.notify("Failed to open '"..ignore_file.."' for appending.", vim.log.levels.ERROR)
|
||||
end
|
||||
else
|
||||
vim.notify("Ok, not adding token file to '"..ignore_file.."'. Be mindful of security!", vim.log.levels.WARN)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Parse .git/config or `git remote get-url origin` to guess the Gitea server
|
||||
----------------------------------------------------------------------------
|
||||
--- Attempt to detect the Gitea server from remote.origin.url or fail
|
||||
----------------------------------------------------------------------------
|
||||
local function detect_gitea_server()
|
||||
-- Attempt: use `git config remote.origin.url`
|
||||
-- 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
|
||||
end
|
||||
-- Example: https://gitea.myserver.com/owner/repo.git
|
||||
-- Strip `.git` suffix if present
|
||||
url = url:gsub("%.git$", "")
|
||||
-- Attempt to extract domain, e.g. "https://gitea.myserver.com"
|
||||
-- We'll do a naive pattern match
|
||||
local protocol, domain_and_path = url:match("^(https?://)(.*)$")
|
||||
if not protocol or not domain_and_path then
|
||||
-- Could be SSH or something else
|
||||
-- For instance: git@gitea.myserver.com:owner/repo.git
|
||||
-- Try a different parse
|
||||
local user_host, path = url:match("^(.-):(.*)$")
|
||||
if user_host and path and user_host:match(".*@") then
|
||||
-- user_host could be "git@gitea.myserver.com"
|
||||
local host = user_host:match("@(.*)")
|
||||
if host then
|
||||
return "https://"..host
|
||||
end
|
||||
end
|
||||
-- Fallback
|
||||
return nil
|
||||
return nil, "No valid remote.origin.url found"
|
||||
end
|
||||
|
||||
-- domain_and_path might be "gitea.myserver.com/owner/repo"
|
||||
-- just extract "gitea.myserver.com"
|
||||
local server = domain_and_path:match("^([^/]+)")
|
||||
if not server then
|
||||
return nil
|
||||
-- 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
|
||||
return protocol .. server
|
||||
|
||||
-- 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
|
||||
|
||||
-- Called during plugin setup or first command usage
|
||||
----------------------------------------------------------------------------
|
||||
--- 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
|
||||
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
|
||||
|
||||
local cfg = config.values
|
||||
local token_file = cfg.config_file
|
||||
local ignore_file = cfg.ignore_file
|
||||
|
||||
-- Attempt to detect the Gitea server if not provided
|
||||
if not cfg.server_url or cfg.server_url == "" then
|
||||
cfg.server_url = detect_gitea_server()
|
||||
end
|
||||
if not cfg.server_url then
|
||||
vim.notify("[gitea.nvim] Could not detect Gitea server from .git/config. Please configure manually.", vim.log.levels.WARN)
|
||||
end
|
||||
|
||||
local token_data = read_token_file(token_file)
|
||||
if token_data and token_data ~= "" then
|
||||
token_cached = token_data
|
||||
return token_cached
|
||||
end
|
||||
|
||||
-- If we reach here, no token was found
|
||||
vim.schedule(function()
|
||||
vim.cmd([[echohl WarningMsg]])
|
||||
vim.cmd([[echo "gitea.nvim: No Gitea token found. Please enter your Gitea Personal Access Token:"]])
|
||||
vim.cmd([[echohl None]])
|
||||
|
||||
local user_token = vim.fn.input("Token: ")
|
||||
vim.cmd("redraw")
|
||||
|
||||
if user_token == nil or user_token == "" then
|
||||
vim.notify("[gitea.nvim] No token provided, plugin may not work properly.", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
write_token_file(token_file, user_token)
|
||||
token_cached = user_token
|
||||
vim.notify("Token saved to " .. token_file .. ".", vim.log.levels.INFO)
|
||||
|
||||
-- Offer to add token_file to .gitignore
|
||||
ensure_ignored(token_file, ignore_file)
|
||||
end)
|
||||
|
||||
return nil
|
||||
ensure_server_url()
|
||||
ensure_token_file()
|
||||
return token_cached
|
||||
end
|
||||
|
||||
function M.get_token()
|
||||
return token_cached
|
||||
end
|
||||
|
||||
return M
|
||||
return M
|
||||
Reference in New Issue
Block a user