|
| 1 | +local Config = require("lazy.core.config") |
| 2 | +local Util = require("lazy.util") |
| 3 | + |
| 4 | +---@class PackSpec |
| 5 | +---@field dependencies? table<string, string> |
| 6 | +---@field lazy? LazyPluginSpec |
| 7 | +local M = {} |
| 8 | + |
| 9 | +M.lazy_file = "lazy.lua" |
| 10 | +M.pkg_file = "pkg.json" |
| 11 | +M.enable_lazy_file = false |
| 12 | + |
| 13 | +---@alias LazyPkg {lazy?:(fun():LazySpec), pkg?:PackSpec} |
| 14 | + |
| 15 | +---@type table<string, LazyPkg> |
| 16 | +M.packspecs = nil |
| 17 | +---@type table<string, LazySpec> |
| 18 | +M.specs = {} |
| 19 | + |
| 20 | +---@param spec LazyPkg |
| 21 | +---@param plugin LazyPlugin |
| 22 | +---@return LazySpec? |
| 23 | +local function convert(plugin, spec) |
| 24 | + ---@type LazySpec |
| 25 | + local ret = {} |
| 26 | + |
| 27 | + local pkg = spec.pkg |
| 28 | + if pkg then |
| 29 | + if pkg.dependencies then |
| 30 | + for url, version in pairs(pkg.dependencies) do |
| 31 | + if (not Config.options.packspec.versions) or version == "*" or version == "" then |
| 32 | + version = nil |
| 33 | + end |
| 34 | + -- HACK: Add `.git` to github urls |
| 35 | + if url:find("github") and not url:match("%.git$") then |
| 36 | + url = url .. ".git" |
| 37 | + end |
| 38 | + ret[#ret + 1] = { url = url, version = version } |
| 39 | + end |
| 40 | + end |
| 41 | + local p = pkg.lazy |
| 42 | + if p then |
| 43 | + p.url = p.url or plugin.url |
| 44 | + p.dir = p.dir or plugin.dir |
| 45 | + ret[#ret + 1] = p |
| 46 | + end |
| 47 | + end |
| 48 | + |
| 49 | + if spec.lazy then |
| 50 | + ret[#ret + 1] = spec.lazy() |
| 51 | + end |
| 52 | + |
| 53 | + return ret |
| 54 | +end |
| 55 | + |
| 56 | +local function load() |
| 57 | + Util.track("packspec") |
| 58 | + M.packspecs = {} |
| 59 | + if vim.loop.fs_stat(Config.options.packspec.path) then |
| 60 | + Util.try(function() |
| 61 | + M.packspecs = loadfile(Config.options.packspec.path)() |
| 62 | + end, "Error loading packspecs:") |
| 63 | + end |
| 64 | + Util.track() |
| 65 | +end |
| 66 | + |
| 67 | +---@param plugin LazyPlugin |
| 68 | +---@return LazySpec? |
| 69 | +function M.get(plugin) |
| 70 | + if not M.packspecs then |
| 71 | + load() |
| 72 | + end |
| 73 | + |
| 74 | + if not M.packspecs[plugin.dir] then |
| 75 | + return |
| 76 | + end |
| 77 | + M.specs[plugin.dir] = M.specs[plugin.dir] or convert(plugin, M.packspecs[plugin.dir]) |
| 78 | + return vim.deepcopy(M.specs[plugin.dir]) |
| 79 | +end |
| 80 | + |
| 81 | +function M.update() |
| 82 | + local ret = {} |
| 83 | + for _, plugin in pairs(Config.plugins) do |
| 84 | + local spec = { |
| 85 | + pkg = M.pkg(plugin), |
| 86 | + lazy = M.enable_lazy_file and M.lazy_pkg(plugin) or nil, |
| 87 | + } |
| 88 | + if not vim.tbl_isempty(spec) then |
| 89 | + ret[plugin.dir] = spec |
| 90 | + end |
| 91 | + end |
| 92 | + local code = "return " .. Util.dump(ret) |
| 93 | + Util.write_file(Config.options.packspec.path, code) |
| 94 | + M.packspecs = nil |
| 95 | + M.specs = {} |
| 96 | +end |
| 97 | + |
| 98 | +---@param plugin LazyPlugin |
| 99 | +function M.lazy_pkg(plugin) |
| 100 | + local file = Util.norm(plugin.dir .. "/" .. M.lazy_file) |
| 101 | + if Util.file_exists(file) then |
| 102 | + ---@type LazySpec |
| 103 | + local chunk = Util.try(function() |
| 104 | + return loadfile(file) |
| 105 | + end, "`" .. M.lazy_file .. "` for **" .. plugin.name .. "** has errors:") |
| 106 | + if chunk then |
| 107 | + return { _raw = ([[function() %s end]]):format(Util.read_file(file)) } |
| 108 | + else |
| 109 | + Util.error("Invalid `package.lua` for **" .. plugin.name .. "**") |
| 110 | + end |
| 111 | + end |
| 112 | +end |
| 113 | + |
| 114 | +---@param plugin LazyPlugin |
| 115 | +function M.pkg(plugin) |
| 116 | + local file = Util.norm(plugin.dir .. "/" .. M.pkg_file) |
| 117 | + if Util.file_exists(file) then |
| 118 | + ---@type PackSpec |
| 119 | + return Util.try(function() |
| 120 | + return vim.json.decode(Util.read_file(file)) |
| 121 | + end, "`" .. M.pkg_file .. "` for **" .. plugin.name .. "** has errors:") |
| 122 | + end |
| 123 | +end |
| 124 | + |
| 125 | +return M |
0 commit comments