Browse Source

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 <git@irrelefant.net>
Matthias Schiffer 6 years ago
parent
commit
51c0ceeb55
1 changed files with 105 additions and 8 deletions
  1. 105 8
      scripts/check_site.lua

+ 105 - 8
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