diff --git a/src/cfengine_cli/commands.py b/src/cfengine_cli/commands.py index ae1ed74..5d41724 100644 --- a/src/cfengine_cli/commands.py +++ b/src/cfengine_cli/commands.py @@ -52,14 +52,14 @@ def format(names, line_length, check) -> int: return format_paths(names, line_length, check) -def _lint(files, strict) -> int: +def _lint(files, strict, syntax_path) -> int: if not files: - return lint_args(["."], strict) - return lint_args(files, strict) + return lint_args(["."], strict, syntax_path) + return lint_args(files, strict, syntax_path) -def lint(files, strict) -> int: - errors = _lint(files, strict) +def lint(files, strict, syntax_path) -> int: + errors = _lint(files, strict, syntax_path) if errors == 0: print("Success, no errors found.") elif errors == 1: diff --git a/src/cfengine_cli/lint.py b/src/cfengine_cli/lint.py index d6acb3a..4429647 100644 --- a/src/cfengine_cli/lint.py +++ b/src/cfengine_cli/lint.py @@ -81,9 +81,9 @@ class SyntaxData: BUILTIN_PROMISE_TYPES = {} BUILTIN_FUNCTIONS = {} - def __init__(self): + def __init__(self, syntax_path=None): """Load the bundled syntax-description.json and derive lookup dicts.""" - self._data_dict = self._load_syntax_description() + self._data_dict = self._load_syntax_description(path=syntax_path) self._derive_syntax_dicts(self._data_dict) assert self.BUILTIN_BODY_TYPES @@ -1100,6 +1100,7 @@ def _lint_main( state=None, snippet: Snippet | None = None, syntax_data=None, + syntax_path: str | None = None, ) -> int: """This is the main function used for linting, it does all the steps on all the arguments (files / folders). @@ -1127,7 +1128,10 @@ def _lint_main( state.mode = Mode.SYNTAX if syntax_data is None: - syntax_data = SyntaxData() + try: + syntax_data = SyntaxData(syntax_path) + except FileNotFoundError: + raise UserError(f"'{syntax_path}' does not exist") filenames = _args_to_filenames(args) @@ -1379,9 +1383,11 @@ def lint_single_file(file: str, strict: bool = True) -> int: return _lint_main([file], strict) -def lint_args(args: Iterable[str], strict: bool = True) -> int: +def lint_args( + args: Iterable[str], strict: bool = True, syntax_path: str | None = None +) -> int: """Lint a list of args (files / folders)""" - return _lint_main(list(args), strict) + return _lint_main(list(args), strict, syntax_path=syntax_path) def lint_policy_file_snippet( diff --git a/src/cfengine_cli/main.py b/src/cfengine_cli/main.py index 77e3cbd..9cffc12 100644 --- a/src/cfengine_cli/main.py +++ b/src/cfengine_cli/main.py @@ -59,6 +59,11 @@ def _get_arg_parser(): default="yes", help="Strict mode. Default=yes, checks for undefined promise types, bundles, bodies, functions", ) + lnt.add_argument( + "--syntax-description", + type=str, + help="Lint based on a user given syntax description", + ) lnt.add_argument("files", nargs="*", help="Files to lint") subp.add_parser( "report", @@ -188,7 +193,11 @@ def run_command_with_args(args) -> int: if args.command == "format": return commands.format(args.files, args.line_length, args.check) if args.command == "lint": - return commands.lint(args.files, (args.strict.lower() in ("y", "ye", "yes"))) + return commands.lint( + args.files, + (args.strict.lower() in ("y", "ye", "yes")), + args.syntax_description, + ) if args.command == "report": return commands.report() if args.command == "run":