aboutsummaryrefslogtreecommitdiff
path: root/src/lib/builder.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/builder.lua')
-rw-r--r--src/lib/builder.lua111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/lib/builder.lua b/src/lib/builder.lua
new file mode 100644
index 0000000..7390257
--- /dev/null
+++ b/src/lib/builder.lua
@@ -0,0 +1,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