WIP add validation to config

This commit is contained in:
Nathan Dwarshuis 2023-09-29 00:32:51 -04:00
parent 187a148631
commit 500d8b634e
3 changed files with 229 additions and 2 deletions

View File

@ -159,7 +159,7 @@ let Graphics =
{-
Defines Graphics module configuration
dev_power: show a power indicator
dev_power: sysfs path to graphics card power directory
show_temp: show temperature in celsius
show_clock: show clock speed
show_gpu_util: show percent utilization

View File

@ -54,6 +54,7 @@ package.cpath = conky_dir..'lib/lib/lua/5.4/?.so;'
local yaml = require 'lyaml'
local i_o = require 'i_o'
local validate = require 'validate'
local config_path = '/tmp/conky.yml'
@ -68,7 +69,9 @@ local find_valid_config = function(paths)
local rc = try_read_config(path)
if rc == 0 then
i_o.infof('Using config at %s', path)
return yaml.load(i_o.read_file(config_path))
local config = yaml.load(i_o.read_file(config_path))
validate.validate_config(config)
return config
else
i_o.warnf('could not read %s; trying next', path)
end

224
src/validate.lua Normal file
View File

@ -0,0 +1,224 @@
local M = {}
local err = require 'err'
local i_o = require 'i_o'
local pure = require 'pure'
M.assert_non_nil = function(what, x)
i_o.assertf(x ~= nil, '%s: %f must not be nil', what, x)
end
M.assert_number = function(what, x)
i_o.assertf(err.get_type(x) == 'number', '%s: \'%s\' must be a number', what, x)
end
M.assert_integer = function(what, x)
M.assert_number(what, x)
i_o.assertf(math.fmod(x, 1) == 0, '%s: \'%s\' must be an integer', what, x)
end
M.assert_less_than = function(what, x, upper)
M.assert_number(what, x)
i_o.assertf(
x < upper,
'%s: %f must be less than %f',
what, x, upper
)
end
M.assert_greater_than = function(what, x, lower)
M.assert_number(what, x)
i_o.assertf(
x > lower,
'%s: %f must be greater than %f',
what, x, lower
)
end
M.assert_less_than_or_eq = function(what, x, upper)
M.assert_number(what, x)
i_o.assertf(
x <= upper,
'%s: %f must be less than or equal to %f',
what, x, upper
)
end
M.assert_greater_than_or_eq = function(what, x, lower)
M.assert_number(what, x)
i_o.assertf(
x >= lower,
'%s: %f must be greater than or equal to %f',
what, x, lower
)
end
M.assert_positive = function(what, x)
M.assert_greater_than(what, x, 0)
end
M.assert_between = function(what, x, lower, upper)
M.assert_number(what, x)
i_o.assertf(
x >= lower and x <= upper,
'%s: %f must be between %f and %f',
what, x, lower, upper
)
end
M.assert_member = function(what, x, seq)
M.assert_non_nil(what, x)
local xs = pure.collapse(pure.keys(seq), ', ')
i_o.assertf(pure.member(x, seq), '%s: %s is not one of %s', what, x, xs)
end
M.assert_unit_fraction = function(what, x)
M.assert_number(what, x)
M.assert_between(what, x, 0, 1)
end
M.assert_color = function(what, x)
M.assert_number(what, x)
M.assert_between(what, x, 0, 0xffffff)
end
M.assert_color_alpha = function(what, x)
M.assert_color(what..'.color', x.color)
M.assert_unit_fraction(what..'.alpha', x.alpha)
end
M.assert_color_stop = function(what, x)
M.assert_color(what..'.color', x.color)
M.assert_unit_fraction(what..'.stop', x.stop)
end
M.assert_color_stop_alpha = function(what, x)
M.assert_color(what..'.color', x.color)
M.assert_unit_fraction(what..'.stop', x.stop)
M.assert_unit_fraction(what..'.alpha', x.alpha)
end
M.assert_valid_pattern = function(what, pat)
local t = pat.type
if t == "RGB" then
M.assert_color(what, pat.data)
elseif t == "RGBA" then
M.assert_color_alpha(what, pat.data)
elseif t == "GradientRGB" then
for _, x in pairs(pat.data) do
M.assert_color_stop(what, x)
end
elseif t == "GradientRGBA" then
for _, x in pairs(pat.data) do
M.assert_color_stop_alpha(what, x)
end
else
i_o.assertf(nil, '%s: pattern has invalid type \'%s\'', what, t)
end
end
-- TODO make spacing parameters aware of thickness, right now they start at the
-- centry of lines, circles, etc.
local validate_filesystem = function(x, width)
-- TODO ensure paths exist here
M.assert_greater_than('filesystem.bar_spacing', x.geometry.bar_spacing, 10)
M.assert_between('filesystem.bar_pad', x.geometry.bar_pad, 20, width)
end
local validate_graphics = function(x)
end
local validate_memory = function(x)
end
local validate_network = function(x)
end
local validate_pacman = function(x)
end
local validate_power = function(x)
end
local validate_processor = function(x)
end
local validate_readwrite = function(x)
end
local validate_system = function(x)
end
M.validate_config = function(config)
local boot = config.bootstrap
M.assert_positive('bootstrap.update_interval', boot.update_interval)
M.assert_positive('bootstrap.dimensions.x', boot.dimensions.x)
M.assert_positive('bootstrap.dimensions.y', boot.dimensions.y)
local font = config.theme.font.sizes
local _font = 'theme.font.sizes'
M.assert_positive(_font..'normal', font.normal)
M.assert_positive(_font..'plot_label', font.plot_label)
M.assert_positive(_font..'table', font.table)
M.assert_positive(_font..'header', font.header)
local geo = config.theme.geometry
local _geo = 'theme.geometry.'
M.assert_greater_than(_geo..'plot.seconds', geo.plot.seconds, 10)
M.assert_greater_than(_geo..'plot.ticks_x', geo.plot.ticks_x, 4)
M.assert_greater_than(_geo..'table.name_chars', geo.table.name_chars, 5)
M.assert_greater_than(_geo..'table.row_spacing', geo.table.row_spacing, 10)
local pat = config.theme.patterns
local _pat = 'theme.pattern.'
M.assert_valid_pattern(_pat..'header', pat.header)
M.assert_valid_pattern(_pat..'panel.bg', pat.panel.bg)
M.assert_valid_pattern(_pat..'text.active', pat.text.active)
M.assert_valid_pattern(_pat..'text.inactive', pat.text.inactive)
M.assert_valid_pattern(_pat..'text.critical', pat.text.critical)
M.assert_valid_pattern(_pat..'border', pat.border)
M.assert_valid_pattern(_pat..'plot.grid', pat.plot.grid)
M.assert_valid_pattern(_pat..'plot.outline', pat.plot.outline)
M.assert_valid_pattern(_pat..'plot.data.border', pat.plot.data.border)
M.assert_valid_pattern(_pat..'plot.data.fill', pat.plot.data.fill)
M.assert_valid_pattern(_pat..'indicator.bg', pat.indicator.bg)
M.assert_valid_pattern(_pat..'indicator.fg.active', pat.indicator.fg.active)
M.assert_valid_pattern(_pat..'indicator.fg.critical', pat.indicator.fg.critical)
for _, panel in pairs(config.layout.panels) do
if type(panel) == "table" then
for _, column in pairs(panel.columns) do
if type(column) == "table" then
for _, block in pairs(column.blocks) do
if type(block) == "table" then
local t = block.type
local d = block.data
if t == "filesystem" then
validate_filesystem(d, column.width)
elseif t == "graphics" then
validate_graphics(d)
elseif t == "memory" then
validate_memory(d)
elseif t == "network" then
validate_network(d)
elseif t == "pacman" then
validate_pacman(d)
elseif t == "power" then
validate_power(d)
elseif t == "processor" then
validate_processor(d)
elseif t == "readwrite" then
validate_readwrite(d)
elseif t == "system" then
validate_system(d)
end
end
end
end
end
end
end
end
return M