refactor: extract spec

This commit is contained in:
2025-05-06 17:12:43 -05:00
parent 3013d714e0
commit d6c37cf364
2 changed files with 185 additions and 174 deletions

View File

@ -1,29 +1,5 @@
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_man = require("dep.spec")
---@class package
---@field id string id of the package
@ -63,153 +39,6 @@ local root
---@type package[]
local packages = {}
--- 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
--- 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
elseif not is_url(spec.url) then -- more strict checking on urls
logger:log("spec", "spec.url must be a properly formatted url 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
elseif not vim.fn.isdirectory(spec.path) then
logger:log("spec", "spec.path must be a valid directory 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
---@param parent package? parent package if nil defaults to self
---@param child package child package
@ -236,7 +65,7 @@ function package:new(spec, overrides)
overrides = overrides or {}
-- ensure that the spec is ok
local new_spec = check_spec(spec)
local new_spec = spec_man.check(spec)
if new_spec == false then
logger:log("spec", vim.inspect(spec))
logger:log("error", "spec check failed, check DepLog")
@ -275,7 +104,7 @@ function package:new(spec, overrides)
packages[id] = o
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.path = spec.path and vim.fs.normalize(spec.path) or spec.path
o.branch = spec.branch or o.branch

182
lua/dep/spec.lua Normal file
View File

@ -0,0 +1,182 @@
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
--- check a spec to see if it's correct
---@param self table|string spec to check
---@return spec|false spec if the spec is ok or false
function spec:check()
-- make sure spec is a table
if type(self) == "string" then
self = { self }
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
return self
end
return spec