summaryrefslogtreecommitdiff
path: root/xmake/actions/create/template.lua
diff options
context:
space:
mode:
Diffstat (limited to 'xmake/actions/create/template.lua')
-rw-r--r--xmake/actions/create/template.lua80
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