mpeterv / luacheck

A tool for linting and static analysis of Lua code.
MIT License
1.92k stars 322 forks source link

Expose function to validate options #122

Closed johnd0e closed 6 years ago

johnd0e commented 7 years ago

I wish module interface of luacheck has function to validate config options.

Without it I have to implement code like this:

local function validateCfg(options)
  local res,msg = pcall(luacheck.check_strings,{},options)
  if not res then
    msg = msg:match"#2 to 'luacheck.check_strings' %((.+)%)" or msg
    return nil,msg
  end
  return res
end
mpeterv commented 7 years ago

I'd like to avoid exposing validation functions because the planned new Lua interface that will support some CLI features like multithreading and config loading will have several methods with different sets of validated options (e.g. config option will be passed to some initial setup method but not to checking methods). Also, fully processing config option requires I/O operations so it's good to do it only once.

Would it work for your use case if instead of throwing a string, validation errors were instead returned as an object after nil? E.g. it could return nil, {type = "validation", option = "ignore", msg = "array of string expected, got string"} in some case. The error object would have __tostring method turning it into a single string again. Functions would still throw on type errors, like passing a number instead of option table. What do you think?

johnd0e commented 7 years ago

I'd like to avoid exposing validation functions because the planned new Lua interface

I suppose that cant harm anything as long as that function stay undocumented.

Also, fully processing config option requires I/O operations so it's good to do it only once.

Do you mean reading config file? In our environment (FAR manager) we cant use luacheck loading functions (including config.load_config), so in any case I have to reimplement config reading in my code..

And I definitely prefer separate validate function, e.g. for such tasks as validate after config editing.

What do you think?

Error object will be good, if you have planned it anyway.

As for my use case I can continue using pcall, that's not a problem.

mpeterv commented 7 years ago

The plan is to have something like this:

-- Here options include config: path to file or a table. If config is invalid, nil + error object is returned.
local checker = luacheck.new(options)
local report = checker:check(inputs)
-- Now can process report as a table or do something like `print(checker:format(report))`.

This way config validation is a step of creating the checker object. You could recreate the checker every time config is edited, thus validating it, and then use the object when something needs to be checked.

In our environment (FAR manager) we cant use luacheck loading functions (including config.load_config), so in any case I have to reimplement config reading in my code..

Why can't it be used, because some of I/O is forbidden or something more specific about how it is implemented?

johnd0e commented 7 years ago

You could recreate the checker every time config is edited

Yes, that will definitely work in my case, thanks.

Why can't it be used, because some of I/O is forbidden or something more specific about how it is implemented?

We have unicode-aware environment, e.g. function loadfile expects filename in utf8, etc.

mpeterv commented 6 years ago

See #107