fix(pkg): versioning and reload specs when pkg-cache is dirty

This commit is contained in:
Folke Lemaitre 2024-06-23 22:00:48 +02:00
parent 183f59e2e8
commit fd8229d6e3
5 changed files with 59 additions and 48 deletions

View File

@ -1,5 +1,6 @@
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
local Meta = require("lazy.core.meta") local Meta = require("lazy.core.meta")
local Pkg = require("lazy.pkg")
local Util = require("lazy.core.util") local Util = require("lazy.core.util")
---@class LazyCorePlugin ---@class LazyCorePlugin
@ -332,6 +333,12 @@ function M.load()
Util.track("state") Util.track("state")
M.update_state() M.update_state()
Util.track() Util.track()
if Config.options.pkg.enabled and Pkg.dirty then
Pkg.update()
return M.load()
end
M.loading = false M.loading = false
vim.api.nvim_exec_autocmds("User", { pattern = "LazyPlugins", modeline = false }) vim.api.nvim_exec_autocmds("User", { pattern = "LazyPlugins", modeline = false })
end end

View File

@ -2,6 +2,8 @@ local Config = require("lazy.core.config")
local Util = require("lazy.util") local Util = require("lazy.util")
local M = {} local M = {}
M.VERSION = 7
M.dirty = false
---@alias LazyPkgSpec LazySpec | fun():LazySpec ---@alias LazyPkgSpec LazySpec | fun():LazySpec
@ -10,10 +12,13 @@ local M = {}
---@field name string ---@field name string
---@field file string ---@field file string
---@field spec? LazySpec ---@field spec? LazySpec
---@field chunk? string|fun():LazySpec
---@class LazyPkgInput: LazyPkg
---@field spec? LazySpec|fun():LazySpec
---@field code? string
---@class LazyPkgSource ---@class LazyPkgSource
---@field get fun(plugin:LazyPlugin):LazyPkg ---@field get fun(plugin:LazyPlugin):LazyPkgInput?
---@type table<string, LazyPkg>? ---@type table<string, LazyPkg>?
M.cache = nil M.cache = nil
@ -25,76 +30,78 @@ function M.update()
sources[#sources + 1] = require("lazy.pkg." .. s) sources[#sources + 1] = require("lazy.pkg." .. s)
end end
---@type table<string, LazyPkg> M.cache = {}
local ret = {}
for _, plugin in pairs(Config.plugins) do for _, plugin in pairs(Config.plugins) do
if plugin._.installed then
for _, source in ipairs(sources) do for _, source in ipairs(sources) do
local spec = source.get(plugin) local spec = source.get(plugin)
if spec then if spec then
spec.name = plugin.name spec.name = plugin.name
if type(spec.chunk) == "function" then if type(spec.code) == "string" then
spec.chunk = string.dump(spec.chunk) spec.spec = { _raw = spec.code }
spec.code = nil
end end
ret[plugin.dir] = spec M.cache[plugin.dir] = spec
break break
end end
end end
end end
local code = "return " .. Util.dump(ret) end
local code = "return " .. Util.dump({ version = M.VERSION, specs = M.cache })
Util.write_file(Config.options.pkg.cache, code) Util.write_file(Config.options.pkg.cache, code)
M.dirty = false
M.cache = nil M.cache = nil
end end
local function _load() local function _load()
Util.track("pkg") Util.track("pkg")
M.cache = {} M.cache = nil
if vim.uv.fs_stat(Config.options.pkg.cache) then if vim.uv.fs_stat(Config.options.pkg.cache) then
Util.try(function() Util.try(function()
local chunk, err = loadfile(Config.options.pkg.cache) local chunk, err = loadfile(Config.options.pkg.cache)
if not chunk then if not chunk then
error(err) error(err)
end end
M.cache = chunk() local ret = chunk()
if ret and ret.version == M.VERSION then
M.cache = ret.specs
end
end, "Error loading pkg:") end, "Error loading pkg:")
end end
if rawget(M, "cache") then
M.dirty = false
else
M.cache = {}
M.dirty = true
end
Util.track() Util.track()
end end
---@param plugin LazyPlugin ---@param dir string
---@return LazyPkg? ---@return LazyPkg?
function M.get(plugin) function M.get(dir)
if not M.cache then local ret = M.cache[dir]
_load()
end
local ret = M.cache[plugin.dir]
if not ret then if not ret then
return return
end end
if ret.chunk and not ret.spec then if type(ret.spec) == "function" then
if type(ret.chunk) == "string" then ret.spec = ret.spec()
ret.chunk = load(ret.chunk, "@" .. plugin.dir)
end
ret.spec = ret.chunk()
ret.chunk = nil
end end
return ret return ret
end end
function M.spec() function M.spec()
if not M.cache then
_load()
end
---@type table<string,LazyPluginSpec> ---@type table<string,LazyPluginSpec>
local ret = {} local ret = {}
for dir in pairs(M.cache) do for dir in pairs(M.cache) do
local pkg = M.get({ dir = dir }) local pkg = M.get(dir)
local spec = pkg and pkg.spec local spec = pkg and pkg.spec
if pkg and spec then if pkg and spec then
spec = type(spec) == "table" and vim.deepcopy(spec) or spec spec = type(spec) == "table" and vim.deepcopy(spec) or spec
---@cast spec LazySpec
ret[dir] = { pkg.name, specs = spec } ret[dir] = { pkg.name, specs = spec }
end end
end end
@ -102,16 +109,11 @@ function M.spec()
return ret return ret
end end
---@param plugin LazyPlugin return setmetatable(M, {
---@return LazySpec? __index = function(_, key)
function M.get_spec(plugin) if key == "cache" then
local pkg = M.get(plugin) _load()
local spec = pkg and pkg.spec return M.cache
if not spec then
return
end end
spec = type(spec) == "table" and vim.deepcopy(spec) or spec end,
return { plugin.name, specs = spec } })
end
return M

View File

@ -16,11 +16,12 @@ function M.get(plugin)
end, "`" .. M.lazy_file .. "` for **" .. plugin.name .. "** has errors:") end, "`" .. M.lazy_file .. "` for **" .. plugin.name .. "** has errors:")
if not chunk then if not chunk then
Util.error("Invalid `" .. M.lazy_file .. "` for **" .. plugin.name .. "**") Util.error("Invalid `" .. M.lazy_file .. "` for **" .. plugin.name .. "**")
return
end end
return { return {
source = "lazy", source = "lazy",
file = M.lazy_file, file = M.lazy_file,
chunk = chunk, code = "function()\n" .. Util.read_file(file) .. "\nend",
} }
end end
end end

View File

@ -46,7 +46,7 @@ function M.get(plugin)
return #rocks > 0 return #rocks > 0
and { and {
source = "rockspec", source = "rockspec",
file = rockspec_file, file = vim.fn.fnamemodify(rockspec_file, ":t"),
spec = { spec = {
plugin.name, plugin.name,
rocks = rocks, rocks = rocks,

View File

@ -34,6 +34,7 @@ M.commands = {
health = function() health = function()
vim.cmd.checkhealth("lazy") vim.cmd.checkhealth("lazy")
end, end,
---@param opts ManagerOpts
pkg = function(opts) pkg = function(opts)
local Pkg = require("lazy.pkg") local Pkg = require("lazy.pkg")
Pkg.update() Pkg.update()
@ -44,7 +45,7 @@ M.commands = {
}, },
}) })
for _, plugin in pairs(opts and opts.plugins or {}) do for _, plugin in pairs(opts and opts.plugins or {}) do
local spec = Pkg.get(plugin) local spec = Pkg.get(plugin.dir)
Util.info(vim.inspect(spec), { lang = "lua", title = plugin.name }) Util.info(vim.inspect(spec), { lang = "lua", title = plugin.name })
end end
end, end,