From 51c0ceeb5519a2ef8f88fa7729fc88a856fdbdc0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 19 Jan 2018 13:26:54 +0100 Subject: [PATCH] scripts/check_site.lua: merge site and domains for validation Each domain is validated separately, preferring domain values to site values. Based-on-patch-by: lemoer --- scripts/check_site.lua | 113 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 8 deletions(-) diff --git a/scripts/check_site.lua b/scripts/check_site.lua index 4cf6f078..0972fd70 100644 --- a/scripts/check_site.lua +++ b/scripts/check_site.lua @@ -1,5 +1,14 @@ local cjson = require 'cjson' +local function exit_error(src, ...) + io.stderr:write(string.format('*** %s error: %s\n', src, string.format(...))) + os.exit(1) +end + + +local has_domains = (os.execute('ls -d "$IPKG_INSTROOT"/lib/gluon/domains/ >/dev/null 2>&1') == 0) + + local function load_json(filename) local f = assert(io.open(filename)) local json = cjson.decode(f:read('*a')) @@ -7,7 +16,51 @@ local function load_json(filename) return json end -local site = load_json(os.getenv('IPKG_INSTROOT') .. '/lib/gluon/site.json') + +local function get_domains() + local domains = {} + local dirs = io.popen("find \"$IPKG_INSTROOT\"/lib/gluon/domains/ -name '*.json'") + for filename in dirs:lines() do + local name = string.match(filename, '([^/]+).json$') + domains[name] = load_json(filename) + end + dirs:close() + + if not next(domains) then + exit_error('site', 'no domain configurations found') + end + + return domains +end + +local site, domain_code, domain, conf + + +local function merge(a, b) + local function is_array(t) + local n = 0 + for k, v in pairs(t) do + n = n + 1 + end + return n == #t + end + + if not b then return a end + if type(a) ~= type(b) then return b end + if type(b) ~= 'table' then return b end + if not next(b) then return a end + if is_array(a) ~= is_array(b) then return b end + + local m = {} + for k, v in pairs(a) do + m[k] = v + end + for k, v in pairs(b) do + m[k] = merge(m[k], v) + end + + return m +end function in_site(var) @@ -19,7 +72,7 @@ function in_domain(var) end function this_domain() - return nil + return domain_code end @@ -31,17 +84,43 @@ local function array_to_string(array) return '[' .. table.concat(array, ', ') .. ']' end + +local loadpath + +local function site_src() + return 'site.conf' +end + +local function domain_src() + return 'domains/' .. domain_code .. '.conf' +end + local function var_error(path, val, msg) if type(val) == 'string' then val = string.format('%q', val) end - print(string.format('*** site.conf error: expected %s to %s, but it is %s', path_to_string(path), msg, tostring(val))) - os.exit(1) + local src + + if has_domains then + if loadpath(nil, domain, unpack(path)) ~= nil then + src = domain_src() + elseif loadpath(nil, site, unpack(path)) ~= nil then + src = site_src() + else + src = site_src() .. ' / ' .. domain_src() + end + else + src = site_src() + end + + exit_error(src, 'expected %s to %s, but it is %s', path_to_string(path), msg, tostring(val)) end function extend(path, c) + if not path then return nil end + local p = {unpack(path)} for _, e in ipairs(c) do @@ -50,20 +129,24 @@ function extend(path, c) return p end -local function loadpath(path, base, c, ...) +function loadpath(path, base, c, ...) if not c or base == nil then return base end if type(base) ~= 'table' then - var_error(path, base, 'be a table') + if path then + var_error(path, base, 'be a table') + else + return nil + end end return loadpath(extend(path, {c}), base[c], ...) end local function loadvar(path) - return loadpath({}, site, unpack(path)) + return loadpath({}, conf, unpack(path)) end local function check_type(t) @@ -188,4 +271,18 @@ function need_array_of(path, array, required) end -dofile() +local check = assert(loadfile()) + +site = load_json(os.getenv('IPKG_INSTROOT') .. '/lib/gluon/site.json') + +if has_domains then + for k, v in pairs(get_domains()) do + domain_code = k + domain = v + conf = merge(site, domain) + check() + end +else + conf = site + check() +end