* luci/libs/uvl:
- fix handling of missing package/section/variable fields in scheme specs - fix dereferencing of scheme tables in luci.uvl.uvlitem.scheme() - unify TYPE_VARIABLE and TYPE_OPTION - implement external "regexp:..." validators - extend reference scheme to implement "lazylist" type for lists
This commit is contained in:
parent
51bfdb1377
commit
6b6abc95d0
3 changed files with 75 additions and 32 deletions
|
@ -33,9 +33,8 @@ require("luci.uvl.dependencies")
|
||||||
TYPE_SCHEME = 0x00
|
TYPE_SCHEME = 0x00
|
||||||
TYPE_CONFIG = 0x01
|
TYPE_CONFIG = 0x01
|
||||||
TYPE_SECTION = 0x02
|
TYPE_SECTION = 0x02
|
||||||
TYPE_VARIABLE = 0x03
|
TYPE_OPTION = 0x03
|
||||||
TYPE_OPTION = 0x04
|
TYPE_ENUM = 0x04
|
||||||
TYPE_ENUM = 0x05
|
|
||||||
|
|
||||||
--- Boolean; default true;
|
--- Boolean; default true;
|
||||||
-- treat sections found in config but not in scheme as error
|
-- treat sections found in config but not in scheme as error
|
||||||
|
@ -306,7 +305,9 @@ function UVL._validate_option( self, option, nodeps )
|
||||||
if type(val) ~= "table" and STRICT_LIST_TYPE then
|
if type(val) ~= "table" and STRICT_LIST_TYPE then
|
||||||
return false, option:error(ERR.OPT_NOTLIST(option))
|
return false, option:error(ERR.OPT_NOTLIST(option))
|
||||||
end
|
end
|
||||||
elseif option:scheme('datatype') then
|
end
|
||||||
|
|
||||||
|
if option:scheme('datatype') then
|
||||||
local dt = option:scheme('datatype')
|
local dt = option:scheme('datatype')
|
||||||
|
|
||||||
if self.datatypes[dt] then
|
if self.datatypes[dt] then
|
||||||
|
@ -378,10 +379,20 @@ end
|
||||||
function UVL._read_scheme_parts( self, scheme, schemes )
|
function UVL._read_scheme_parts( self, scheme, schemes )
|
||||||
|
|
||||||
-- helper function to check for required fields
|
-- helper function to check for required fields
|
||||||
local function _req( c, t, r )
|
local function _req( t, n, c, r )
|
||||||
for i, v in ipairs(r) do
|
for i, v in ipairs(r) do
|
||||||
if not t[v] then
|
if not c[v] then
|
||||||
return false, ERR.SME_REQFLD({c,t}, v)
|
local p, o = scheme:sid(), nil
|
||||||
|
|
||||||
|
if t == TYPE_SECTION then
|
||||||
|
o = section( scheme, nil, p, n )
|
||||||
|
elseif t == TYPE_OPTION then
|
||||||
|
o = option( scheme, nil, p, '(nil)', n )
|
||||||
|
elseif t == TYPE_ENUM then
|
||||||
|
o = enum( scheme, nil, p, '(nil)', '(nil)', n )
|
||||||
|
end
|
||||||
|
|
||||||
|
return false, ERR.SME_REQFLD(o,v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
|
@ -393,7 +404,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
|
||||||
if c == TYPE_SECTION then
|
if c == TYPE_SECTION then
|
||||||
k = "package"
|
k = "package"
|
||||||
n = 1
|
n = 1
|
||||||
elseif c == TYPE_VARIABLE then
|
elseif c == TYPE_OPTION then
|
||||||
k = "section"
|
k = "section"
|
||||||
n = 2
|
n = 2
|
||||||
elseif c == TYPE_ENUM then
|
elseif c == TYPE_ENUM then
|
||||||
|
@ -444,7 +455,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
|
||||||
for k, v in pairs( conf ) do
|
for k, v in pairs( conf ) do
|
||||||
if v['.type'] == 'section' then
|
if v['.type'] == 'section' then
|
||||||
|
|
||||||
ok, err = _req( TYPE_SECTION, v, { "name", "package" } )
|
ok, err = _req( TYPE_SECTION, k, v, { "name", "package" } )
|
||||||
if err then return false, scheme:error(err) end
|
if err then return false, scheme:error(err) end
|
||||||
|
|
||||||
local r, err = _ref( TYPE_SECTION, v )
|
local r, err = _ref( TYPE_SECTION, v )
|
||||||
|
@ -496,10 +507,10 @@ function UVL._read_scheme_parts( self, scheme, schemes )
|
||||||
for k, v in pairs( conf ) do
|
for k, v in pairs( conf ) do
|
||||||
if v['.type'] == "variable" then
|
if v['.type'] == "variable" then
|
||||||
|
|
||||||
ok, err = _req( TYPE_VARIABLE, v, { "name", "section" } )
|
ok, err = _req( TYPE_OPTION, k, v, { "name", "section" } )
|
||||||
if err then return false, scheme:error(err) end
|
if err then return false, scheme:error(err) end
|
||||||
|
|
||||||
local r, err = _ref( TYPE_VARIABLE, v )
|
local r, err = _ref( TYPE_OPTION, v )
|
||||||
if err then return false, scheme:error(err) end
|
if err then return false, scheme:error(err) end
|
||||||
|
|
||||||
local p = self.packages[r[1]]
|
local p = self.packages[r[1]]
|
||||||
|
@ -567,7 +578,7 @@ function UVL._read_scheme_parts( self, scheme, schemes )
|
||||||
for k, v in pairs( conf ) do
|
for k, v in pairs( conf ) do
|
||||||
if v['.type'] == "enum" then
|
if v['.type'] == "enum" then
|
||||||
|
|
||||||
ok, err = _req( TYPE_ENUM, v, { "value", "variable" } )
|
ok, err = _req( TYPE_ENUM, k, v, { "value", "variable" } )
|
||||||
if err then return false, scheme:error(err) end
|
if err then return false, scheme:error(err) end
|
||||||
|
|
||||||
local r, err = _ref( TYPE_ENUM, v )
|
local r, err = _ref( TYPE_ENUM, v )
|
||||||
|
@ -682,6 +693,25 @@ function UVL._read_validator( self, values, validators )
|
||||||
validator = value:gsub("^exec:","")
|
validator = value:gsub("^exec:","")
|
||||||
elseif value:match("^lua:") then
|
elseif value:match("^lua:") then
|
||||||
validator = self:_resolve_function( (value:gsub("^lua:","") ) )
|
validator = self:_resolve_function( (value:gsub("^lua:","") ) )
|
||||||
|
elseif value:match("^regexp:") then
|
||||||
|
local pattern = value:gsub("^regexp:","")
|
||||||
|
validator = function( type, dtype, pack, sect, optn, ... )
|
||||||
|
local values = { ... }
|
||||||
|
for _, v in ipairs(values) do
|
||||||
|
local ok, match =
|
||||||
|
luci.util.copcall( string.match, v, pattern )
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
return false, match
|
||||||
|
elseif not match then
|
||||||
|
return false,
|
||||||
|
'Value "%s" does not match pattern "%s"' % {
|
||||||
|
v, pattern
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if validator then
|
if validator then
|
||||||
|
@ -774,16 +804,19 @@ function uvlitem.scheme(self, opt)
|
||||||
local s
|
local s
|
||||||
|
|
||||||
if #self.sref == 4 or #self.sref == 3 then
|
if #self.sref == 4 or #self.sref == 3 then
|
||||||
s = self.s
|
s = self.s and self.s.packages
|
||||||
.packages[self.sref[1]]
|
s = s and s[self.sref[1]]
|
||||||
.variables[self.sref[2]][self.sref[3]]
|
s = s and s.variables
|
||||||
|
s = s and s[self.sref[2]]
|
||||||
|
s = s and s[self.sref[3]]
|
||||||
elseif #self.sref == 2 then
|
elseif #self.sref == 2 then
|
||||||
s = self.s
|
s = self.s and self.s.packages
|
||||||
.packages[self.sref[1]]
|
s = s and s[self.sref[1]]
|
||||||
.sections[self.sref[2]]
|
s = s and s.sections
|
||||||
|
s = s and s[self.sref[2]]
|
||||||
else
|
else
|
||||||
s = self.s
|
s = self.s and self.s.packages
|
||||||
.packages[self.sref[1]]
|
s = s and s[self.sref[1]]
|
||||||
end
|
end
|
||||||
|
|
||||||
if s and opt then
|
if s and opt then
|
||||||
|
|
|
@ -43,10 +43,14 @@ function check( self, object )
|
||||||
if object:scheme('validators') then
|
if object:scheme('validators') then
|
||||||
for _, val in ipairs(object:scheme('validators')) do
|
for _, val in ipairs(object:scheme('validators')) do
|
||||||
local ok, err = false, nil
|
local ok, err = false, nil
|
||||||
|
|
||||||
|
local values = object:value()
|
||||||
|
values = type(values) == "table" and values or { values }
|
||||||
|
|
||||||
local args = {
|
local args = {
|
||||||
object:scheme('type'),
|
object:scheme('type'), object:scheme('datatype'),
|
||||||
object.cref[1], object.cref[2], object.cref[3],
|
object.cref[1], object.cref[2], object.cref[3] or '',
|
||||||
object:scheme('datatype'), object:value()
|
unpack(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
if type(val) == "function" then
|
if type(val) == "function" then
|
||||||
|
|
|
@ -38,7 +38,7 @@ config variable
|
||||||
option name 'description'
|
option name 'description'
|
||||||
option title 'Description of the defined package'
|
option title 'Description of the defined package'
|
||||||
option section 'schema.package'
|
option section 'schema.package'
|
||||||
option type 'variable'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ config variable
|
||||||
option name 'description'
|
option name 'description'
|
||||||
option title 'Description of the defined section'
|
option title 'Description of the defined section'
|
||||||
option section 'schema.section'
|
option section 'schema.section'
|
||||||
option type 'variable'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ config variable
|
||||||
option name 'depends'
|
option name 'depends'
|
||||||
option title 'List of dependencies within and between defined sections'
|
option title 'List of dependencies within and between defined sections'
|
||||||
option section 'schema.section'
|
option section 'schema.section'
|
||||||
option type 'list'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ config variable
|
||||||
option name 'description'
|
option name 'description'
|
||||||
option title 'Description of the defined variable'
|
option title 'Description of the defined variable'
|
||||||
option section 'schema.variable'
|
option section 'schema.variable'
|
||||||
option type 'variable'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ config variable
|
||||||
option name 'depends'
|
option name 'depends'
|
||||||
option title 'List of dependencies between defined variables'
|
option title 'List of dependencies between defined variables'
|
||||||
option section 'schema.variable'
|
option section 'schema.variable'
|
||||||
option type 'list'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -240,6 +240,12 @@ config enum
|
||||||
option title 'This is a list variable'
|
option title 'This is a list variable'
|
||||||
option variable 'schema.variable.type'
|
option variable 'schema.variable.type'
|
||||||
|
|
||||||
|
# List-or-Option variable type (schema.@variable.type=lazylist)
|
||||||
|
config enum
|
||||||
|
option value 'lazylist'
|
||||||
|
option title 'This is a list or option variable'
|
||||||
|
option variable 'schema.variable.type'
|
||||||
|
|
||||||
# Reference variable type (schema.@variable.type=reference)
|
# Reference variable type (schema.@variable.type=reference)
|
||||||
config enum
|
config enum
|
||||||
option value 'reference'
|
option value 'reference'
|
||||||
|
@ -260,7 +266,7 @@ config variable
|
||||||
option name 'validator'
|
option name 'validator'
|
||||||
option title 'Datatype of this variable'
|
option title 'Datatype of this variable'
|
||||||
option section 'schema.variable'
|
option section 'schema.variable'
|
||||||
option type 'list'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -269,7 +275,7 @@ config variable
|
||||||
option name 'valueof'
|
option name 'valueof'
|
||||||
option title 'Reference to section or option to read values from'
|
option title 'Reference to section or option to read values from'
|
||||||
option section 'schema.variable'
|
option section 'schema.variable'
|
||||||
option type 'list'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -323,7 +329,7 @@ config variable
|
||||||
option name 'description'
|
option name 'description'
|
||||||
option title 'Description of the defined enum value'
|
option title 'Description of the defined enum value'
|
||||||
option section 'schema.enum'
|
option section 'schema.enum'
|
||||||
option type 'variable'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
@ -332,7 +338,7 @@ config variable
|
||||||
option name 'depends'
|
option name 'depends'
|
||||||
option title 'List of dependencies on defined variables'
|
option title 'List of dependencies on defined variables'
|
||||||
option section 'schema.enum'
|
option section 'schema.enum'
|
||||||
option type 'list'
|
option type 'lazylist'
|
||||||
option datatype 'string'
|
option datatype 'string'
|
||||||
option required false
|
option required false
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue