build: remove some obsolete support scripts
[project/luci.git] / libs / uvl / root / usr / bin / uvl
1 #!/usr/bin/lua
2 --[[
3
4 UCI Validation Layer - Command Line Utility
5 (c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
6 (c) 2008 Steven Barth <steven@midlink.org>
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12 http://www.apache.org/licenses/LICENSE-2.0
13
14 $Id$
15
16 ]]--
17
18 require("luci.uvl")
19 require("luci.util")
20
21
22 function getopt( arg, options )
23 options = options or ""
24 local tab = {}
25 local args = {}
26 for k, v in ipairs(arg) do
27 if v:sub(1, 2) == "--" then
28 local x = v:find( "=", 1, true )
29 if x then
30 tab[ v:sub( 3, x-1 ) ] = v:sub( x+1 )
31 else
32 tab[ v:sub( 3 ) ] = true
33 end
34 elseif v:sub( 1, 1 ) == "-" then
35 local y = 2
36 local l = #v
37 local jopt
38 while ( y <= l ) do
39 jopt = v:sub( y, y )
40 if options:find( jopt, 1, true ) then
41 if y < l then
42 tab[ jopt ] = v:sub( y+1 )
43 y = l
44 else
45 tab[ jopt ] = arg[ k + 1 ]
46 arg[ k + 1 ] = ""
47 end
48 else
49 tab[ jopt ] = true
50 end
51 y = y + 1
52 end
53 elseif #v > 0 then
54 table.insert(args, v)
55 end
56 end
57 return tab, args
58 end
59
60 function genspec(conf)
61 require("luci.model.uci")
62 require("luci.uvl.datatypes")
63
64 local uci = luci.model.uci.cursor()
65 local ok, err = uci:load(conf)
66
67 if not ok then
68 print("Can not load config:", err)
69 os.exit(1)
70 else
71 local function _guess_datatype(v)
72 if type(v) == "table" then v = v[1] end
73
74 for _, type in ipairs({
75 "boolean", "integer", "float", "ip4addr", "ip6addr",
76 "macaddr", "directory", "file"
77 }) do
78 if luci.uvl.datatypes[type](v) then
79 return type
80 end
81 end
82 return "string"
83 end
84
85
86 local co = uci:get_all(conf)
87 local ct = { }
88 local ca = { }
89 local so = { }
90 local to = { }
91
92 -- count section types
93 for _, section in pairs(co) do
94 ct[section['.type']] = ( ct[section['.type']] or 0 ) + 1
95 ca[section['.type']] = section['.anonymous']
96 so[section['.type']] = so[section['.type']] or { }
97 to[section['.type']] = to[section['.type']] or { }
98
99 for option, value in pairs(section) do
100 if option:sub(1,1) ~= "." then
101 so[section['.type']][option] = _guess_datatype(value)
102 to[section['.type']][option] = ( type(value) == "table" and "list" or "variable" )
103 end
104 end
105 end
106
107 -- package name
108 print( "package %s" % conf )
109
110 -- write section schemes
111 for type, count in luci.util.kspairs(ct) do
112 print( "\nconfig section" )
113 print( "\toption name '%s'" % type )
114 print( "\toption title 'Section %s'" % type )
115 print( "\toption package '%s'"% conf )
116 print( "\toption named %s" % ( ca[type] and 'false' or 'true' ) )
117 print( "\toption unique %s" % ( ct[type] > 1 and 'false' or ( ca[type] and 'false' or 'true' ) ) )
118 print( "\toption dynamic false" )
119 print( "\toption required false" )
120
121 -- write option schemes
122 for opt, val in luci.util.kspairs(so[type]) do
123 print( "\nconfig variable" )
124 print( "\toption name '%s'" % opt )
125 print( "\toption title 'Option %s'" % opt )
126 print( "\toption section '%s.%s'" %{ conf, type } )
127 print( "\toption datatype '%s'" % so[type][opt] )
128
129 if to[type][opt] ~= "variable" then
130 print( "\toption type '%s'" % to[type][opt] )
131 end
132 end
133
134 print("")
135 end
136
137 end
138 end
139
140
141 local options, arguments = getopt( arg )
142
143 if #arguments ~= 2 or options.help then
144 print([=[
145
146 uvl - UCI Validation Layer
147 $Id$
148 (c) 2008 Jo-Philipp Wich, Steven Barth
149
150 Usage:
151 uvl --help
152 uvl [--silent] [--schemedir=DIR] [--configdir=DIR] [--no-strict-sections] \
153 [--no-strict-options] [--no-strict-validators] [--no-strict-lists] \
154 {verify|verify-scheme|genspec} config[.section[.option]]
155
156 Options:
157 --help
158 Display this help message.
159
160 --silent
161 Don't produce any output.
162
163 --schemedir=DIR
164 Use DIR as scheme directory.
165
166 --configdir=DIR
167 Use DIR as config directory.
168
169 --no-strict-sections
170 Don't treat sections found in config but not in scheme as error.
171
172 --no-strict-options
173 Don't treat options found in config but not in scheme as error.
174
175 --no-strict-validators
176 Don't invalidate config if an external validator fails.
177
178 --no-strict-lists
179 Don't invalidate lists that are stored options.
180
181 Actions:
182 verify
183 Validate given configuration, section or option.
184
185 verify-scheme
186 Validate given scheme against the reference meta scheme.
187
188 genspec
189 Generate a scheme skeleton from given configuration.
190 ]=])
191 os.exit(255)
192 elseif arguments[1] == "verify" or arguments[1] == "verify-scheme" then
193 luci.uvl.STRICT_UNKNOWN_SECTIONS =
194 ( not options['no-strict-sections'] and true or false )
195 luci.uvl.STRICT_UNKNOWN_OPTIONS =
196 ( not options['no-strict-options'] and true or false )
197 luci.uvl.STRICT_EXTERNAL_VALIDATORS =
198 ( not options['no-strict-validators'] and true or false )
199 luci.uvl.STRICT_LIST_TYPE =
200 ( not options['no-strict-lists'] and true or false )
201
202 local uvl = luci.uvl.UVL(
203 type(options.schemedir) == "string" and options.schemedir,
204 type(options.configdir) == "string" and options.configdir
205 )
206
207 local cso = luci.util.split( arguments[2], "." )
208 local ok, err
209
210 if arguments[1] == "verify-scheme" then
211 uvl:read_scheme( 'schema', cso[1] )
212
213 local uci = uvl.uci.cursor(
214 type(options.configdir) == "string"
215 and options.configdir or uvl.schemedir .. '/default'
216 )
217
218 ok, err = uvl:validate_config( cso[1], uci:get_all(cso[1]) )
219 if err then err.code = luci.uvl.errors.ERR_SCHEME end
220 else
221 ok, err = uvl:validate( unpack(cso) )
222 end
223
224 if ok then
225 if not options.silent then
226 print( string.format(
227 '%s "%s" validates fine!',
228 ( arguments[1] == "verify-scheme" and "Scheme" or
229 ( #cso == 1 and "Config" or
230 ( #cso == 2 and "Section" or "Option" ) ) ),
231 table.concat(cso, ".")
232 ) )
233 end
234 os.exit( 0 )
235 else
236 if not options.silent then print( err and err:string() or "Unknown error" ) end
237 os.exit( 1 )
238 end
239 else
240 genspec( arguments[2] )
241 end