1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author ruki
-- @file main.lua
--
-- imports
import("core.base.option")
import("core.project.project")
import("actions.create.template", {rootdir = os.programdir()})
-- validate template component against path traversal
function _validate_template_component(name, value)
if #value == 0 or value == "." or value == ".."
or value:find("/", 1, true) or value:find("\\", 1, true)
or value:find(":", 1, true) or value:find("\0", 1, true) then
raise("invalid %s: %s!", name, value)
end
end
-- get template language from template id
function _get_language_from_template(templateid)
local lang = option.get("language")
if lang then
_validate_template_component("language", lang)
end
if not templateid or not lang or template.templatedir(lang, templateid) then
return lang
end
local langs = template.languages_for_template(templateid)
if #langs == 1 then
return langs[1]
elseif #langs > 1 then
raise("template(%s): please pass -l/--language, supported languages: %s", templateid, table.concat(langs, ", "))
end
return lang
end
-- get template id from command line options
function _get_templateid()
local templateid = option.get("template")
_validate_template_component("template id", templateid)
return templateid
end
-- get target name from command line options
function _get_targetname()
return option.get("target") or path.basename(project.directory()) or "demo"
end
-- create project from template
function _create_project(lang, templateid, targetname)
assert(targetname ~= ".", "you should specify ${red}-P${reset} instead of directly using ${red}.${reset}")
assert(lang, "no language!")
assert(templateid, "no template id!")
-- get project directory
local projectdir = path.absolute(option.get("project") or path.join(os.curdir(), targetname))
if not os.isdir(projectdir) then
-- make the project directory if not exists
os.mkdir(projectdir)
end
-- xmake.lua exists?
if os.isfile(path.join(projectdir, "xmake.lua")) and not option.get("force") then
raise("project (${underline}%s/xmake.lua${reset}) exists!", projectdir)
end
-- empty project?
os.tryrm(path.join(projectdir, ".xmake"))
if not os.emptydir(projectdir) and not option.get("force") then
-- otherwise, check whether it is empty
raise("project directory (${underline}%s${reset}) is not empty!", projectdir)
end
-- enter the project directory
os.cd(projectdir)
-- create project
local sourcedir = template.templatedir(lang, templateid)
assert(sourcedir, "template(%s/%s): not found!", lang, templateid)
-- get the builtin variables
local builtinvars = template.builtinvars(targetname)
-- copy template project files
local createdfiles = template.copy_files(sourcedir, projectdir)
-- copy the default .gitignore
if not os.isfile(path.join(projectdir, ".gitignore")) then
os.cp(path.join(os.programdir(), "scripts", "gitignore"), path.join(projectdir, ".gitignore"))
table.insert(createdfiles, path.join(projectdir, ".gitignore"))
end
-- replace template variables
template.replace_variables_in_files(createdfiles, builtinvars)
-- done
table.sort(createdfiles)
for _, file in ipairs(createdfiles) do
cprint(" ${green}[+]: ${clear}%s", path.relative(file, projectdir))
end
end
function main()
os.cd(os.workingdir())
local targetname = _get_targetname()
local templateid = _get_templateid()
local lang = _get_language_from_template(templateid)
-- create project from template
cprint("${bright}create %s ...", targetname)
_create_project(lang, templateid, targetname)
cprint("${color.success}create ok!")
end
|