mirror of https://github.com/folke/lazy.nvim.git
fix(pkg): correctly pre-load package specs and remove them when needed during resolve
This commit is contained in:
parent
ee2ca39f67
commit
4326d4b487
|
@ -1,4 +1,5 @@
|
||||||
local Config = require("lazy.core.config")
|
local Config = require("lazy.core.config")
|
||||||
|
local Pkg = require("lazy.pkg")
|
||||||
local Util = require("lazy.core.util")
|
local Util = require("lazy.core.util")
|
||||||
|
|
||||||
--- This class is used to manage the plugins.
|
--- This class is used to manage the plugins.
|
||||||
|
@ -10,6 +11,7 @@ local Util = require("lazy.core.util")
|
||||||
---@field dirty table<string, boolean>
|
---@field dirty table<string, boolean>
|
||||||
---@field spec LazySpecLoader
|
---@field spec LazySpecLoader
|
||||||
---@field fragments LazyFragments
|
---@field fragments LazyFragments
|
||||||
|
---@field pkgs table<string, number>
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
---@param spec LazySpecLoader
|
---@param spec LazySpecLoader
|
||||||
|
@ -22,9 +24,30 @@ function M.new(spec)
|
||||||
self.frag_to_meta = {}
|
self.frag_to_meta = {}
|
||||||
self.str_to_meta = {}
|
self.str_to_meta = {}
|
||||||
self.dirty = {}
|
self.dirty = {}
|
||||||
|
self.pkgs = {}
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- import package specs
|
||||||
|
function M:load_pkgs()
|
||||||
|
if not Config.options.pkg.enabled then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local specs = Pkg.spec()
|
||||||
|
for dir, spec in pairs(specs) do
|
||||||
|
local meta, fragment = self:add(spec)
|
||||||
|
if meta and fragment then
|
||||||
|
-- tag all package fragments as optional
|
||||||
|
for _, fid in ipairs(meta._.frags) do
|
||||||
|
local frag = self.fragments:get(fid)
|
||||||
|
frag.spec.optional = true
|
||||||
|
end
|
||||||
|
-- keep track of the top-level package fragment
|
||||||
|
self.pkgs[dir] = fragment.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Remove a plugin and all its fragments.
|
--- Remove a plugin and all its fragments.
|
||||||
---@param name string
|
---@param name string
|
||||||
function M:del(name)
|
function M:del(name)
|
||||||
|
@ -88,6 +111,7 @@ function M:add(plugin)
|
||||||
self.plugins[meta.name] = meta
|
self.plugins[meta.name] = meta
|
||||||
self.frag_to_meta[fragment.id] = meta
|
self.frag_to_meta[fragment.id] = meta
|
||||||
self.dirty[meta.name] = true
|
self.dirty[meta.name] = true
|
||||||
|
return meta, fragment
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Rebuild all plugins based on dirty fragments,
|
--- Rebuild all plugins based on dirty fragments,
|
||||||
|
@ -101,6 +125,7 @@ function M:rebuild()
|
||||||
self.dirty[meta.name] = true
|
self.dirty[meta.name] = true
|
||||||
else
|
else
|
||||||
-- fragment was deleted, so remove it from plugin
|
-- fragment was deleted, so remove it from plugin
|
||||||
|
self.frag_to_meta[fid] = nil
|
||||||
---@param f number
|
---@param f number
|
||||||
meta._.frags = vim.tbl_filter(function(f)
|
meta._.frags = vim.tbl_filter(function(f)
|
||||||
return f ~= fid
|
return f ~= fid
|
||||||
|
@ -260,11 +285,28 @@ function M:fix_disabled()
|
||||||
return changes
|
return changes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Removes package fragments for plugins that no longer use the same directory.
|
||||||
|
function M:fix_pkgs()
|
||||||
|
for dir, fid in pairs(self.pkgs) do
|
||||||
|
local plugin = self.frag_to_meta[fid]
|
||||||
|
plugin = plugin and self.plugins[plugin.name]
|
||||||
|
if plugin then
|
||||||
|
-- check if plugin is still in the same directory
|
||||||
|
if plugin.dir ~= dir then
|
||||||
|
self.fragments:del(fid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:rebuild()
|
||||||
|
end
|
||||||
|
|
||||||
--- Resolve all plugins, based on cond, enabled and optional.
|
--- Resolve all plugins, based on cond, enabled and optional.
|
||||||
function M:resolve()
|
function M:resolve()
|
||||||
Util.track("resolve plugins")
|
Util.track("resolve plugins")
|
||||||
self:rebuild()
|
self:rebuild()
|
||||||
|
|
||||||
|
self:fix_pkgs()
|
||||||
|
|
||||||
self:fix_cond()
|
self:fix_cond()
|
||||||
|
|
||||||
-- selene: allow(empty_loop)
|
-- selene: allow(empty_loop)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
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
|
||||||
|
@ -16,7 +15,6 @@ M.loading = false
|
||||||
---@field notifs {msg:string, level:number, file?:string}[]
|
---@field notifs {msg:string, level:number, file?:string}[]
|
||||||
---@field importing? string
|
---@field importing? string
|
||||||
---@field optional? boolean
|
---@field optional? boolean
|
||||||
---@field pkgs table<string, boolean>
|
|
||||||
local Spec = {}
|
local Spec = {}
|
||||||
M.Spec = Spec
|
M.Spec = Spec
|
||||||
M.LOCAL_SPEC = ".lazy.lua"
|
M.LOCAL_SPEC = ".lazy.lua"
|
||||||
|
@ -30,8 +28,8 @@ function Spec.new(spec, opts)
|
||||||
self.modules = {}
|
self.modules = {}
|
||||||
self.notifs = {}
|
self.notifs = {}
|
||||||
self.ignore_installed = {}
|
self.ignore_installed = {}
|
||||||
self.pkgs = {}
|
|
||||||
self.optional = opts and opts.optional
|
self.optional = opts and opts.optional
|
||||||
|
self.meta:load_pkgs()
|
||||||
if spec then
|
if spec then
|
||||||
self:parse(spec)
|
self:parse(spec)
|
||||||
end
|
end
|
||||||
|
@ -62,25 +60,6 @@ function Spec.get_name(pkg)
|
||||||
return slash and name:sub(#name - slash + 2) or pkg:gsub("%W+", "_")
|
return slash and name:sub(#name - slash + 2) or pkg:gsub("%W+", "_")
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param plugin LazyPluginSpec
|
|
||||||
function Spec:add(plugin)
|
|
||||||
self.meta:add(plugin)
|
|
||||||
|
|
||||||
---@diagnostic disable-next-line: cast-type-mismatch
|
|
||||||
---@cast plugin LazyPlugin
|
|
||||||
|
|
||||||
-- import the plugin's spec
|
|
||||||
if Config.options.pkg.enabled and plugin.dir and not self.pkgs[plugin.dir] then
|
|
||||||
self.pkgs[plugin.dir] = true
|
|
||||||
local pkg = Pkg.get_spec(plugin)
|
|
||||||
if pkg then
|
|
||||||
self:normalize(pkg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return plugin
|
|
||||||
end
|
|
||||||
|
|
||||||
function Spec:error(msg)
|
function Spec:error(msg)
|
||||||
self:log(msg, vim.log.levels.ERROR)
|
self:log(msg, vim.log.levels.ERROR)
|
||||||
end
|
end
|
||||||
|
@ -110,7 +89,7 @@ end
|
||||||
---@param spec LazySpec|LazySpecImport
|
---@param spec LazySpec|LazySpecImport
|
||||||
function Spec:normalize(spec)
|
function Spec:normalize(spec)
|
||||||
if type(spec) == "string" then
|
if type(spec) == "string" then
|
||||||
self:add({ spec })
|
self.meta:add({ spec })
|
||||||
elseif #spec > 1 or Util.is_list(spec) then
|
elseif #spec > 1 or Util.is_list(spec) then
|
||||||
---@cast spec LazySpec[]
|
---@cast spec LazySpec[]
|
||||||
for _, s in ipairs(spec) do
|
for _, s in ipairs(spec) do
|
||||||
|
@ -118,11 +97,11 @@ function Spec:normalize(spec)
|
||||||
end
|
end
|
||||||
elseif spec[1] or spec.dir or spec.url then
|
elseif spec[1] or spec.dir or spec.url then
|
||||||
---@cast spec LazyPluginSpec
|
---@cast spec LazyPluginSpec
|
||||||
local plugin = self:add(spec)
|
self.meta:add(spec)
|
||||||
---@diagnostic disable-next-line: cast-type-mismatch
|
---@diagnostic disable-next-line: cast-type-mismatch
|
||||||
---@cast plugin LazySpecImport
|
---@cast spec LazySpecImport
|
||||||
if plugin and plugin.import then
|
if spec and spec.import then
|
||||||
self:import(plugin)
|
self:import(spec)
|
||||||
end
|
end
|
||||||
elseif spec.import then
|
elseif spec.import then
|
||||||
---@cast spec LazySpecImport
|
---@cast spec LazySpecImport
|
||||||
|
|
|
@ -7,6 +7,7 @@ local M = {}
|
||||||
|
|
||||||
---@class LazyPkg
|
---@class LazyPkg
|
||||||
---@field source string
|
---@field source string
|
||||||
|
---@field name string
|
||||||
---@field file string
|
---@field file string
|
||||||
---@field spec? LazySpec
|
---@field spec? LazySpec
|
||||||
---@field chunk? string|fun():LazySpec
|
---@field chunk? string|fun():LazySpec
|
||||||
|
@ -30,6 +31,7 @@ function M.update()
|
||||||
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
|
||||||
if type(spec.chunk) == "function" then
|
if type(spec.chunk) == "function" then
|
||||||
spec.chunk = string.dump(spec.chunk)
|
spec.chunk = string.dump(spec.chunk)
|
||||||
end
|
end
|
||||||
|
@ -81,6 +83,25 @@ function M.get(plugin)
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.spec()
|
||||||
|
if not M.cache then
|
||||||
|
_load()
|
||||||
|
end
|
||||||
|
---@type table<string,LazyPluginSpec>
|
||||||
|
local ret = {}
|
||||||
|
|
||||||
|
for dir in pairs(M.cache) do
|
||||||
|
local pkg = M.get({ dir = dir })
|
||||||
|
local spec = pkg and pkg.spec
|
||||||
|
if pkg and spec then
|
||||||
|
spec = type(spec) == "table" and vim.deepcopy(spec) or spec
|
||||||
|
ret[dir] = { pkg.name, specs = spec }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
---@param plugin LazyPlugin
|
---@param plugin LazyPlugin
|
||||||
---@return LazySpec?
|
---@return LazySpec?
|
||||||
function M.get_spec(plugin)
|
function M.get_spec(plugin)
|
||||||
|
|
|
@ -29,24 +29,27 @@ function M.get(plugin)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type RockSpec?
|
---@type RockSpec?
|
||||||
|
---@diagnostic disable-next-line: missing-fields
|
||||||
local rockspec = {}
|
local rockspec = {}
|
||||||
local ret, err = loadfile(rockspec_file, "t", rockspec)
|
local load, err = loadfile(rockspec_file, "t", rockspec)
|
||||||
if not ret then
|
if not load then
|
||||||
error(err)
|
error(err)
|
||||||
end
|
end
|
||||||
ret()
|
load()
|
||||||
return rockspec
|
|
||||||
and rockspec.package
|
---@param dep string
|
||||||
|
local rocks = vim.tbl_filter(function(dep)
|
||||||
|
local name = dep:gsub("%s.*", "")
|
||||||
|
return not vim.tbl_contains(M.skip, name)
|
||||||
|
end, rockspec and rockspec.dependencies or {})
|
||||||
|
|
||||||
|
return #rocks > 0
|
||||||
and {
|
and {
|
||||||
source = "rockspec",
|
source = "rockspec",
|
||||||
file = rockspec_file,
|
file = rockspec_file,
|
||||||
spec = {
|
spec = {
|
||||||
dir = plugin.dir,
|
plugin.name,
|
||||||
url = plugin.url,
|
rocks = rocks,
|
||||||
rocks = vim.tbl_filter(function(dep)
|
|
||||||
local name = dep:gsub("%s.*", "")
|
|
||||||
return not vim.tbl_contains(M.skip, name)
|
|
||||||
end, rockspec.dependencies),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
or nil
|
or nil
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
|
|
||||||
---@class LazyFragment
|
---@class LazyFragment
|
||||||
---@field id number
|
---@field id number
|
||||||
|
---@field pkg? boolean
|
||||||
---@field pid? number
|
---@field pid? number
|
||||||
---@field deps? number[]
|
---@field deps? number[]
|
||||||
---@field frags? number[]
|
---@field frags? number[]
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
std="vim"
|
std="vim"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
mixed_table="allow"
|
||||||
|
|
Loading…
Reference in New Issue