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
|
Builder = {}
function Builder:from_template(path)
local builder = {
template = loadfile(
path,
nil,
Env.Sandbox {
Template = Template
}
)(),
source = Path:new(path),
}
builder.source_directory = builder.source:parent()
setmetatable(builder, self)
self.__index = self
local argument_template = {
strict = true,
{ name = "target" },
{ name = "template", description = "some description", kind = "property", required = true },
};
for key, value in pairs(builder.template.options) do
argument_template[#argument_template + 1] = value
end
local args = require('arg')(argument_template)
for key, _ in pairs(builder.template.options) do
builder.template.arguments[key] = args[key]
end
return builder
end
function Builder:entries()
local entries = {}
for _, value in ipairs(self.template.files) do
entries[#entries + 1] = {
path = Path:new(value.path),
env = value.env,
}
end
for _, value in ipairs(self.template.directories) do
for entry in Path:new(value.path):children() do
entries[#entries + 1] = {
path = entry,
env = value.env,
}
end
end
local i = 1
return function()
local value = entries[i]
i = i + 1
return value
end
end
function Builder:build(args)
local instance = Instance:new()
for entry in self:entries() do
instance:register(
entry.path,
entry.path.is_directory and nil or self:process_file(entry)
)
end
return instance
end
function Builder:process_file(file)
local f = (self.source_directory / file.path):open("r")
local raw = f:read("*all")
f:close()
local content = ''
for _, split in ipairs(raw:split_into_template_blocks()) do
if split.kind == 'text' then
content = content .. split.content
else
local func, err = load(
'return ' .. split.content,
'macro ' .. tostring(file.path),
't',
Env.Sandbox(file.env)
)
if err then
error(err)
end
local value = func()
if type(value) == 'function' then
content = content .. tostring(value())
else
content = content .. tostring(value)
end
end
end
return content
end
|