feat(config): more sophisticated param validation

This commit is contained in:
Barrett Ruth 2025-09-19 22:45:36 -04:00
parent db85bacd4c
commit 69fc2ecdbb
5 changed files with 221 additions and 43 deletions

View file

@ -37,8 +37,7 @@
---@field max_output_lines number Maximum lines of test output to display
---@class DiffGitConfig
---@field command string Git executable name
---@field args string[] Additional git diff arguments
---@field args string[] Git diff arguments
---@class DiffConfig
---@field git DiffGitConfig
@ -68,7 +67,26 @@ local constants = require('cp.constants')
---@type cp.Config
M.defaults = {
contests = {},
contests = {
default = {
cpp = {
compile = { 'g++', '{source}', '-o', '{binary}', '-std=c++17' },
test = { '{binary}' },
debug = {
'g++',
'{source}',
'-o',
'{binary}',
'-std=c++17',
'-g',
'-fsanitize=address,undefined',
},
},
python = {
test = { 'python3', '{source}' },
},
},
},
snippets = {},
hooks = {
before_run = nil,
@ -87,7 +105,6 @@ M.defaults = {
},
diff = {
git = {
command = 'git',
args = { 'diff', '--no-index', '--word-diff=plain', '--word-diff-regex=.', '--no-prefix' },
},
},
@ -114,25 +131,62 @@ function M.setup(user_config)
if user_config.contests then
for contest_name, contest_config in pairs(user_config.contests) do
for lang_name, lang_config in pairs(contest_config) do
if type(lang_config) == 'table' and lang_config.extension then
if
not vim.tbl_contains(
vim.tbl_keys(constants.filetype_to_language),
lang_config.extension
)
then
error(
("Invalid extension '%s' for language '%s' in contest '%s'. Valid extensions: %s"):format(
lang_config.extension,
lang_name,
contest_name,
table.concat(vim.tbl_keys(constants.filetype_to_language), ', ')
vim.validate({
[contest_name] = {
contest_config,
function(config)
if type(config) ~= 'table' then
return false
end
for lang_name, lang_config in pairs(config) do
if type(lang_config) == 'table' then
if
lang_name ~= 'default_language'
and not vim.tbl_contains(vim.tbl_keys(constants.canonical_filetypes), lang_name)
then
return false,
("Invalid language '%s'. Valid languages: %s"):format(
lang_name,
table.concat(vim.tbl_keys(constants.canonical_filetypes), ', ')
)
end
if
lang_config.extension
and not vim.tbl_contains(
vim.tbl_keys(constants.filetype_to_language),
lang_config.extension
)
then
return false,
("Invalid extension '%s'. Valid extensions: %s"):format(
lang_config.extension,
table.concat(vim.tbl_keys(constants.filetype_to_language), ', ')
)
end
end
end
if
config.default_language
and not vim.tbl_contains(
vim.tbl_keys(constants.canonical_filetypes),
config.default_language
)
)
end
end
end
then
return false,
("Invalid default_language '%s'. Valid languages: %s"):format(
config.default_language,
table.concat(vim.tbl_keys(constants.canonical_filetypes), ', ')
)
end
return true
end,
'contest configuration',
},
})
end
end
@ -226,6 +280,26 @@ function M.setup(user_config)
end
end
end
if not contest_config.default_language then
local available_langs = {}
for lang_name, lang_config in pairs(contest_config) do
if type(lang_config) == 'table' and lang_name ~= 'default_language' then
table.insert(available_langs, lang_name)
end
end
if #available_langs == 0 then
error('No language configurations found')
end
if vim.tbl_contains(available_langs, 'cpp') then
contest_config.default_language = 'cpp'
else
table.sort(available_langs)
contest_config.default_language = available_langs[1]
end
end
end
return config