From b30abd2412e0eb0fb92c31867aa6a7d71ff28f38 Mon Sep 17 00:00:00 2001 From: aceforeverd Date: Sat, 5 Aug 2023 22:48:32 +0800 Subject: [PATCH 1/4] feat(unfinished): check archived plugins --- lua/aceforeverd/init.lua | 2 ++ lua/aceforeverd/plugins/util.lua | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 lua/aceforeverd/plugins/util.lua diff --git a/lua/aceforeverd/init.lua b/lua/aceforeverd/init.lua index 6870e70..cd4b133 100644 --- a/lua/aceforeverd/init.lua +++ b/lua/aceforeverd/init.lua @@ -68,6 +68,8 @@ function M.setup() -- keymap guideline -- xxx -> view-only operators -- xxx -> possibly write operators + + vim.api.nvim_create_user_command('GetOldPlugins', [[lua require('aceforeverd.plugins.util').GetOldPlugins()]], {}) end return M diff --git a/lua/aceforeverd/plugins/util.lua b/lua/aceforeverd/plugins/util.lua new file mode 100644 index 0000000..280a250 --- /dev/null +++ b/lua/aceforeverd/plugins/util.lua @@ -0,0 +1,26 @@ +local base = 'https://api.github.com/repo/' + +function GetRepo(repo) + local curl = require('plenary.curl') + return curl.get(base .. repo) +end + +function GetOldPlugins() + local plugins = vim.fn['minpac#getpluglist']() + local out = {} + for _, value in pairs(plugins) do + local url = value['url'] + local repo = vim.fn.substitute(url, [[^https://github.com/]], '', '') + local stats = GetRepo(repo) + + if stats ~= nil and stats.archived == true then + table.insert(out, {value, 'archived'}) + end + end + + vim.api.nvim_notify(vim.inspect(out), vim.log.levels.INFO, {}) +end + +return { + GetOldPlugins = GetOldPlugins +} From 6bc48c7392048c3c77b6da8daf4be8ab1ef50951 Mon Sep 17 00:00:00 2001 From: aceforeverd Date: Sun, 6 Aug 2023 12:04:58 +0800 Subject: [PATCH 2/4] save changes --- lua/aceforeverd/init.lua | 2 +- lua/aceforeverd/plugins/util.lua | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lua/aceforeverd/init.lua b/lua/aceforeverd/init.lua index cd4b133..54e143b 100644 --- a/lua/aceforeverd/init.lua +++ b/lua/aceforeverd/init.lua @@ -69,7 +69,7 @@ function M.setup() -- xxx -> view-only operators -- xxx -> possibly write operators - vim.api.nvim_create_user_command('GetOldPlugins', [[lua require('aceforeverd.plugins.util').GetOldPlugins()]], {}) + vim.api.nvim_create_user_command('PackCheckHealth', [[lua require('aceforeverd.plugins.util').GetOldPlugins()]], {}) end return M diff --git a/lua/aceforeverd/plugins/util.lua b/lua/aceforeverd/plugins/util.lua index 280a250..5cf42f0 100644 --- a/lua/aceforeverd/plugins/util.lua +++ b/lua/aceforeverd/plugins/util.lua @@ -6,6 +6,7 @@ function GetRepo(repo) end function GetOldPlugins() + -- minpac plugins local plugins = vim.fn['minpac#getpluglist']() local out = {} for _, value in pairs(plugins) do @@ -14,11 +15,25 @@ function GetOldPlugins() local stats = GetRepo(repo) if stats ~= nil and stats.archived == true then - table.insert(out, {value, 'archived'}) + table.insert(out, repo) + else + vim.notify('ok: ' .. repo, vim.log.levels.INFO, {}) end end - vim.api.nvim_notify(vim.inspect(out), vim.log.levels.INFO, {}) + -- lazy plugins + local lua_plugins = require('aceforeverd.plugins').plugin_list + for _, value in pairs(lua_plugins) do + local stats = GetRepo(value[0]) + + if stats ~= nil and stats.archived == true then + table.insert(out, value[0]) + else + vim.notify('ok: ' .. value[0], vim.log.levels.INFO, {}) + end + end + + vim.notify('archived: ' .. vim.inspect(out), vim.log.levels.INFO, {}) end return { From af5808b2bc9dcb798814746b460267cd68a179f6 Mon Sep 17 00:00:00 2001 From: aceforeverd Date: Fri, 20 Mar 2026 16:37:47 +0800 Subject: [PATCH 3/4] fix check archived plugins --- autoload/aceforeverd/plugin.vim | 5 +++ lua/aceforeverd/plugins/util.lua | 61 +++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/autoload/aceforeverd/plugin.vim b/autoload/aceforeverd/plugin.vim index 593480f..0dfb3d5 100644 --- a/autoload/aceforeverd/plugin.vim +++ b/autoload/aceforeverd/plugin.vim @@ -235,6 +235,11 @@ function! aceforeverd#plugin#init() abort call s:plugin_add('kkoomen/vim-doge', {'type': 'opt', 'do': 'packadd vim-doge | call doge#install()'}) endfunction +function! aceforeverd#plugin#list() abort + call aceforeverd#plugin#init() + return minpac#getpluglist() +endfunction + function! s:config_plugins() abort " no matchit & matchparen let g:loaded_matchit = 1 diff --git a/lua/aceforeverd/plugins/util.lua b/lua/aceforeverd/plugins/util.lua index 5cf42f0..8f65dd2 100644 --- a/lua/aceforeverd/plugins/util.lua +++ b/lua/aceforeverd/plugins/util.lua @@ -1,35 +1,62 @@ -local base = 'https://api.github.com/repo/' +local base = 'https://api.github.com/repos/' -function GetRepo(repo) +local curl_timeout = 10000 + +--- check if a plugin repo is archived, or long time no update +---@param repo string path to repo, format: 'username/repo' +---@return {archived: boolean, err_msg: string} +local function check_archived(repo) + if repo == nil or repo == '' then + return {err_msg = "invalid repo"} + end + + + -- require authorization or rate limit will easily hit, use gh if applicable local curl = require('plenary.curl') - return curl.get(base .. repo) + -- use pcall to catch error throw by curl.get + local ok, stat = pcall(curl.get, base .. repo, { timeout = curl_timeout }) + if not ok then + return { err_msg = stat } + end + if stat.exit ~= 0 or stat.status ~= 200 then + local msg = stat.body.message or vim.inspect(stat.body) + return { err_msg = string.format('exit=%d, status=%d, message: %s', stat.exit, stat.status, msg) } + end + + return stat.body end function GetOldPlugins() -- minpac plugins - local plugins = vim.fn['minpac#getpluglist']() + local plugins = vim.fn['aceforeverd#plugin#list']() local out = {} for _, value in pairs(plugins) do local url = value['url'] local repo = vim.fn.substitute(url, [[^https://github.com/]], '', '') - local stats = GetRepo(repo) - - if stats ~= nil and stats.archived == true then - table.insert(out, repo) - else - vim.notify('ok: ' .. repo, vim.log.levels.INFO, {}) + repo = vim.fn.substitute(repo, [[\.git$]], '', '') + local stats = check_archived(repo) + if stats ~= nil then + if stats.err_msg ~= nil then + vim.notify(string.format('%s error: %s', repo, stats.err_msg), vim.log.levels.WARN, {}) + elseif stats.archived == true then + table.insert(out, repo) + end end end -- lazy plugins local lua_plugins = require('aceforeverd.plugins').plugin_list for _, value in pairs(lua_plugins) do - local stats = GetRepo(value[0]) - - if stats ~= nil and stats.archived == true then - table.insert(out, value[0]) - else - vim.notify('ok: ' .. value[0], vim.log.levels.INFO, {}) + local repo = value[0] + local stats = check_archived(repo) + if stats ~= nil then + if stats.err_msg ~= nil then + vim.notify(string.format('%s error: %s', repo, stats.err_msg), vim.log.levels.WARN, {}) + elseif stats.archived == true then + table.insert(out, repo) + else + vim.notify(string.format("%s: ok", repo), vim.log.levels.INFO, {}) + end end end @@ -37,5 +64,5 @@ function GetOldPlugins() end return { - GetOldPlugins = GetOldPlugins + GetOldPlugins = GetOldPlugins, } From ee0788060d2cbc46ff7fc446556dbf1492cbaca5 Mon Sep 17 00:00:00 2001 From: aceforeverd Date: Wed, 1 Apr 2026 18:59:08 +0800 Subject: [PATCH 4/4] nan --- lua/aceforeverd/plugins/util.lua | 245 ++++++++++++++++++++++++++----- 1 file changed, 206 insertions(+), 39 deletions(-) diff --git a/lua/aceforeverd/plugins/util.lua b/lua/aceforeverd/plugins/util.lua index 8f65dd2..f096b71 100644 --- a/lua/aceforeverd/plugins/util.lua +++ b/lua/aceforeverd/plugins/util.lua @@ -1,66 +1,233 @@ local base = 'https://api.github.com/repos/' - local curl_timeout = 10000 +local function get_github_token() + local token = os.getenv('GITHUB_TOKEN') + if token and token ~= '' then + return token + end + + local token_file = vim.fn.expand('~/.github_token') + if vim.fn.filereadable(token_file) == 1 then + local lines = vim.fn.readfile(token_file) + if #lines > 0 then + return vim.trim(lines[1]) + end + end + return nil +end + --- check if a plugin repo is archived, or long time no update ---@param repo string path to repo, format: 'username/repo' ----@return {archived: boolean, err_msg: string} -local function check_archived(repo) +---@param callback function(stats) +local function check_archived_async(repo, callback) if repo == nil or repo == '' then - return {err_msg = "invalid repo"} + callback({ err_msg = 'invalid repo' }) + return end - - -- require authorization or rate limit will easily hit, use gh if applicable local curl = require('plenary.curl') - -- use pcall to catch error throw by curl.get - local ok, stat = pcall(curl.get, base .. repo, { timeout = curl_timeout }) - if not ok then - return { err_msg = stat } + local token = get_github_token() + local headers = { + ['Accept'] = 'application/vnd.github.v3+json', + } + if token then + headers['Authorization'] = 'token ' .. token + end + + curl.get(base .. repo, { + timeout = curl_timeout, + headers = headers, + callback = function(stat) + if stat.exit ~= 0 then + callback({ err_msg = string.format('curl error: exit=%d', stat.exit) }) + return + end + + local ok, body = pcall(vim.json.decode, stat.body) + if not ok then + callback({ err_msg = 'failed to decode response body' }) + return + end + + if stat.status ~= 200 then + local msg = body.message or 'Unknown error' + local err_msg = string.format('HTTP %d: %s', stat.status, msg) + if stat.status == 401 then + err_msg = 'HTTP 401: Unauthorized (check your token)' + elseif stat.status == 403 then + if msg:find('rate limit') then + err_msg = 'HTTP 403: Rate limit exceeded' + else + err_msg = 'HTTP 403: Forbidden' + end + elseif stat.status == 404 then + err_msg = 'HTTP 404: Not Found (repo might be deleted or private)' + end + callback({ err_msg = err_msg }) + return + end + + callback(body) + end, + }) +end + +local function show_results_ui(plugin_repos) + local Popup = require('nui.popup') + local event = require('nui.utils.autocmd').event + + local popup = Popup({ + enter = true, + focusable = true, + border = { + style = 'rounded', + text = { + top = ' Plugin Archive Check ', + top_align = 'center', + }, + }, + position = '50%', + size = { + width = '80%', + height = '60%', + }, + }) + + popup:mount() + + popup:on(event.BufLeave, function() + popup:unmount() + end) + + local bufnr = popup.bufnr + vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr }) + vim.api.nvim_buf_set_keymap(bufnr, 'n', 'q', ':q', { noremap = true, silent = true }) + + local results = {} + local total = #plugin_repos + local finished = 0 + local archived_repos = {} + + local function update_view() + local lines = { + string.format('Progress: %d/%d', finished, total), + '', + } + + for _, res in ipairs(results) do + local status_text = '' + local hl_group = '' + if res.status == 'checking' then + status_text = 'Checking...' + hl_group = 'Comment' + elseif res.status == 'ok' then + status_text = 'OK' + hl_group = 'DiagnosticInfo' + elseif res.status == 'archived' then + status_text = 'ARCHIVED' + hl_group = 'DiagnosticWarn' + elseif res.status == 'error' then + status_text = 'ERROR: ' .. res.err_msg + hl_group = 'DiagnosticError' + end + table.insert(lines, string.format('%-40s %s', res.repo, status_text)) + end + + if finished == total then + table.insert(lines, '') + table.insert(lines, 'Summary:') + if #archived_repos > 0 then + table.insert(lines, 'Archived plugins found:') + for _, repo in ipairs(archived_repos) do + table.insert(lines, ' - ' .. repo) + end + else + table.insert(lines, 'No archived plugins found.') + end + end + + vim.schedule(function() + if not vim.api.nvim_buf_is_valid(bufnr) then + return + end + vim.api.nvim_set_option_value('modifiable', true, { buf = bufnr }) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) + + -- Add highlights + for i, res in ipairs(results) do + local hl = 'Comment' + if res.status == 'ok' then + hl = 'DiagnosticInfo' + elseif res.status == 'archived' then + hl = 'DiagnosticWarn' + elseif res.status == 'error' then + hl = 'DiagnosticError' + end + vim.api.nvim_buf_add_highlight(bufnr, -1, hl, i + 1, 41, -1) + end + + vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr }) + end) end - if stat.exit ~= 0 or stat.status ~= 200 then - local msg = stat.body.message or vim.inspect(stat.body) - return { err_msg = string.format('exit=%d, status=%d, message: %s', stat.exit, stat.status, msg) } + + for i, repo in ipairs(plugin_repos) do + results[i] = { repo = repo, status = 'checking' } end + update_view() - return stat.body + for i, repo in ipairs(plugin_repos) do + check_archived_async(repo, function(stats) + finished = finished + 1 + if stats.err_msg then + results[i].status = 'error' + results[i].err_msg = stats.err_msg + elseif stats.archived then + results[i].status = 'archived' + table.insert(archived_repos, repo) + else + results[i].status = 'ok' + end + update_view() + end) + end end function GetOldPlugins() - -- minpac plugins - local plugins = vim.fn['aceforeverd#plugin#list']() - local out = {} - for _, value in pairs(plugins) do - local url = value['url'] - local repo = vim.fn.substitute(url, [[^https://github.com/]], '', '') - repo = vim.fn.substitute(repo, [[\.git$]], '', '') - local stats = check_archived(repo) - if stats ~= nil then - if stats.err_msg ~= nil then - vim.notify(string.format('%s error: %s', repo, stats.err_msg), vim.log.levels.WARN, {}) - elseif stats.archived == true then - table.insert(out, repo) + local plugin_repos = {} + + -- minpac plugins (legacy support as per original script) + local ok_minpac, minpac_plugins = pcall(vim.fn['aceforeverd#plugin#list']) + if ok_minpac then + for _, value in pairs(minpac_plugins) do + local url = value['url'] + local repo = vim.fn.substitute(url, [[^https://github.com/]], '', '') + repo = vim.fn.substitute(repo, [[\.git$]], '', '') + if not vim.tbl_contains(plugin_repos, repo) then + table.insert(plugin_repos, repo) end end end -- lazy plugins - local lua_plugins = require('aceforeverd.plugins').plugin_list - for _, value in pairs(lua_plugins) do - local repo = value[0] - local stats = check_archived(repo) - if stats ~= nil then - if stats.err_msg ~= nil then - vim.notify(string.format('%s error: %s', repo, stats.err_msg), vim.log.levels.WARN, {}) - elseif stats.archived == true then - table.insert(out, repo) - else - vim.notify(string.format("%s: ok", repo), vim.log.levels.INFO, {}) + local ok_lazy, lua_plugins = pcall(function() + return require('aceforeverd.plugins').plugin_list + end) + if ok_lazy then + for _, value in pairs(lua_plugins) do + local repo = value[1] or value[0] -- lazy spec can be { "user/repo" } or { [0] = "user/repo" } + if type(repo) == 'string' and not repo:find('http') and not vim.tbl_contains(plugin_repos, repo) then + table.insert(plugin_repos, repo) end end end - vim.notify('archived: ' .. vim.inspect(out), vim.log.levels.INFO, {}) + if #plugin_repos == 0 then + vim.notify('No plugins found to check.', vim.log.levels.WARN) + return + end + + show_results_ui(plugin_repos) end return {