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