check_site.lua 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. local cjson = require 'cjson'
  2. local function load_json(filename)
  3. local f = assert(io.open(filename))
  4. local json = cjson.decode(f:read('*a'))
  5. f:close()
  6. return json
  7. end
  8. local site = load_json(os.getenv('IPKG_INSTROOT') .. '/lib/gluon/site.json')
  9. function in_site(var)
  10. return var
  11. end
  12. function in_domain(var)
  13. return var
  14. end
  15. function this_domain()
  16. return nil
  17. end
  18. local function path_to_string(path)
  19. return table.concat(path, '/')
  20. end
  21. local function array_to_string(array)
  22. return '[' .. table.concat(array, ', ') .. ']'
  23. end
  24. local function var_error(path, val, msg)
  25. if type(val) == 'string' then
  26. val = string.format('%q', val)
  27. end
  28. print(string.format('*** site.conf error: expected %s to %s, but it is %s', path_to_string(path), msg, tostring(val)))
  29. os.exit(1)
  30. end
  31. function extend(path, c)
  32. local p = {unpack(path)}
  33. for _, e in ipairs(c) do
  34. p[#p+1] = e
  35. end
  36. return p
  37. end
  38. local function loadpath(path, base, c, ...)
  39. if not c or base == nil then
  40. return base
  41. end
  42. if type(base) ~= 'table' then
  43. var_error(path, base, 'be a table')
  44. end
  45. return loadpath(extend(path, {c}), base[c], ...)
  46. end
  47. local function loadvar(path)
  48. return loadpath({}, site, unpack(path))
  49. end
  50. local function check_type(t)
  51. return function(val)
  52. return type(val) == t
  53. end
  54. end
  55. local function check_one_of(array)
  56. return function(val)
  57. for _, v in ipairs(array) do
  58. if v == val then
  59. return true
  60. end
  61. end
  62. return false
  63. end
  64. end
  65. function need(path, check, required, msg)
  66. local val = loadvar(path)
  67. if required == false and val == nil then
  68. return nil
  69. end
  70. if not check(val) then
  71. var_error(path, val, msg)
  72. end
  73. return val
  74. end
  75. local function need_type(path, type, required, msg)
  76. return need(path, check_type(type), required, msg)
  77. end
  78. function need_alphanumeric_key(path)
  79. local val = path[#path]
  80. -- We don't use character classes like %w here to be independent of the locale
  81. if not val:match('^[0-9a-zA-Z_]+$') then
  82. var_error(path, val, 'have a key using only alphanumeric characters and underscores')
  83. end
  84. end
  85. function need_string(path, required)
  86. return need_type(path, 'string', required, 'be a string')
  87. end
  88. function need_string_match(path, pat, required)
  89. local val = need_string(path, required)
  90. if not val then
  91. return nil
  92. end
  93. if not val:match(pat) then
  94. var_error(path, val, "match pattern '" .. pat .. "'")
  95. end
  96. return val
  97. end
  98. function need_number(path, required)
  99. return need_type(path, 'number', required, 'be a number')
  100. end
  101. function need_boolean(path, required)
  102. return need_type(path, 'boolean', required, 'be a boolean')
  103. end
  104. function need_array(path, subcheck, required)
  105. local val = need_type(path, 'table', required, 'be an array')
  106. if not val then
  107. return nil
  108. end
  109. if subcheck then
  110. for i = 1, #val do
  111. subcheck(extend(path, {i}))
  112. end
  113. end
  114. return val
  115. end
  116. function need_table(path, subcheck, required)
  117. local val = need_type(path, 'table', required, 'be a table')
  118. if not val then
  119. return nil
  120. end
  121. if subcheck then
  122. for k, _ in pairs(val) do
  123. subcheck(extend(path, {k}))
  124. end
  125. end
  126. return val
  127. end
  128. function need_value(path, value, required)
  129. return need(path, function(v)
  130. return v == value
  131. end, required, 'be ' .. tostring(value))
  132. end
  133. function need_one_of(path, array, required)
  134. return need(path, check_one_of(array), required, 'be one of the given array ' .. array_to_string(array))
  135. end
  136. function need_string_array(path, required)
  137. return need_array(path, need_string, required)
  138. end
  139. function need_string_array_match(path, pat, required)
  140. return need_array(path, function(e) need_string_match(e, pat) end, required)
  141. end
  142. function need_array_of(path, array, required)
  143. return need_array(path, function(e) need_one_of(e, array) end, required)
  144. end
  145. dofile()