Skip to content

Commit

Permalink
feat(spec): allow using plugin names in dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Dec 22, 2022
1 parent eb01b6d commit 4bf771a
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 5 deletions.
18 changes: 15 additions & 3 deletions lua/lazy/core/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@ local M = {}

---@class LazySpecLoader
---@field plugins table<string, LazyPlugin>
---@field errors string[]
local Spec = {}
M.Spec = Spec

---@param spec? LazySpec
function Spec.new(spec)
local self = setmetatable({}, { __index = Spec })
self.plugins = {}
self.errors = {}
if spec then
self:normalize(spec)
end
Expand Down Expand Up @@ -100,7 +102,7 @@ function Spec:add(plugin, is_dep)
plugin.dir = Config.options.root .. "/" .. plugin.name
end
else
Util.error("Invalid plugin spec " .. vim.inspect(plugin))
self:error("Invalid plugin spec " .. vim.inspect(plugin))
end

plugin.event = type(plugin.event) == "string" and { plugin.event } or plugin.event
Expand All @@ -116,13 +118,23 @@ function Spec:add(plugin, is_dep)
return self.plugins[plugin.name]
end

function Spec:error(error)
self.errors[#self.errors + 1] = error
Util.error(error)
end

---@param spec LazySpec
---@param results? string[]
---@param is_dep? boolean
function Spec:normalize(spec, results, is_dep)
results = results or {}
if type(spec) == "string" then
table.insert(results, self:add({ spec }, is_dep).name)
if is_dep and not spec:find("/", 1, true) then
-- spec is a plugin name
table.insert(results, spec)
else
table.insert(results, self:add({ spec }, is_dep).name)
end
elseif #spec > 1 or Util.is_list(spec) then
---@cast spec LazySpec[]
for _, s in ipairs(spec) do
Expand Down Expand Up @@ -160,7 +172,7 @@ function Spec:merge(old, new)
---@diagnostic disable-next-line: no-unknown
old[k] = values
else
Util.error("Merging plugins is not supported for key `" .. k .. "`\n" .. vim.inspect({ old = old, new = new }))
self:error("Merging plugins is not supported for key `" .. k .. "`\n" .. vim.inspect({ old = old, new = new }))
end
else
---@diagnostic disable-next-line: no-unknown
Expand Down
166 changes: 164 additions & 2 deletions tests/core/plugin_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe("plugin spec url/name", function()
end
local spec = Plugin.Spec.new(test[1])
local plugins = vim.tbl_values(spec.plugins)
assert(#spec.errors == 0)
assert.equal(1, #plugins)
assert.same(test[2], plugins[1])
end)
Expand All @@ -41,7 +42,8 @@ describe("plugin spec opt", function()
{ { { "foo/bar", dependencies = { { "foo/dep1" }, "foo/dep2" } } } },
}
for _, test in ipairs(tests) do
local spec = Plugin.Spec.new(test)
local spec = Plugin.Spec.new(vim.deepcopy(test))
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert(vim.tbl_count(spec.plugins) == 3)
Expand All @@ -52,12 +54,168 @@ describe("plugin spec opt", function()
assert(spec.plugins.dep1.lazy == true)
assert(spec.plugins.dep2._.dep == true)
assert(spec.plugins.dep2.lazy == true)
spec = Plugin.Spec.new(test)
for _, plugin in pairs(spec.plugins) do
plugin.dir = nil
end
assert.same(spec.plugins, {
bar = {
"foo/bar",
_ = {},
dependencies = { "dep1", "dep2" },
name = "bar",
url = "https://github.com/foo/bar.git",
},
dep1 = {
"foo/dep1",
_ = {
dep = true,
},
name = "dep1",
url = "https://github.com/foo/dep1.git",
},
dep2 = {
"foo/dep2",
_ = {
dep = true,
},
name = "dep2",
url = "https://github.com/foo/dep2.git",
},
})
end
end)

describe("deps", function()
it("handles dep names", function()
Config.options.defaults.lazy = false
local tests = {
{ { "foo/bar", dependencies = { { "dep1" }, "foo/dep2" } }, "foo/dep1" },
{ "foo/dep1", { "foo/bar", dependencies = { { "dep1" }, "foo/dep2" } } },
}
for _, test in ipairs(tests) do
local spec = Plugin.Spec.new(vim.deepcopy(test))
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
spec = Plugin.Spec.new(test)
for _, plugin in pairs(spec.plugins) do
plugin.dir = nil
end
assert.same(spec.plugins, {
bar = {
"foo/bar",
_ = {},
dependencies = { "dep1", "dep2" },
name = "bar",
url = "https://github.com/foo/bar.git",
},
dep1 = {
"foo/dep1",
_ = {},
name = "dep1",
url = "https://github.com/foo/dep1.git",
},
dep2 = {
"foo/dep2",
_ = {
dep = true,
},
name = "dep2",
url = "https://github.com/foo/dep2.git",
},
})
end
end)

it("handles opt from dep", function()
Config.options.defaults.lazy = false
local spec = Plugin.Spec.new({ "foo/dep1", { "foo/bar", dependencies = { "foo/dep1", "foo/dep2" } } })
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert.same(3, vim.tbl_count(spec.plugins))
assert(spec.plugins.bar._.dep ~= true)
assert(spec.plugins.bar.lazy == false)
assert(spec.plugins.dep2._.dep == true)
assert(spec.plugins.dep2.lazy == true)
assert(spec.plugins.dep1._.dep ~= true)
assert(spec.plugins.dep1.lazy == false)
end)

it("handles defaults opt", function()
do
Config.options.defaults.lazy = true
local spec = Plugin.Spec.new({ "foo/bar" })
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert(spec.plugins.bar.lazy == true)
end
do
Config.options.defaults.lazy = false
local spec = Plugin.Spec.new({ "foo/bar" })
Config.plugins = spec.plugins
Plugin.update_state()
assert(spec.plugins.bar.lazy == false)
end
end)

it("handles opt from dep", function()
Config.options.defaults.lazy = false
local spec = Plugin.Spec.new({ "foo/bar", event = "foo" })
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert.same(1, vim.tbl_count(spec.plugins))
assert(spec.plugins.bar._.dep ~= true)
assert(spec.plugins.bar.lazy == true)
end)

it("merges lazy loaders", function()
local tests = {
{ { "foo/bar", event = "mod1" }, { "foo/bar", event = "mod2" } },
{ { "foo/bar", event = { "mod1" } }, { "foo/bar", event = { "mod2" } } },
{ { "foo/bar", event = "mod1" }, { "foo/bar", event = { "mod2" } } },
}
for _, test in ipairs(tests) do
local spec = Plugin.Spec.new(test)
assert(#spec.errors == 0)
assert(vim.tbl_count(spec.plugins) == 1)
assert(type(spec.plugins.bar.event) == "table")
assert(#spec.plugins.bar.event == 2)
assert(vim.tbl_contains(spec.plugins.bar.event, "mod1"))
assert(vim.tbl_contains(spec.plugins.bar.event, "mod2"))
end
end)

it("refuses to merge", function()
local spec = Plugin.Spec.new({
{ "foo/dep1", config = 1 },
{
"foo/bar",
dependencies = { { "foo/dep1", config = 2 }, "foo/dep2" },
},
})
assert(#spec.errors > 0)
end)

-- it("recursive deps", function()
-- local spec = Plugin.Spec.new({
-- "nvim-telescope/telescope.nvim",
-- dependencies = {
-- "nvim-lua/plenary.nvim",
-- { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
-- { "nvim-telescope/telescope-frecency.nvim", dependencies = "kkharji/sqlite.lua" },
-- },
-- })
-- end)
end)

it("handles opt from dep", function()
Config.options.defaults.lazy = false
local spec = Plugin.Spec.new({ "foo/dep1", { "foo/bar", dependencies = { "foo/dep1", "foo/dep2" } } })
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert.same(3, vim.tbl_count(spec.plugins))
Expand All @@ -73,6 +231,7 @@ describe("plugin spec opt", function()
do
Config.options.defaults.lazy = true
local spec = Plugin.Spec.new({ "foo/bar" })
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert(spec.plugins.bar.lazy == true)
Expand All @@ -89,6 +248,7 @@ describe("plugin spec opt", function()
it("handles opt from dep", function()
Config.options.defaults.lazy = false
local spec = Plugin.Spec.new({ "foo/bar", event = "foo" })
assert(#spec.errors == 0)
Config.plugins = spec.plugins
Plugin.update_state()
assert.same(1, vim.tbl_count(spec.plugins))
Expand All @@ -104,6 +264,7 @@ describe("plugin spec opt", function()
}
for _, test in ipairs(tests) do
local spec = Plugin.Spec.new(test)
assert(#spec.errors == 0)
assert(vim.tbl_count(spec.plugins) == 1)
assert(type(spec.plugins.bar.event) == "table")
assert(#spec.plugins.bar.event == 2)
Expand All @@ -113,13 +274,14 @@ describe("plugin spec opt", function()
end)

it("refuses to merge", function()
Plugin.Spec.new({
local spec = Plugin.Spec.new({
{ "foo/dep1", config = 1 },
{
"foo/bar",
dependencies = { { "foo/dep1", config = 2 }, "foo/dep2" },
},
})
assert(#spec.errors > 0)
end)

-- it("recursive deps", function()
Expand Down

0 comments on commit 4bf771a

Please sign in to comment.