summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-03-03 23:42:58 +0800
committerruki <[email protected]>2026-03-03 23:42:58 +0800
commit5abb591b562a07ef59213cc1ddc8b74dd181f7ac (patch)
treeec59101e7cf6b986aa3de562f4d2efcc98078963
parentf23220b1abbb51882f1912533b397f2f2d38b66b (diff)
get templates from xmake-repo
-rw-r--r--xmake/actions/create/main.lua86
-rw-r--r--xmake/actions/create/template.lua38
2 files changed, 117 insertions, 7 deletions
diff --git a/xmake/actions/create/main.lua b/xmake/actions/create/main.lua
index fc75e06a4..72b69f3b2 100644
--- a/xmake/actions/create/main.lua
+++ b/xmake/actions/create/main.lua
@@ -63,7 +63,13 @@ function _get_targetname()
end
-- list all supported templates for each language
+--
+-- output is in tree format:
+-- <source>
+-- <language>
+-- <template>
function _list_templates(lang_filter)
+ local rootinfos = template.rootinfos()
local languages = template.languages()
if lang_filter then
_validate_template_component("language", lang_filter)
@@ -72,15 +78,89 @@ function _list_templates(lang_filter)
end
languages = {lang_filter}
end
+
+ -- map a template directory to its root meta (repo/global/builtin)
+ local rootinfo_of = function (dir)
+ if not dir then
+ return
+ end
+ dir = path.absolute(dir)
+ for _, info in ipairs(rootinfos) do
+ local rootdir = path.absolute(info.dir)
+ if dir == rootdir or dir:startswith(rootdir .. path.sep()) then
+ return info
+ end
+ end
+ end
+
+ local sourcekey_of = function (info)
+ if not info then
+ return "unknown"
+ end
+ if info.kind == "repo" then
+ return "repo:" .. info.name
+ end
+ return info.kind or "unknown"
+ end
+
+ local groups = {}
for _, lang in ipairs(languages) do
- cprint("${bright}%s${reset}", lang)
local templates = template.templates(lang)
if templates and #templates > 0 then
for _, name in ipairs(templates) do
- cprint(" - %s", name)
+ local sourcedir = template.templatedir(lang, name)
+ local info = rootinfo_of(sourcedir)
+ local key = sourcekey_of(info)
+ local group = groups[key]
+ if not group then
+ group = {info = info, langs = {}}
+ groups[key] = group
+ end
+ group.langs[lang] = group.langs[lang] or {}
+ table.insert(group.langs[lang], name)
+ end
+ end
+ end
+
+ local groupkeys = {}
+ local inserted = {}
+ for _, info in ipairs(rootinfos) do
+ local key = sourcekey_of(info)
+ if groups[key] and not inserted[key] then
+ table.insert(groupkeys, key)
+ inserted[key] = true
+ end
+ end
+ if groups["unknown"] and not inserted["unknown"] then
+ table.insert(groupkeys, "unknown")
+ inserted["unknown"] = true
+ end
+
+ for _, key in ipairs(groupkeys) do
+ local group = groups[key]
+ if group then
+ local info = group.info
+ if info and info.kind == "repo" then
+ local branch = info.branch and (" " .. info.branch) or ""
+ cprint("${bright}%s${reset}: %s%s", info.name, info.url or "", branch)
+ else
+ cprint("${bright}%s${reset}", (info and info.kind) or "unknown")
+ end
+ local langs = {}
+ for lang, _ in pairs(group.langs) do
+ table.insert(langs, lang)
+ end
+ table.sort(langs)
+ for _, lang in ipairs(langs) do
+ cprint(" ${bright}%s${reset}", lang)
+ local templates = group.langs[lang]
+ table.sort(templates)
+ for _, name in ipairs(templates) do
+ print(" - %s", name)
+ end
end
+ print("")
end
- print("")
end
end
diff --git a/xmake/actions/create/template.lua b/xmake/actions/create/template.lua
index 701786c48..26b4672a0 100644
--- a/xmake/actions/create/template.lua
+++ b/xmake/actions/create/template.lua
@@ -22,6 +22,7 @@
import("core.base.global")
import("core.base.hashset")
import("core.language.language")
+import("core.package.repository")
-- some builtin template variables in xmake.lua
function builtinvars(targetname)
@@ -29,16 +30,45 @@ function builtinvars(targetname)
FAQ = function() return io.readfile(path.join(os.programdir(), "scripts", "faq.lua")) end}
end
--- get template root directories
-function rootdirs()
+-- get all template roots with extra meta information
+--
+-- priority:
+-- 1. repo: <global-repo>/templates
+-- 2. global: <globaldir>/templates
+-- 3. builtin: <programdir>/templates
+function rootinfos()
local results = {}
+
+ -- get template directories from global repositories
+ local repos = repository.repositories(true)
+ if repos then
+ local repolist = repos
+ table.sort(repolist, function (a, b) return a:name() < b:name() end)
+ for _, repo in ipairs(repolist) do
+ local dir = path.join(repo:directory(), "templates")
+ if os.isdir(dir) then
+ table.insert(results, {kind = "repo", name = repo:name(), url = repo:url(), branch = repo:branch(), dir = dir})
+ end
+ end
+ end
+
+ -- get template directories from global and builtin
local dir = path.join(global.directory(), "templates")
if os.isdir(dir) then
- table.insert(results, dir)
+ table.insert(results, {kind = "global", dir = dir})
end
dir = path.join(os.programdir(), "templates")
if os.isdir(dir) then
- table.insert(results, dir)
+ table.insert(results, {kind = "builtin", dir = dir})
+ end
+ return results
+end
+
+-- get template root directories
+function rootdirs()
+ local results = {}
+ for _, info in ipairs(rootinfos()) do
+ table.insert(results, info.dir)
end
return results
end