dep/lua/dep.lua
2026-01-01 17:04:54 -05:00

152 lines
4 KiB
Lua

local logger = require("dep.log")
local packager = require("dep.package")
local modules = require("dep.modules")
local bench = require("dep.bench")
local lazy = require("dep.lazy")
-- all functions for convenience
local M = {}
--- sync a tree of plugins
---@param tree package[] tree of plugins
---@param cb function? callback
local function synctree(tree, cb)
local progress = 0
local has_errors = false
local function done(err)
progress = progress + 1
has_errors = has_errors or err
if progress == #tree then
if has_errors then
logger:log("error", "there were errors during sync; see :messages or :DepLog for more information")
else
logger:log("update", "synchronized %s %s", #tree, #tree == 1 and "package" or "packages")
end
for _, p in pairs(tree) do
p:reload()
end
if cb then
cb()
end
end
end
-- convert our spec to vim.pack.Spec
local vimspecs = {}
for _, p in ipairs(tree) do
table.insert(vimspecs, {
name = p.name,
src = p.path or p.url,
version = p.commit or p.branch
})
end
vim.pack.add(vimspecs, { load = done, confirm = false })
vim.pack.update(vimspecs, { force = true })
end
--- check if a package should be synced
---@param opts table options
---@param package package package table spec
---@return boolean sync
local function shouldsync(opts, package)
if opts.sync == "never" then
return false
elseif opts.sync == "new" or opts.sync == nil then
return not package.exists
else
return opts.sync == "always"
end
end
--- make comparison for table.sort
---@param a package package spec a
---@param b package package spec b
---@return boolean
local function comp(a, b)
-- NOTE: this doesn't have to be in any real order, it just has to be
-- consistant, thus we can just check if the unicode value of one package
-- id is less than the other
return a.id < b.id
end
-- basically the main function of our program
---@param opts speclist
return function(opts)
M.config_path = debug.getinfo(2, "S").source:sub(2)
logger.pipe = logger:setup()
bench.setup()
lazy.setup()
-- generate doc tags
vim.cmd.helptags(vim.fn.stdpath('data')..'/site/pack/core/opt/dep/doc')
local initialized, err = pcall(function()
packager.set_base_dir(opts.base_dir or vim.fn.stdpath("data").."/site/pack/core/opt/")
bench.mark("load", function()
-- register all packages
local root = packager:new({
"squibid/dep",
url = "https://git.squi.bid/squibid/dep.git",
branch = "pack"
})
if not root then
logger:log("error", "couldn't register root package")
return
end
-- setup all packages and modules
if opts.modules then
modules:setup(opts, nil, M.config_path)
end
packager.register_speclist(opts)
-- sort package dependencies
for _, package in pairs(packager.get_packages()) do
table.sort(package.requirements, comp)
table.sort(package.dependents, comp)
end
-- make sure there arent any circular dependencies
local ok = packager.findcycle(packager.get_packages())
if type(ok) == "table" then
logger:log("error", "found a cycle in the package spec here: %s", vim.inspect(ok))
end
end)
-- load packages
for _, package in pairs(packager.get_packages()) do
package:reload()
end
-- get all package that need syncing
local targets = {}
for _, package in pairs(packager.get_packages()) do
if shouldsync(opts, package) then
table.insert(targets, package)
end
end
-- install all targets
synctree(targets)
end)
if not initialized then
logger:log("error", err)
end
-- add some user commands
vim.api.nvim_create_user_command("DepSync", function()
synctree(packager.get_packages())
end, {})
vim.api.nvim_create_user_command("DepReload", function()
for _, package in pairs(packager.get_packages()) do
package:reload()
end
end, {})
end