feat: added support for plugin packages by lazy, rockspec and packspec

This commit is contained in:
Folke Lemaitre 2024-06-18 21:54:54 +02:00
parent 2d4f2cb507
commit 1e0ab0574e
11 changed files with 281 additions and 171 deletions

View file

@ -31,8 +31,19 @@ M.defaults = {
-- increase downloads a lot.
filter = true,
},
pkg = {
enabled = true,
cache = vim.fn.stdpath("state") .. "/lazy/pkg-cache.lua",
versions = true, -- Honor versions in pkg sources
sources = {
"lazy",
"rockspec",
"packspec",
},
},
rocks = {
root = vim.fn.stdpath("data") .. "/lazy-rocks",
server = "https://nvim-neorocks.github.io/rocks-binaries/",
},
dev = {
---@type string | fun(plugin: LazyPlugin): string directory where you store your local plugin projects
@ -182,11 +193,6 @@ M.defaults = {
-- Track each new require in the Lazy profiling tab
require = false,
},
packspec = {
enabled = true,
versions = true, -- Honor dependency versions in packspecs
path = vim.fn.stdpath("state") .. "/lazy/packspec.lua",
},
debug = false,
}
@ -306,9 +312,9 @@ function M.setup(opts)
-- useful for plugin developers when making changes to a packspec file
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = "package.lua",
pattern = "lazy.lua",
callback = function()
require("lazy.view.commands").cmd("packspec")
require("lazy.view.commands").cmd("pkg")
end,
})
end,

View file

@ -1,125 +0,0 @@
local Config = require("lazy.core.config")
local Util = require("lazy.util")
---@class PackSpec
---@field dependencies? table<string, string>
---@field lazy? LazyPluginSpec
local M = {}
M.lazy_file = "lazy.lua"
M.pkg_file = "pkg.json"
M.enable_lazy_file = false
---@alias LazyPkg {lazy?:(fun():LazySpec), pkg?:PackSpec}
---@type table<string, LazyPkg>
M.packspecs = nil
---@type table<string, LazySpec>
M.specs = {}
---@param spec LazyPkg
---@param plugin LazyPlugin
---@return LazySpec?
local function convert(plugin, spec)
---@type LazySpec
local ret = {}
local pkg = spec.pkg
if pkg then
if pkg.dependencies then
for url, version in pairs(pkg.dependencies) do
if (not Config.options.packspec.versions) or version == "*" or version == "" then
version = nil
end
-- HACK: Add `.git` to github urls
if url:find("github") and not url:match("%.git$") then
url = url .. ".git"
end
ret[#ret + 1] = { url = url, version = version }
end
end
local p = pkg.lazy
if p then
p.url = p.url or plugin.url
p.dir = p.dir or plugin.dir
ret[#ret + 1] = p
end
end
if spec.lazy then
ret[#ret + 1] = spec.lazy()
end
return ret
end
local function load()
Util.track("packspec")
M.packspecs = {}
if vim.loop.fs_stat(Config.options.packspec.path) then
Util.try(function()
M.packspecs = loadfile(Config.options.packspec.path)()
end, "Error loading packspecs:")
end
Util.track()
end
---@param plugin LazyPlugin
---@return LazySpec?
function M.get(plugin)
if not M.packspecs then
load()
end
if not M.packspecs[plugin.dir] then
return
end
M.specs[plugin.dir] = M.specs[plugin.dir] or convert(plugin, M.packspecs[plugin.dir])
return vim.deepcopy(M.specs[plugin.dir])
end
function M.update()
local ret = {}
for _, plugin in pairs(Config.plugins) do
local spec = {
pkg = M.pkg(plugin),
lazy = M.enable_lazy_file and M.lazy_pkg(plugin) or nil,
}
if not vim.tbl_isempty(spec) then
ret[plugin.dir] = spec
end
end
local code = "return " .. Util.dump(ret)
Util.write_file(Config.options.packspec.path, code)
M.packspecs = nil
M.specs = {}
end
---@param plugin LazyPlugin
function M.lazy_pkg(plugin)
local file = Util.norm(plugin.dir .. "/" .. M.lazy_file)
if Util.file_exists(file) then
---@type LazySpec
local chunk = Util.try(function()
return loadfile(file)
end, "`" .. M.lazy_file .. "` for **" .. plugin.name .. "** has errors:")
if chunk then
return { _raw = ([[function() %s end]]):format(Util.read_file(file)) }
else
Util.error("Invalid `package.lua` for **" .. plugin.name .. "**")
end
end
end
---@param plugin LazyPlugin
function M.pkg(plugin)
local file = Util.norm(plugin.dir .. "/" .. M.pkg_file)
if Util.file_exists(file) then
---@type PackSpec
return Util.try(function()
return vim.json.decode(Util.read_file(file))
end, "`" .. M.pkg_file .. "` for **" .. plugin.name .. "** has errors:")
end
end
return M

View file

@ -1,5 +1,5 @@
local Config = require("lazy.core.config")
local Packspec = require("lazy.core.packspec")
local Pkg = require("lazy.pkg")
local Util = require("lazy.core.util")
---@class LazyCorePlugin
@ -16,7 +16,7 @@ M.loading = false
---@field notifs {msg:string, level:number, file?:string}[]
---@field importing? string
---@field optional? boolean
---@field packspecs table<string, boolean>
---@field pkgs table<string, boolean>
---@field names table<string,string>
local Spec = {}
M.Spec = Spec
@ -35,7 +35,7 @@ function Spec.new(spec, opts)
self.dirty = {}
self.notifs = {}
self.ignore_installed = {}
self.packspecs = {}
self.pkgs = {}
self.optional = opts and opts.optional
self.names = {}
if spec then
@ -173,11 +173,11 @@ function Spec:add(plugin, results)
end
-- import the plugin's spec
if Config.options.packspec.enabled and plugin.dir and not self.packspecs[plugin.dir] then
self.packspecs[plugin.dir] = true
local packspec = Packspec.get(plugin)
if packspec then
self:normalize(packspec, nil, true)
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, nil)
end
end