diff --git a/lua/lazy/core/config.lua b/lua/lazy/core/config.lua index 58f9e10..db79250 100644 --- a/lua/lazy/core/config.lua +++ b/lua/lazy/core/config.lua @@ -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, diff --git a/lua/lazy/core/packspec.lua b/lua/lazy/core/packspec.lua deleted file mode 100644 index 75217d1..0000000 --- a/lua/lazy/core/packspec.lua +++ /dev/null @@ -1,125 +0,0 @@ -local Config = require("lazy.core.config") -local Util = require("lazy.util") - ----@class PackSpec ----@field dependencies? table ----@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 -M.packspecs = nil ----@type table -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 diff --git a/lua/lazy/core/plugin.lua b/lua/lazy/core/plugin.lua index 6c8d7da..de6d228 100644 --- a/lua/lazy/core/plugin.lua +++ b/lua/lazy/core/plugin.lua @@ -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 +---@field pkgs table ---@field names table 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 diff --git a/lua/lazy/manage/init.lua b/lua/lazy/manage/init.lua index 308930e..3e145c8 100644 --- a/lua/lazy/manage/init.lua +++ b/lua/lazy/manage/init.lua @@ -93,7 +93,7 @@ function M.install(opts) }, opts):wait(function() require("lazy.manage.lock").update() require("lazy.help").update() - require("lazy.core.packspec").update() + require("lazy.pkg").update() end) end @@ -119,7 +119,7 @@ function M.update(opts) }, opts):wait(function() require("lazy.manage.lock").update() require("lazy.help").update() - require("lazy.core.packspec").update() + require("lazy.pkg").update() end) end -- diff --git a/lua/lazy/manage/rocks.lua b/lua/lazy/manage/rocks.lua index efad65d..3e1bc6e 100644 --- a/lua/lazy/manage/rocks.lua +++ b/lua/lazy/manage/rocks.lua @@ -16,33 +16,32 @@ M.rocks = {} ---@param ... string ---@return string[] function M.args(...) - local ret = { "--tree", Config.rocks.tree, "--lua-version", "5.1" } + local ret = { + "--tree", + Config.rocks.tree, + "--server", + Config.options.rocks.server, + "--dev", + "--lua-version", + "5.1", + } vim.list_extend(ret, { ... }) return ret end -function M.parse(rockspec_file) - local rockspec = {} - local ret, err = loadfile(rockspec_file, "t", rockspec) - if not ret then - error(err) - end - ret() - return rockspec -end - --- dd(M.parse("/home/folke/.local/share/nvim/lazy/neorg/neorg-scm-1.rockspec")) - ---@param plugin LazyPlugin function M.get_rockspec(plugin) - assert(plugin.rocks and #plugin.rocks > 0, plugin.name .. " has no rocks") - local rockspec_file = Config.rocks.specs .. "/lazy-" .. plugin.name .. "-0.0-0.rockspec" + local rocks = vim.tbl_map(function(rock) + return rock.name + end, plugin._.rocks) + assert(rocks and #rocks > 0, plugin.name .. " has no rocks") + local rockspec_file = Config.rocks.specs .. "/lazy-" .. plugin.name .. "-scm-1.rockspec" require("lazy.util").write_file( rockspec_file, ([[ rockspec_format = "3.0" package = "lazy-%s" -version = "0.0-0" +version = "scm-1" source = { url = "%s" } dependencies = %s build = { type = "builtin" } @@ -78,9 +77,11 @@ function M.update_state() spec = spec, installed = installed[name] ~= nil, } - plugin._.rocks_installed = plugin._.rocks_installed and rock.installed - table.insert(plugin._.rocks, rock) - table.insert(rocks, rock) + if rock.name ~= "lua" then + plugin._.rocks_installed = plugin._.rocks_installed and rock.installed + table.insert(plugin._.rocks, rock) + table.insert(rocks, rock) + end end end end diff --git a/lua/lazy/pkg/init.lua b/lua/lazy/pkg/init.lua new file mode 100644 index 0000000..f09afbc --- /dev/null +++ b/lua/lazy/pkg/init.lua @@ -0,0 +1,92 @@ +local Config = require("lazy.core.config") +local Util = require("lazy.util") + +local M = {} + +---@alias LazyPkgSpec LazySpec | fun():LazySpec + +---@class LazyPkg +---@field source string +---@field file string +---@field spec? LazySpec +---@field chunk? string|fun():LazySpec + +---@class LazyPkgSource +---@field get fun(plugin:LazyPlugin):LazyPkg + +---@type table? +M.cache = nil + +function M.update() + ---@type LazyPkgSource[] + local sources = {} + for _, s in ipairs(Config.options.pkg.sources) do + sources[#sources + 1] = require("lazy.pkg." .. s) + end + + ---@type table + local ret = {} + for _, plugin in pairs(Config.plugins) do + for _, source in ipairs(sources) do + local spec = source.get(plugin) + if spec then + if type(spec.chunk) == "function" then + spec.chunk = string.dump(spec.chunk) + end + ret[plugin.dir] = spec + break + end + end + end + local code = "return " .. Util.dump(ret) + Util.write_file(Config.options.pkg.cache, code) + M.cache = nil +end + +local function _load() + Util.track("pkg") + M.cache = {} + if vim.uv.fs_stat(Config.options.pkg.cache) then + Util.try(function() + local chunk, err = loadfile(Config.options.pkg.cache) + if not chunk then + error(err) + end + M.cache = chunk() + end, "Error loading pkg:") + end + Util.track() +end + +---@param plugin LazyPlugin +---@return LazyPkg? +function M.get(plugin) + if not M.cache then + _load() + end + + local ret = M.cache[plugin.dir] + if not ret then + return + end + + if ret.chunk and not ret.spec then + if type(ret.chunk) == "string" then + ret.chunk = load(ret.chunk, "@" .. plugin.dir) + end + ret.spec = ret.chunk() + ret.chunk = nil + end + + return ret +end + +---@param plugin LazyPlugin +---@return LazySpec? +function M.get_spec(plugin) + local pkg = M.get(plugin) + local spec = pkg and pkg.spec + return spec and type(spec) == "table" and vim.deepcopy(spec) or spec +end + +return M diff --git a/lua/lazy/pkg/lazy.lua b/lua/lazy/pkg/lazy.lua new file mode 100644 index 0000000..07b0491 --- /dev/null +++ b/lua/lazy/pkg/lazy.lua @@ -0,0 +1,28 @@ +local Util = require("lazy.util") + +local M = {} + +M.lazy_file = "lazy.lua" + +---@param plugin LazyPlugin +---@return LazyPkg? +function M.get(plugin) + local file = Util.norm(plugin.dir .. "/" .. M.lazy_file) + if Util.file_exists(file) then + ---@type fun(): LazySpec + local chunk = Util.try(function() + local ret, err = loadfile(file) + return err and error(err) or ret + end, "`" .. M.lazy_file .. "` for **" .. plugin.name .. "** has errors:") + if not chunk then + Util.error("Invalid `" .. M.lazy_file .. "` for **" .. plugin.name .. "**") + end + return { + source = "lazy", + file = M.lazy_file, + chunk = chunk, + } + end +end + +return M diff --git a/lua/lazy/pkg/packspec.lua b/lua/lazy/pkg/packspec.lua new file mode 100644 index 0000000..c9f2042 --- /dev/null +++ b/lua/lazy/pkg/packspec.lua @@ -0,0 +1,54 @@ +local Util = require("lazy.util") + +---@class PackSpec +---@field dependencies? table +---@field lazy? LazyPluginSpec +--- +local M = {} + +M.pkg_file = "pkg.json" + +---@param plugin LazyPlugin +---@return LazyPkg? +function M.get(plugin) + local file = Util.norm(plugin.dir .. "/" .. M.pkg_file) + if not Util.file_exists(file) then + return + end + ---@type PackSpec + local pkg = Util.try(function() + return vim.json.decode(Util.read_file(file)) + end, "`" .. M.pkg_file .. "` for **" .. plugin.name .. "** has errors:") + + if not pkg then + return + end + + ---@type LazySpec + local ret = {} + if pkg.dependencies then + for url, version in pairs(pkg.dependencies) do + -- 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 + if pkg.lazy then + ret[#ret + 1] = pkg.lazy + end + return { + source = "lazy", + file = M.pkg_file, + spec = ret, + } +end + +return M diff --git a/lua/lazy/pkg/rockspec.lua b/lua/lazy/pkg/rockspec.lua new file mode 100644 index 0000000..7a0c752 --- /dev/null +++ b/lua/lazy/pkg/rockspec.lua @@ -0,0 +1,55 @@ +--# selene:allow(incorrect_standard_library_use) + +local Util = require("lazy.core.util") + +local M = {} + +M.dev_suffix = "-scm-1.rockspec" +M.skip = { "lua" } + +---@class RockSpec +---@field rockspec_format string +---@field package string +---@field version string +---@field dependencies string[] + +---@param plugin LazyPlugin +---@return LazyPkg? +function M.get(plugin) + local rockspec_file ---@type string? + Util.ls(plugin.dir, function(path, name, t) + if t == "file" and name:sub(-#M.dev_suffix) == M.dev_suffix then + rockspec_file = path + return false + end + end) + + if not rockspec_file then + return + end + + ---@type RockSpec? + local rockspec = {} + local ret, err = loadfile(rockspec_file, "t", rockspec) + if not ret then + error(err) + end + ret() + return rockspec + and rockspec.package + and { + source = "rockspec", + file = rockspec_file, + spec = { + dir = plugin.dir, + url = plugin.url, + rocks = vim.tbl_filter(function(dep) + local name = dep:gsub("%s.*", "") + return not vim.tbl_contains(M.skip, name) + end, rockspec.dependencies), + }, + } + or nil +end + +return M diff --git a/lua/lazy/util.lua b/lua/lazy/util.lua index 970b066..755c1cd 100644 --- a/lua/lazy/util.lua +++ b/lua/lazy/util.lua @@ -241,22 +241,21 @@ function M._dump(value, result) table.insert(result, value._raw) elseif t == "table" then table.insert(result, "{") - local i = 1 + for _, v in ipairs(value) do + M._dump(v, result) + table.insert(result, ",") + end ---@diagnostic disable-next-line: no-unknown for k, v in pairs(value) do - if k == i then - elseif type(k) == "string" then + if type(k) == "string" then if k:match("^[a-zA-Z]+$") then table.insert(result, ("%s="):format(k)) else table.insert(result, ("[%q]="):format(k)) end - else - table.insert(result, k .. "=") + M._dump(v, result) + table.insert(result, ",") end - M._dump(v, result) - table.insert(result, ",") - i = i + 1 end table.insert(result, "}") else diff --git a/lua/lazy/view/commands.lua b/lua/lazy/view/commands.lua index 13c5070..6b828a5 100644 --- a/lua/lazy/view/commands.lua +++ b/lua/lazy/view/commands.lua @@ -35,11 +35,11 @@ M.commands = { vim.cmd.checkhealth("lazy") end, pkg = function(opts) - local Pkg = require("lazy.core.packspec") + local Pkg = require("lazy.pkg") Pkg.update() require("lazy.manage.reloader").reload({ { - file = "packspec", --Config.options.packspec.path, + file = "pkg", what = "changed", }, })