check_site.lua 3.6 KB

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