Compare commits
10 Commits
a28fd8f2e6
...
71b78bfca4
Author | SHA1 | Date | |
---|---|---|---|
71b78bfca4
|
|||
30cc9a8d50 | |||
e0814ff507 | |||
47796d597e | |||
d6c37cf364 | |||
3013d714e0 | |||
a0bfaefe7c | |||
a3a3652294 | |||
2ccbb7ea74 | |||
dfb1820a8e |
90
lua/dep.lua
90
lua/dep.lua
@ -3,6 +3,7 @@ local git = require('dep.git')
|
|||||||
local fs = require('dep.fs')
|
local fs = require('dep.fs')
|
||||||
local packager = require('dep.package')
|
local packager = require('dep.package')
|
||||||
local h = require('dep.helpers')
|
local h = require('dep.helpers')
|
||||||
|
local spec_man = require("dep.spec")
|
||||||
|
|
||||||
-- all functions for convenience
|
-- all functions for convenience
|
||||||
local M = {}
|
local M = {}
|
||||||
@ -27,68 +28,56 @@ function M.benchmark(name, code, ...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- recurse over all packages and register them
|
--- recurse over all packages and register them
|
||||||
---@param speclist spec[] table of specs
|
---@param speclist speclist table of specs
|
||||||
---@param overrides spec? a package spec that is used to override options
|
---@param overrides spec? a package spec that is used to override options
|
||||||
function M.registertree(speclist, overrides)
|
function M.registertree(speclist, overrides)
|
||||||
overrides = overrides or {}
|
overrides = overrides or {}
|
||||||
|
|
||||||
-- recurse the packages
|
-- recurse the packages
|
||||||
local over = overrides
|
local over = overrides
|
||||||
for _, spec in pairs(speclist) do
|
for _, spec in ipairs(speclist) do
|
||||||
-- make sure the overrides override and take into account the packages spec
|
-- make sure the overrides override and take into account the packages spec
|
||||||
---@diagnostic disable-next-line: missing-fields
|
---@diagnostic disable-next-line: missing-fields
|
||||||
over = {
|
over = {
|
||||||
pin = over.pin or spec.pin,
|
pin = overrides.pin or spec.pin,
|
||||||
disable = over.disable or spec.disable
|
disable = overrides.disable or spec.disable
|
||||||
}
|
}
|
||||||
|
|
||||||
local ok = packager:new(spec, overrides)
|
-- While a package can fail to load we just don't care, it will work itself
|
||||||
|
-- out. The goal is to make sure every plugin that can load does load, not
|
||||||
|
-- keep working plugins from loading because an unrelated one doesn't load.
|
||||||
|
packager:new(spec, over)
|
||||||
|
end
|
||||||
|
|
||||||
-- if erroring print out the spec and the error
|
if speclist.modules then
|
||||||
|
for _, module in ipairs(speclist.modules) do
|
||||||
|
local name = "<unnamed module>"
|
||||||
|
|
||||||
|
if type(module) == "string" then
|
||||||
|
if speclist.modules.prefix then
|
||||||
|
if speclist.modules.prefix:sub(#speclist.modules.prefix) ~= "." and
|
||||||
|
module:sub(1, 2) ~= "." then
|
||||||
|
module = "."..module
|
||||||
|
end
|
||||||
|
module = speclist.modules.prefix..module
|
||||||
|
end
|
||||||
|
|
||||||
|
name, module = module, require(module)
|
||||||
|
end
|
||||||
|
name = module.name or name
|
||||||
|
|
||||||
|
-- allow a module to be a spec
|
||||||
|
if spec_man.check(module, true) ~= false then
|
||||||
|
---@diagnostic disable-next-line: cast-local-type
|
||||||
|
module = { module }
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, err = pcall(M.registertree, module, overrides)
|
||||||
if not ok then
|
if not ok then
|
||||||
error(string.format("(spec=%s)", vim.inspect(spec)))
|
error(string.format("%s <- %s", err, name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- clean out old packages
|
|
||||||
function M.clean()
|
|
||||||
h.uv.fs_scandir(
|
|
||||||
packager.get_base_dir(),
|
|
||||||
vim.schedule_wrap(function(err, handle)
|
|
||||||
if err then
|
|
||||||
logger:log("error", "failed to clean; reason: %s", err)
|
|
||||||
else
|
|
||||||
local queue = {}
|
|
||||||
|
|
||||||
while handle do
|
|
||||||
local name = h.uv.fs_scandir_next(handle)
|
|
||||||
if name then
|
|
||||||
queue[name] = packager.get_base_dir().."/"..name
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- keep packages that still exist
|
|
||||||
for _, package in pairs(packager.get_packages()) do
|
|
||||||
queue[package.name] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
for name, dir in pairs(queue) do
|
|
||||||
local co = coroutine.create(function()
|
|
||||||
local ok = vim.fn.delete(dir, "rf")
|
|
||||||
if ok then
|
|
||||||
logger:log("clean", "deleted %s", name)
|
|
||||||
else
|
|
||||||
logger:log("error", "failed to delete %s", name)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
coroutine.resume(co)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- reload all packages in package table spec
|
--- reload all packages in package table spec
|
||||||
@ -133,7 +122,7 @@ function M.synctree(tree, cb)
|
|||||||
logger:log("update", "synchronized %s %s", #tree, #tree == 1 and "package" or "packages")
|
logger:log("update", "synchronized %s %s", #tree, #tree == 1 and "package" or "packages")
|
||||||
end
|
end
|
||||||
|
|
||||||
M.clean()
|
fs:clean(packager)
|
||||||
M.reload()
|
M.reload()
|
||||||
|
|
||||||
if cb then
|
if cb then
|
||||||
@ -177,7 +166,8 @@ return function(opts)
|
|||||||
-- register all packages
|
-- register all packages
|
||||||
local root = packager:new({
|
local root = packager:new({
|
||||||
"squibid/dep",
|
"squibid/dep",
|
||||||
url = "https://git.squi.bid/dep",
|
url = "https://git.squi.bid/squibid/dep.git",
|
||||||
|
branch = "lazy",
|
||||||
pin = true
|
pin = true
|
||||||
})
|
})
|
||||||
if not root then
|
if not root then
|
||||||
@ -200,7 +190,7 @@ return function(opts)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
-- load packages
|
-- load packages
|
||||||
M.reload()
|
M.reload(false)
|
||||||
|
|
||||||
--- check if a package should be synced
|
--- check if a package should be synced
|
||||||
---@param package table package table spec
|
---@param package table package table spec
|
||||||
@ -259,7 +249,7 @@ return function(opts)
|
|||||||
|
|
||||||
vim.api.nvim_create_user_command("DepClean", function()
|
vim.api.nvim_create_user_command("DepClean", function()
|
||||||
-- clean AND reload to make sure that all old packages are gone
|
-- clean AND reload to make sure that all old packages are gone
|
||||||
M.clean()
|
fs:clean(packager)
|
||||||
M.reload()
|
M.reload()
|
||||||
end, {})
|
end, {})
|
||||||
|
|
||||||
|
@ -3,12 +3,18 @@ local logger = require('dep.log')
|
|||||||
|
|
||||||
local fs = {}
|
local fs = {}
|
||||||
|
|
||||||
|
--- abstract away fs:link to make calling more intuitive
|
||||||
|
---@param package package package to update
|
||||||
|
---@param cb function callback on success
|
||||||
function fs:sync(package, cb)
|
function fs:sync(package, cb)
|
||||||
if not package.exists then
|
if not package.exists then
|
||||||
fs:link(package, cb)
|
fs:link(package, cb)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- create a symlink to a local package
|
||||||
|
---@param package package package to link
|
||||||
|
---@param cb function callback on success
|
||||||
function fs:link(package, cb)
|
function fs:link(package, cb)
|
||||||
h.uv.fs_symlink(package.path, package.dir, nil, function(err, _)
|
h.uv.fs_symlink(package.path, package.dir, nil, function(err, _)
|
||||||
if err then
|
if err then
|
||||||
@ -19,4 +25,48 @@ function fs:link(package, cb)
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- clean out old packages
|
||||||
|
---@param package package any package
|
||||||
|
function fs:clean(package)
|
||||||
|
h.uv.fs_scandir(
|
||||||
|
package.get_base_dir(),
|
||||||
|
vim.schedule_wrap(function(err, handle)
|
||||||
|
if err then
|
||||||
|
logger:log("error", "failed to clean; reason: %s", err)
|
||||||
|
else
|
||||||
|
local queue = {}
|
||||||
|
|
||||||
|
while handle do
|
||||||
|
local name = h.uv.fs_scandir_next(handle)
|
||||||
|
if name then
|
||||||
|
queue[name] = package.get_base_dir().."/"..name
|
||||||
|
else
|
||||||
|
-- if there's a single error bail out
|
||||||
|
logger:log("error", "failed to run clean uv.fs_scandir_next failed")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- keep packages that still exist
|
||||||
|
for _, pkg in ipairs(package.get_packages()) do
|
||||||
|
queue[pkg.name] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- start deleting all of the packages which are chosen for deletion
|
||||||
|
for name, dir in pairs(queue) do
|
||||||
|
local co = coroutine.create(function()
|
||||||
|
local ok = vim.fn.delete(dir, "rf")
|
||||||
|
if ok then
|
||||||
|
logger:log("clean", "deleted %s", name)
|
||||||
|
else
|
||||||
|
logger:log("error", "failed to delete %s", name)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
coroutine.resume(co)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
return fs
|
return fs
|
||||||
|
@ -46,7 +46,6 @@ end
|
|||||||
---@param package package package to install
|
---@param package package package to install
|
||||||
---@param cb function callback
|
---@param cb function callback
|
||||||
function git.install(package, cb)
|
function git.install(package, cb)
|
||||||
|
|
||||||
if not package.enabled then
|
if not package.enabled then
|
||||||
cb()
|
cb()
|
||||||
return
|
return
|
||||||
@ -99,13 +98,9 @@ function git.update(package, cb)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local function logerr(err)
|
|
||||||
logger:log("error", "failed to update %s; reason: %s", package.id, err)
|
|
||||||
end
|
|
||||||
|
|
||||||
proc.git_rev_parse(package.dir, "HEAD", function(err, before)
|
proc.git_rev_parse(package.dir, "HEAD", function(err, before)
|
||||||
if err then
|
if err then
|
||||||
logerr(before)
|
log_err(before)
|
||||||
cb(err)
|
cb(err)
|
||||||
else
|
else
|
||||||
if package.commit then
|
if package.commit then
|
||||||
|
@ -66,7 +66,8 @@ function logger:log(level, message, ...)
|
|||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
if not logger.silent then
|
if not logger.silent then
|
||||||
if level == "error" then
|
if level == "error" then
|
||||||
vim.api.nvim_echo({ { string.format("[dep] %s", message) } }, true, { err = true })
|
vim.api.nvim_echo({ { string.format("[dep] %s", message) } }, true,
|
||||||
|
{ err = true })
|
||||||
elseif logger.stage_colors[level] then
|
elseif logger.stage_colors[level] then
|
||||||
vim.api.nvim_echo({
|
vim.api.nvim_echo({
|
||||||
{ "[dep]", "Identifier" },
|
{ "[dep]", "Identifier" },
|
||||||
@ -78,7 +79,8 @@ function logger:log(level, message, ...)
|
|||||||
|
|
||||||
-- write to the pipe if it's open
|
-- write to the pipe if it's open
|
||||||
if logger.pipe then
|
if logger.pipe then
|
||||||
logger.pipe:write(string.format("[%s] %s:%s: %s\n", os.date("%T"), source.short_src:gsub('.*%/', ''), source.currentline, message))
|
logger.pipe:write(string.format("[%s] %s:%s: %s\n", os.date("%T"),
|
||||||
|
source.short_src:gsub('.*%/', ''), source.currentline, message))
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
@ -1,29 +1,5 @@
|
|||||||
local logger = require('dep.log')
|
local logger = require('dep.log')
|
||||||
|
local spec_man = require("dep.spec")
|
||||||
-- TODO: allow specificying a path to use instead of cloning
|
|
||||||
-- like so: @field path string? path to override other url
|
|
||||||
-- I might have to deal with removing dead links and what not
|
|
||||||
--
|
|
||||||
-- I think it would be best to link the desired directory to the
|
|
||||||
-- neovim package directory, but idk if that will be easy enough
|
|
||||||
-- we'll see
|
|
||||||
|
|
||||||
---@class spec
|
|
||||||
---@field [1] string id
|
|
||||||
---@field setup function? code to run before the package is loaded
|
|
||||||
---@field load function? code to run after the package is loaded
|
|
||||||
---@field config function? code to run after the package is installed/updated
|
|
||||||
---@field lazy function? code to run which determines when the package is loaded
|
|
||||||
---@field as string? overrides the short name of the package which is usually set
|
|
||||||
--- to a substring of all the chars after '/' in spec[1]
|
|
||||||
---@field url string? the url to the git repository hosting the package
|
|
||||||
---@field path string? path to local version of plugin, overrides the url
|
|
||||||
---@field branch string? the branch which the version of the package resides
|
|
||||||
---@field commit string? the commit which the version of the package resides
|
|
||||||
---@field disable boolean? if true disables the package from being loaded
|
|
||||||
---@field pin boolean? if true disables the package from being installed/updated
|
|
||||||
---@field reqs spec|spec[]|string? packages that this package requires
|
|
||||||
---@field deps spec|spec[]|string? packages that depend on this package
|
|
||||||
|
|
||||||
---@class package
|
---@class package
|
||||||
---@field id string id of the package
|
---@field id string id of the package
|
||||||
@ -63,135 +39,6 @@ local root
|
|||||||
---@type package[]
|
---@type package[]
|
||||||
local packages = {}
|
local packages = {}
|
||||||
|
|
||||||
--- check a spec to see if it's correct
|
|
||||||
---@param spec spec|string the specification to check
|
|
||||||
---@return spec|false spec if the spec is ok or false
|
|
||||||
local function check_spec(spec)
|
|
||||||
-- make sure spec is a table
|
|
||||||
if type(spec) == "string" then
|
|
||||||
spec = { spec }
|
|
||||||
end
|
|
||||||
|
|
||||||
-- make sure all the data is correct
|
|
||||||
do -- spec[1]
|
|
||||||
if type(spec[1]) ~= "string" then
|
|
||||||
logger:log("spec", "spec[1] must be a string")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local name = spec[1]:match("^[%w-_.]+/([%w-_.]+)$")
|
|
||||||
if not name then
|
|
||||||
logger:log("spec", 'invalid name "%s"; must be in the format "user/package"', spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.setup ~= nil then -- spec.setup
|
|
||||||
if type(spec.setup) ~= "function" then
|
|
||||||
logger:log("spec", "spec.setup must be a function in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.load ~= nil then -- spec.load
|
|
||||||
if type(spec.load) ~= "function" then
|
|
||||||
logger:log("spec", "spec.load must be a function in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.config ~= nil then -- spec.config
|
|
||||||
if type(spec.config) ~= "function" then
|
|
||||||
logger:log("spec", "spec.config must be a function in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.lazy ~= nil then -- spec.lazy
|
|
||||||
if type(spec.lazy) ~= "function" then
|
|
||||||
logger:log("spec", "spec.lazy must be a function in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.as ~= nil then -- spec.as
|
|
||||||
if type(spec.as) ~= "string" then
|
|
||||||
logger:log("spec", "spec.as must be a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.url ~= nil then -- spec.url
|
|
||||||
if type(spec.url) ~= "string" then
|
|
||||||
logger:log("spec", "spec.url must be a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.path ~= nil then -- spec.path
|
|
||||||
if type(spec.path) ~= "string" then
|
|
||||||
logger:log("spec", "spec.path must be a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.branch ~= nil then -- spec.branch
|
|
||||||
if type(spec.branch) ~= "string" then
|
|
||||||
logger:log("spec", "spec.branch must be a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.commit ~= nil then -- spec.commit
|
|
||||||
if type(spec.commit) ~= "string" then
|
|
||||||
logger:log("spec", "spec.commit must be a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.disable ~= nil then -- spec.disable
|
|
||||||
if type(spec.disable) ~= "boolean" then
|
|
||||||
logger:log("spec", "spec.disable must be a boolean in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.pin ~= nil then -- spec.pin
|
|
||||||
if type(spec.pin) ~= "boolean" then
|
|
||||||
logger:log("spec", "spec.pin must be a boolean in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.reqs ~= nil then -- spec.reqs
|
|
||||||
local is = type(spec.reqs)
|
|
||||||
if is ~= "table" and is ~= "string" then
|
|
||||||
logger:log("spec", "spec.reqs must be a table or a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- turn an id into a spec
|
|
||||||
if (is == "string") then
|
|
||||||
spec.reqs = { spec.reqs }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if spec.deps ~= nil then -- spec.deps
|
|
||||||
local is = type(spec.deps)
|
|
||||||
if is ~= "table" and is ~= "string" then
|
|
||||||
logger:log("spec", "spec.deps must be a table or a string in %s", spec[1])
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- turn an id into a spec
|
|
||||||
if (is == "string") then
|
|
||||||
spec.deps = { spec.deps }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return spec
|
|
||||||
end
|
|
||||||
|
|
||||||
--- tell the parent it has a child and the child it has a parent
|
--- tell the parent it has a child and the child it has a parent
|
||||||
---@param parent package? parent package if nil defaults to self
|
---@param parent package? parent package if nil defaults to self
|
||||||
---@param child package child package
|
---@param child package child package
|
||||||
@ -218,7 +65,7 @@ function package:new(spec, overrides)
|
|||||||
overrides = overrides or {}
|
overrides = overrides or {}
|
||||||
|
|
||||||
-- ensure that the spec is ok
|
-- ensure that the spec is ok
|
||||||
local new_spec = check_spec(spec)
|
local new_spec = spec_man.check(spec_man.correct_spec(spec))
|
||||||
if new_spec == false then
|
if new_spec == false then
|
||||||
logger:log("spec", vim.inspect(spec))
|
logger:log("spec", vim.inspect(spec))
|
||||||
logger:log("error", "spec check failed, check DepLog")
|
logger:log("error", "spec check failed, check DepLog")
|
||||||
@ -257,7 +104,7 @@ function package:new(spec, overrides)
|
|||||||
packages[id] = o
|
packages[id] = o
|
||||||
end
|
end
|
||||||
|
|
||||||
o.name = spec.as or o.name or id:match("^[%w-_.]+/([%w-_.]+)$")
|
o.name = spec.as or o.name or spec_man.get_name(spec)
|
||||||
o.url = spec.url or o.url or ("https://github.com/"..id..".git")
|
o.url = spec.url or o.url or ("https://github.com/"..id..".git")
|
||||||
o.path = spec.path and vim.fs.normalize(spec.path) or spec.path
|
o.path = spec.path and vim.fs.normalize(spec.path) or spec.path
|
||||||
o.branch = spec.branch or o.branch
|
o.branch = spec.branch or o.branch
|
||||||
@ -359,7 +206,7 @@ function package.get_root()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- get the packages in dep
|
--- get the packages in dep
|
||||||
---@return package root
|
---@return package[] packages
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function package.get_packages()
|
function package.get_packages()
|
||||||
return packages
|
return packages
|
||||||
|
@ -122,7 +122,8 @@ function proc.git_resolve_branch(url, branch, cb)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
return proc
|
return proc
|
||||||
|
207
lua/dep/spec.lua
Normal file
207
lua/dep/spec.lua
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
local logger = require("dep.log")
|
||||||
|
|
||||||
|
---@class modules
|
||||||
|
---@field prefix string prefix to prepend to the modules
|
||||||
|
---@field [integer] string list of all modules to load
|
||||||
|
|
||||||
|
---@class speclist
|
||||||
|
---@field modules modules a list of modules
|
||||||
|
---@field [integer] spec a spec
|
||||||
|
|
||||||
|
---@class spec
|
||||||
|
---@field [1] string id
|
||||||
|
---@field setup function? code to run before the package is loaded
|
||||||
|
---@field load function? code to run after the package is loaded
|
||||||
|
---@field config function? code to run after the package is installed/updated
|
||||||
|
---@field lazy function? code to run which determines when the package is loaded
|
||||||
|
---@field as string? overrides the short name of the package which is usually set
|
||||||
|
--- to a substring of all the chars after "/" in spec[1]
|
||||||
|
---@field url string? the url to the git repository hosting the package
|
||||||
|
---@field path string? path to local version of plugin, overrides the url
|
||||||
|
---@field branch string? the branch which the version of the package resides
|
||||||
|
---@field commit string? the commit which the version of the package resides
|
||||||
|
---@field disable boolean? if true disables the package from being loaded
|
||||||
|
---@field pin boolean? if true disables the package from being installed/updated
|
||||||
|
---@field reqs spec|spec[]|string? packages that this package requires
|
||||||
|
---@field deps spec|spec[]|string? packages that depend on this package
|
||||||
|
local spec = {}
|
||||||
|
|
||||||
|
--- check if a string seems to be a url
|
||||||
|
---@param url string the "url" to check
|
||||||
|
---@return boolean is_url
|
||||||
|
local function is_url(url)
|
||||||
|
if url:sub(1, 8) == "https://" or
|
||||||
|
url:sub(1, 7) == "http://" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- get the proper name of a spec
|
||||||
|
---@return string spec.name
|
||||||
|
function spec:get_name()
|
||||||
|
return self[1]:match("^[%w-_.]+/([%w-_.]+)$")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- attempt to correct a spec
|
||||||
|
---@param self table|string spec to check
|
||||||
|
---@return spec spec
|
||||||
|
function spec:correct_spec()
|
||||||
|
if type(self) == "string" then
|
||||||
|
return { self }
|
||||||
|
elseif type(self) == "table" then
|
||||||
|
repeat
|
||||||
|
if type(self[1]) ~= "string" then
|
||||||
|
self = self[1]
|
||||||
|
end
|
||||||
|
until type(self[1]) == "string"
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-- store the logger temporarily to prevent any logs from being printed when
|
||||||
|
-- being run in silent mode
|
||||||
|
local __logger
|
||||||
|
|
||||||
|
--- check a spec to see if it's correct
|
||||||
|
---@param self table spec to check
|
||||||
|
---@param silent boolean? should the checker report errors
|
||||||
|
---@return spec|false spec if the spec is ok or false
|
||||||
|
function spec:check(silent)
|
||||||
|
if silent == true then
|
||||||
|
__logger = logger
|
||||||
|
logger = { log = function() end }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- make sure all the data is correct
|
||||||
|
do -- spec[1]
|
||||||
|
if type(self[1]) ~= "string" then
|
||||||
|
logger:log("spec", "spec[1] must be a string")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = spec.get_name(self)
|
||||||
|
if not name then
|
||||||
|
logger:log("spec", 'invalid name "%s"; must be in the format "user/package"', self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.setup ~= nil then -- spec.setup
|
||||||
|
if type(self.setup) ~= "function" then
|
||||||
|
logger:log("spec", "spec.setup must be a function in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.load ~= nil then -- spec.load
|
||||||
|
if type(self.load) ~= "function" then
|
||||||
|
logger:log("spec", "spec.load must be a function in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.config ~= nil then -- spec.config
|
||||||
|
if type(self.config) ~= "function" then
|
||||||
|
logger:log("spec", "spec.config must be a function in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.lazy ~= nil then -- spec.lazy
|
||||||
|
if type(self.lazy) ~= "function" then
|
||||||
|
logger:log("spec", "spec.lazy must be a function in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.as ~= nil then -- spec.as
|
||||||
|
if type(self.as) ~= "string" then
|
||||||
|
logger:log("spec", "spec.as must be a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.url ~= nil then -- spec.url
|
||||||
|
if type(self.url) ~= "string" then
|
||||||
|
logger:log("spec", "spec.url must be a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
elseif not is_url(self.url) then -- more strict checking on urls
|
||||||
|
logger:log("spec", "spec.url must be a properly formatted url in %s",
|
||||||
|
self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.path ~= nil then -- spec.path
|
||||||
|
if type(self.path) ~= "string" then
|
||||||
|
logger:log("spec", "spec.path must be a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
elseif not vim.fn.isdirectory(self.path) then
|
||||||
|
logger:log("spec", "spec.path must be a valid directory in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.branch ~= nil then -- spec.branch
|
||||||
|
if type(self.branch) ~= "string" then
|
||||||
|
logger:log("spec", "spec.branch must be a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.commit ~= nil then -- spec.commit
|
||||||
|
if type(self.commit) ~= "string" then
|
||||||
|
logger:log("spec", "spec.commit must be a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.disable ~= nil then -- spec.disable
|
||||||
|
if type(self.disable) ~= "boolean" then
|
||||||
|
logger:log("spec", "spec.disable must be a boolean in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.pin ~= nil then -- spec.pin
|
||||||
|
if type(self.pin) ~= "boolean" then
|
||||||
|
logger:log("spec", "spec.pin must be a boolean in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.reqs ~= nil then -- spec.reqs
|
||||||
|
local is = type(self.reqs)
|
||||||
|
if is ~= "table" and is ~= "string" then
|
||||||
|
logger:log("spec", "spec.reqs must be a table or a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- turn an id into a spec
|
||||||
|
if (is == "string") then
|
||||||
|
self.reqs = { self.reqs }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.deps ~= nil then -- spec.deps
|
||||||
|
local is = type(self.deps)
|
||||||
|
if is ~= "table" and is ~= "string" then
|
||||||
|
logger:log("spec", "spec.deps must be a table or a string in %s", self[1])
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- turn an id into a spec
|
||||||
|
if (is == "string") then
|
||||||
|
self.deps = { self.deps }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if silent == true then
|
||||||
|
logger = __logger
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
return spec
|
Reference in New Issue
Block a user