Initial commit 🎉
* Extracted core module and default loaders from Restia * Set up luarocks * Set up busted, luacheck and luacov
This commit is contained in:
commit
66e459225f
15 changed files with 284 additions and 0 deletions
5
.busted
Normal file
5
.busted
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
return {
|
||||||
|
_all = {
|
||||||
|
lpath = "?.lua;?/init.lua"
|
||||||
|
}
|
||||||
|
}
|
3
config.ld
Normal file
3
config.ld
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
readme = 'readme.md'
|
||||||
|
format = 'discount'
|
||||||
|
file = { 'glass.lua', 'glass' }
|
27
glass-dev-1.rockspec
Normal file
27
glass-dev-1.rockspec
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package = "glass"
|
||||||
|
version = "dev-1"
|
||||||
|
source = {
|
||||||
|
url = "git+https://github.com/darkwiiplayer/glass"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
homepage = "https://github.com/darkwiiplayer/glass",
|
||||||
|
license = "Unlicense"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lfs"
|
||||||
|
}
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
glass = "glass.lua",
|
||||||
|
["glass.cosmo"] = "glass/cosmo.lua",
|
||||||
|
["glass.discount"] = "glass/discount.lua",
|
||||||
|
["glass.json"] = "glass/json.lua",
|
||||||
|
["glass.lua"] = "glass/lua.lua",
|
||||||
|
["glass.moonhtml"] = "glass/moonhtml.lua",
|
||||||
|
["glass.moonhtml_cosmo"] = "glass/moonhtml_cosmo.lua",
|
||||||
|
["glass.raw"] = "glass/raw.lua",
|
||||||
|
["glass.skooma"] = "glass/skooma.lua",
|
||||||
|
["glass.yaml"] = "glass/yaml.lua"
|
||||||
|
}
|
||||||
|
}
|
51
glass.lua
Normal file
51
glass.lua
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
--- Loads configurations from files on demand.
|
||||||
|
-- @author DarkWiiPlayer
|
||||||
|
-- @license Unlicense
|
||||||
|
|
||||||
|
local lfs = require 'lfs'
|
||||||
|
|
||||||
|
local config = {}
|
||||||
|
|
||||||
|
local __metatable = {}
|
||||||
|
function __metatable:__index(index)
|
||||||
|
if type(index)~="string" then return nil end
|
||||||
|
local path = self.__dir..'/'..index
|
||||||
|
local attributes = lfs.attributes(path)
|
||||||
|
if attributes and attributes.mode=='directory' then
|
||||||
|
return config.bind(path, self.__loaders)
|
||||||
|
else
|
||||||
|
for _, loader in ipairs(self.__loaders) do
|
||||||
|
local result = loader(path)
|
||||||
|
if result then
|
||||||
|
rawset(self, index, result)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil, "Could not load: "..tostring(index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Binds a table to a config directory.
|
||||||
|
-- The returned table maps keys to configurations, which are handled by
|
||||||
|
-- different "loaders". loaders are handlers that try loading a config entry in
|
||||||
|
-- a certain format and are tried sequentially until one succeeds. If no
|
||||||
|
-- loader matches, nil is returned.
|
||||||
|
-- @tparam string dir Path to the directory to look in.
|
||||||
|
-- @tparam table loaders A table of loaders to use when attempting to load a configuration entry.
|
||||||
|
-- @treturn table config A table that maps to the config directory
|
||||||
|
-- @usage
|
||||||
|
-- local config = glass.bind 'configurations'
|
||||||
|
-- main_config.foo.bar
|
||||||
|
-- -- Loads some file like foo.json or foo.yaml
|
||||||
|
-- -- in the configurations directory
|
||||||
|
function config.bind(dir, loaders)
|
||||||
|
if type(dir)~="string" then
|
||||||
|
error(string.format("bad argument #1 to '%s' (string expected, got %s)", debug.getinfo(1).name, type(loaders)), 2)
|
||||||
|
end
|
||||||
|
if type(loaders)~="table" then
|
||||||
|
error(string.format("bad argument #2 to '%s' (table expected, got %s)", debug.getinfo(1).name, type(loaders)), 2)
|
||||||
|
end
|
||||||
|
return setmetatable({__dir=dir, __loaders=loaders}, __metatable)
|
||||||
|
end
|
||||||
|
|
||||||
|
return config
|
19
glass/cosmo.lua
Normal file
19
glass/cosmo.lua
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
--- Loader for cosmo templates.
|
||||||
|
-- @module restia.config.cosmo
|
||||||
|
|
||||||
|
local cosmo = require 'cosmo'
|
||||||
|
local readfile = require 'restia.config.readfile'
|
||||||
|
|
||||||
|
--- Loads a cosmo template from a file and returns the compiled template.
|
||||||
|
-- Returns nil if no template can be found.
|
||||||
|
-- @treturn function Template
|
||||||
|
-- @function load
|
||||||
|
return function(name)
|
||||||
|
name = tostring(name) .. '.cosmo'
|
||||||
|
local text = readfile(name)
|
||||||
|
if text then
|
||||||
|
return assert(cosmo.compile(text, name))
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
23
glass/discount.lua
Normal file
23
glass/discount.lua
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
--- Loader for markdown files using lua-discount
|
||||||
|
-- @module restia.config.discount
|
||||||
|
|
||||||
|
local discount = require 'discount'
|
||||||
|
|
||||||
|
--- Loads a markdown file and converts it into HTML.
|
||||||
|
-- Returns a function that returns a static string
|
||||||
|
-- to keep compatible with restia template semantics.
|
||||||
|
-- HTML-Conversion only happens once during loading.
|
||||||
|
-- @treturn function Template
|
||||||
|
-- @function load
|
||||||
|
return function(name)
|
||||||
|
name = tostring(name) .. '.md'
|
||||||
|
local file = io.open(name)
|
||||||
|
if file then
|
||||||
|
local html = discount(file:read("*a"))
|
||||||
|
return function()
|
||||||
|
return html
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
18
glass/json.lua
Normal file
18
glass/json.lua
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--- Loader for JSON-Data using Lua-CJSON
|
||||||
|
-- @module restia.config.json
|
||||||
|
|
||||||
|
local json = require 'cjson'
|
||||||
|
local readfile = require 'restia.cofnig.readfile'
|
||||||
|
|
||||||
|
--- Loads a JSON-File and returns a corresponding Lua table.
|
||||||
|
-- May return non-table values for invalid JSON,
|
||||||
|
-- as CJSON supports other types than Object at
|
||||||
|
-- the top-level of the JSON file.
|
||||||
|
-- @treturn table JSON-Data
|
||||||
|
-- @function load
|
||||||
|
return function(file)
|
||||||
|
local raw = readfile(file..'.json')
|
||||||
|
if raw then
|
||||||
|
return json.decode(raw)
|
||||||
|
end
|
||||||
|
end
|
13
glass/lua.lua
Normal file
13
glass/lua.lua
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
--- Loader for Lua files
|
||||||
|
-- @module restia.config.lua
|
||||||
|
|
||||||
|
--- Loads and compiles a Lua file and runs it.
|
||||||
|
-- Returns the result of running the Lua file.
|
||||||
|
-- If running the code immediately is not desired,
|
||||||
|
-- it has to be returned as a function.
|
||||||
|
-- @return The result of the Lua file after running it
|
||||||
|
-- @function load
|
||||||
|
return function(name)
|
||||||
|
local f = loadfile(name..'.lua')
|
||||||
|
return f and f() or nil
|
||||||
|
end
|
18
glass/moonhtml.lua
Normal file
18
glass/moonhtml.lua
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--- Loader for MoonHTML files
|
||||||
|
-- @module restia.config.moonhtml
|
||||||
|
|
||||||
|
|
||||||
|
local template = require 'restia.template'
|
||||||
|
|
||||||
|
--- Loads and compiles a moonhtml template.
|
||||||
|
-- @treturn function template
|
||||||
|
-- @function load
|
||||||
|
return function(name)
|
||||||
|
name = tostring(name) .. '.moonhtml'
|
||||||
|
local file = io.open(name)
|
||||||
|
if file then
|
||||||
|
return assert(template.loadmoon(file:read("*a"), name))
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
13
glass/raw.lua
Normal file
13
glass/raw.lua
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
--- Loader for plain files
|
||||||
|
-- @module restia.config.readfile
|
||||||
|
|
||||||
|
--- Loads a normal file as a string.
|
||||||
|
-- @treturn string The content of the file
|
||||||
|
-- @function load
|
||||||
|
return function(path)
|
||||||
|
local f = io.open(path)
|
||||||
|
if not f then return end
|
||||||
|
local result = f:read("*a")
|
||||||
|
f:close()
|
||||||
|
return result
|
||||||
|
end
|
18
glass/skooma.lua
Normal file
18
glass/skooma.lua
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--- Loader for Skooma templates
|
||||||
|
-- @module restia.config.skooma
|
||||||
|
|
||||||
|
local skooma = require 'skooma'
|
||||||
|
|
||||||
|
--- Loads a Lua file with the Skooma environment and runs it.
|
||||||
|
-- Normally, the file should return a function
|
||||||
|
-- to follow restia template semantics.
|
||||||
|
-- @return The result of the template file.
|
||||||
|
-- @function load
|
||||||
|
return function(name)
|
||||||
|
name = tostring(name)..'.skooma'
|
||||||
|
local template = loadfile(name, "tb", skooma.default)
|
||||||
|
template = template and template()
|
||||||
|
if template then
|
||||||
|
return template
|
||||||
|
end
|
||||||
|
end
|
18
glass/yaml.lua
Normal file
18
glass/yaml.lua
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--- Loader for YAML-Data using Lua-CYAML
|
||||||
|
-- @module restia.config.yaml
|
||||||
|
|
||||||
|
local yaml = require 'lyaml'
|
||||||
|
local readfile = require 'restia.config.readfile'
|
||||||
|
|
||||||
|
--- Loads a YAML-File and returns a corresponding Lua table.
|
||||||
|
-- May return non-table values for invalid YAML,
|
||||||
|
-- as CYAML supports other types than Object at
|
||||||
|
-- the top-level of the YAML file.
|
||||||
|
-- @treturn table YAML-Data
|
||||||
|
-- @function load
|
||||||
|
return function(file)
|
||||||
|
local raw = readfile(file..'.yml') or readfile(file..'.yaml')
|
||||||
|
if raw then
|
||||||
|
return yaml.load(raw)
|
||||||
|
end
|
||||||
|
end
|
22
license
Normal file
22
license
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
33
readme.md
Normal file
33
readme.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Glass
|
||||||
|
Makes your configs (almost) see-through.
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
Glass is a Lua library that makes it easy to lazy-load configuration files into a Lua table at runtime. Its main purpose is to make accessing different configuration files "transparent" to the programmer.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
Assume the file `app/config/settings.json` exists in your project directory with the content `{"user":{"name":"User"}}`
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local glass = require 'glass'
|
||||||
|
local config = glass.bind('app/config', {
|
||||||
|
(require 'glass.json');
|
||||||
|
})
|
||||||
|
print(config.settings.user.name) -- prints "User"
|
||||||
|
```
|
||||||
|
|
||||||
|
## How it Works
|
||||||
|
A glass loader is initialised with a list of loaders and will try each of them in order in its `__index` metamethod. The first loader that is able to fetch the wanted configuration will be used.
|
||||||
|
|
||||||
|
## Loaders
|
||||||
|
Glass offers the following loaders out of the box:
|
||||||
|
* `cosmo` loads cosmo templates
|
||||||
|
* `discount` loads markdown files\*.
|
||||||
|
* `json` loads a JSON file as a Lua table.
|
||||||
|
* `lua` loads and executes a Lua file.
|
||||||
|
* `moonhtml` loads a MoonHTML template and returns it as a function.
|
||||||
|
* `readfile` loads a file as a string.
|
||||||
|
* `skooma` loads a skooma template and returns it as a function.
|
||||||
|
* `yaml` loads a YAML file as a Lua table.
|
||||||
|
|
||||||
|
\* For easier interoperability with other template loaders, the `discount` loader returns a static function which can be called to return the generated HTML. The markdown file is only parsed the first time.
|
3
spec/core_spec.moon
Normal file
3
spec/core_spec.moon
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
describe 'core module', ->
|
||||||
|
pending 'works as intended', ->
|
||||||
|
-- TODO: Write some tests
|
Loading…
Reference in a new issue