diff --git a/lua/dep/package.lua b/lua/dep/package.lua index 83b8768..d1a1161 100644 --- a/lua/dep/package.lua +++ b/lua/dep/package.lua @@ -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 diff --git a/lua/dep/spec.lua b/lua/dep/spec.lua new file mode 100644 index 0000000..1e5b467 --- /dev/null +++ b/lua/dep/spec.lua @@ -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