diff options
Diffstat (limited to 'xmake/actions/create/template.lua')
| -rw-r--r-- | xmake/actions/create/template.lua | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/xmake/actions/create/template.lua b/xmake/actions/create/template.lua index 1279c1d35..ac39e2ff8 100644 --- a/xmake/actions/create/template.lua +++ b/xmake/actions/create/template.lua @@ -22,7 +22,7 @@ import("core.base.global") import("core.base.hashset") import("core.language.language") -import("core.package.repository") +import("core.package.addon") -- some builtin template variables in xmake.lua function builtinvars(targetname) @@ -33,19 +33,16 @@ end -- get all template roots with extra meta information -- -- priority: --- 1. repo: <global-repo>/templates (including builtin repo templates) +-- 1. addon: <globaldir>/addons/<name>/<version>/templates -- 2. global: <globaldir>/templates +-- 3. builtin: <programdir>/templates function rootinfos() local results = {} - -- get template directories from global repositories - local repos = repository.repositories({global = true, network = false}) - if repos then - for _, repo in ipairs(repos) do - local templatesdir = path.join(repo:directory(), "templates") - if os.isdir(templatesdir) then - table.insert(results, {kind = "repo", name = repo:name(), url = repo:url(), branch = repo:branch(), dir = templatesdir}) - end + -- get template directories from the installed addons + for _, addoninfo in ipairs(addon.payloadinfos("templates")) do + if os.isdir(addoninfo.dir) then + table.insert(results, {kind = "addon", name = addoninfo.name, version = addoninfo.version, dir = addoninfo.dir}) end end @@ -54,9 +51,31 @@ function rootinfos() if os.isdir(dir) then table.insert(results, {kind = "global", dir = dir}) end + dir = path.join(os.programdir(), "templates") + if os.isdir(dir) then + table.insert(results, {kind = "builtin", dir = dir}) + end return results end +-- get the root information of the given template directory +-- +-- @param templatedir the template directory, e.g. <programdir>/templates/c/console +-- @return the root information, @see rootinfos +-- +function rootinfo_of(templatedir) + if not templatedir then + return + end + templatedir = path.absolute(templatedir) + for _, info in ipairs(rootinfos()) do + local rootdir = path.absolute(info.dir) + if templatedir == rootdir or templatedir:startswith(rootdir .. path.sep()) then + return info + end + end +end + -- get template root directories function rootdirs() local results = {} @@ -83,6 +102,23 @@ end function templatedir(lang, templateid) assert(lang) assert(templateid) + + -- the qualified template of an addon, e.g. @addon/basic-templates/verilator.console + -- + -- @note the template ids are not namespaced, we only need it to disambiguate the conflicts + -- + if templateid:startswith("@addon/") then + local referenceinfo = addon.resolve_reference(templateid, "/", "templates") + local subdir = _templateid_subdir(referenceinfo.name) + if subdir then + local dir = path.join(referenceinfo.dir, lang, subdir) + if os.isfile(path.join(dir, "xmake.lua")) then + return dir + end + end + return + end + for _, rootdir in ipairs(rootdirs()) do local subdir = _templateid_subdir(templateid) if subdir then @@ -154,11 +190,21 @@ function languages() return results end +-- get the reference of the given template, e.g. @addon/basic-templates/verilator.console +function _template_reference(rootinfo, templateid) + if rootinfo.kind == "addon" then + return string.format("@addon/%s/%s", rootinfo.name, templateid) + end + return path.join(rootinfo.dir, templateid) +end + -- get all templates for the given language function templates(lang) assert(lang) local found = hashset.new() - for _, rootdir in ipairs(rootdirs()) do + local providers = {} + for _, rootinfo in ipairs(rootinfos()) do + local rootdir = rootinfo.dir local templateroot = path.join(rootdir, lang) local configfiles = os.files(path.join(templateroot, "**", "xmake.lua")) if configfiles then @@ -182,7 +228,17 @@ function templates(lang) end if ok then table.insert(accepted, item.dir) - found:insert((item.relpath:gsub("[/\\]", "."))) + local templateid = (item.relpath:gsub("[/\\]", ".")) + -- the templates are not namespaced, so we need to report the conflicts of the addons, + -- otherwise we do not know which template will be used + local provider = providers[templateid] + if provider and (provider.kind == "addon" or rootinfo.kind == "addon") then + wprint("template(%s/%s) conflicts, we will use the first one!\n -> %s\n -> %s\nplease use the qualified template id to disambiguate them.", + lang, templateid, _template_reference(provider, templateid), _template_reference(rootinfo, templateid)) + else + providers[templateid] = rootinfo + found:insert(templateid) + end end end end |
