diff --git a/src/cfengine_cli/commands.py b/src/cfengine_cli/commands.py index 6db55f2..aed5177 100644 --- a/src/cfengine_cli/commands.py +++ b/src/cfengine_cli/commands.py @@ -50,34 +50,33 @@ def deploy() -> int: return r -def _format_filename(filename, line_length): +def _format_filename(filename, line_length, check): if filename.startswith("./."): - return + return 0 if filename.endswith(".json"): - format_json_file(filename) - return + return format_json_file(filename, check) if filename.endswith(".cf"): - format_policy_file(filename, line_length) - return + return format_policy_file(filename, line_length, check) raise UserError(f"Unrecognized file format: {filename}") -def _format_dirname(directory, line_length): +def _format_dirname(directory, line_length, check): + ret = 0 for filename in find(directory, extension=".json"): - _format_filename(filename, line_length) + ret |= _format_filename(filename, line_length, check) for filename in find(directory, extension=".cf"): - _format_filename(filename, line_length) + ret |= _format_filename(filename, line_length, check) + return ret -def format(names, line_length) -> int: +def format(names, line_length, check) -> int: if not names: - _format_dirname(".", line_length) - return 0 + return _format_dirname(".", line_length, check) if len(names) == 1 and names[0] == "-": # Special case, format policy file from stdin to stdout - format_policy_fin_fout(sys.stdin, sys.stdout, line_length) - return 0 + return format_policy_fin_fout(sys.stdin, sys.stdout, line_length, check) + ret = 0 for name in names: if name == "-": raise UserError( @@ -86,12 +85,12 @@ def format(names, line_length) -> int: if not os.path.exists(name): raise UserError(f"{name} does not exist") if os.path.isfile(name): - _format_filename(name, line_length) + ret |= _format_filename(name, line_length, check) continue if os.path.isdir(name): - _format_dirname(name, line_length) + ret |= _format_dirname(name, line_length, check) continue - return 0 + return ret def _lint(files, strict) -> int: diff --git a/src/cfengine_cli/docs.py b/src/cfengine_cli/docs.py index f0b7a80..6fa46b1 100644 --- a/src/cfengine_cli/docs.py +++ b/src/cfengine_cli/docs.py @@ -212,7 +212,7 @@ def fn_autoformat(_origin_path, snippet_path, language, _first_line, _last_line) raise UserError(f"Invalid json in '{snippet_path}'") case "cf": # Note: Dead code - Not used for CFEngine policy yet - format_policy_file(snippet_path, 80) + format_policy_file(snippet_path, 80, False) def _translate_language(x): diff --git a/src/cfengine_cli/format.py b/src/cfengine_cli/format.py index da6063e..58615b9 100644 --- a/src/cfengine_cli/format.py +++ b/src/cfengine_cli/format.py @@ -1,13 +1,21 @@ import tree_sitter_cfengine as tscfengine from tree_sitter import Language, Parser, Node -from cfbs.pretty import pretty_file +from cfbs.pretty import pretty_file, pretty_check_file -def format_json_file(filename): +def format_json_file(filename, check): assert filename.endswith(".json") + + if check: + r = not pretty_check_file(filename) + if r: + print(f"JSON file '{filename}' needs reformatting") + return r + r = pretty_file(filename) if r: print(f"JSON file '{filename}' was reformatted") + return r def text(node: Node): @@ -534,8 +542,9 @@ def autoformat(node, fmt, line_length, macro_indent, indent=0): fmt.print(node, indent) -def format_policy_file(filename, line_length): +def format_policy_file(filename, line_length, check): assert filename.endswith(".cf") + PY_LANGUAGE = Language(tscfengine.language()) parser = Parser(PY_LANGUAGE) @@ -551,12 +560,17 @@ def format_policy_file(filename, line_length): new_data = fmt.buffer + "\n" if new_data != original_data.decode("utf-8"): + if check: + print(f"Policy file '{filename}' needs reformatting") + return 1 + with open(filename, "w") as f: f.write(new_data) print(f"Policy file '{filename}' was reformatted") + return 0 -def format_policy_fin_fout(fin, fout, line_length): +def format_policy_fin_fout(fin, fout, line_length, check): PY_LANGUAGE = Language(tscfengine.language()) parser = Parser(PY_LANGUAGE) @@ -571,3 +585,4 @@ def format_policy_fin_fout(fin, fout, line_length): new_data = fmt.buffer + "\n" fout.write(new_data) + return 0 diff --git a/src/cfengine_cli/main.py b/src/cfengine_cli/main.py index adb96e3..68ac3cc 100644 --- a/src/cfengine_cli/main.py +++ b/src/cfengine_cli/main.py @@ -48,6 +48,7 @@ def _get_arg_parser(): fmt = subp.add_parser("format", help="Autoformat .json and .cf files") fmt.add_argument("files", nargs="*", help="Files to format") fmt.add_argument("--line-length", default=80, type=int, help="Maximum line length") + fmt.add_argument("--check", action="store_true") lnt = subp.add_parser( "lint", help="Look for syntax errors and other simple mistakes", @@ -136,7 +137,7 @@ def run_command_with_args(args) -> int: if args.command == "deploy": return commands.deploy() if args.command == "format": - return commands.format(args.files, args.line_length) + 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"))) if args.command == "report":