Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions src/cfengine_cli/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def add_bundle(self, name: str) -> None:
# - Can record the parameters / signature
# - Can record whether the bundle is inside a macro
# - Can have a list of classes and vars defined inside
self.bundles[name] = True
self.bundles[name] = {"is_defined": True}

def add_body(self, name: str) -> None:
"""This is called during discovery wherever a body is defined.
Expand All @@ -299,7 +299,7 @@ def add_body(self, name: str) -> None:
body file control {}
"""
name = _qualify(name, self.namespace)
self.bodies[name] = True
self.bodies[name] = {"is_defined": True}

def add_promise_type(self, name: str) -> None:
"""This is called during discovery wherever a custom promise type is
Expand Down Expand Up @@ -461,12 +461,22 @@ def _discover_node(node: Node, state: State) -> int:
if name == "control":
return 0 # No need to define control blocks
state.add_body(name)
qualified_name = _qualify(name, state.namespace)
if (n := node.next_named_sibling) and n.type == "parameter_list":
_, *args, _ = n.children
args = list(filter(",".__ne__, iter(_text(x) for x in args)))
state.bodies[qualified_name].update({"parameters": args})
return 0

# Define bundles:
if node.type == "bundle_block_name":
name = _text(node)
qualified_name = _qualify(name, state.namespace)
state.add_bundle(name)
if (n := node.next_named_sibling) and n.type == "parameter_list":
_, *args, _ = n.children
args = list(filter(",".__ne__, iter(_text(x) for x in args)))
state.bundles[qualified_name].update({"parameters": args})
return 0

# Define custom promise types:
Expand Down Expand Up @@ -661,8 +671,12 @@ def _lint_node(
)
return 1
if node.type == "call":
known_faulty_defs = {"regex_replace"}
call, _, *args, _ = node.children # f ( a1 , a2 , a..N )
call = _text(call)
if call in known_faulty_defs:
return 0

args = list(filter(",".__ne__, iter(_text(x) for x in args)))

if call in syntax_data.BUILTIN_FUNCTIONS:
Expand All @@ -671,10 +685,28 @@ def _lint_node(
if not variadic and (len(params) != len(args)):
_highlight_range(node, lines)
print(
f"Error: Expected {len(params)} arguments, received {len(args)} {location}"
f"Error: Expected {len(params)} arguments, received {len(args)} for function '{call}' {location}"
)
return 1
# TODO: Handle variadic functions with varying number of required arguments (0-N, 1-N, 2-N and so on)
qualified_name = _qualify(call, state.namespace)
if qualified_name in state.bundles:
params = state.bundles[qualified_name].get("parameters", [])
if len(params) != len(args):
_highlight_range(node, lines)
print(
f"Error: Expected {len(params)} arguments, received {len(args)} for bundle '{call}' {location}"
)
return 1
if qualified_name in state.bodies:
params = state.bodies[qualified_name].get("parameters", [])
if len(params) != len(args):
_highlight_range(node, lines)
print(
f"Error: Expected {len(params)} arguments, received {len(args)} for body '{call}' {location}"
)
return 1

return 0


Expand Down
4 changes: 2 additions & 2 deletions tests/lint/013_function_call_arg_count.expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"string1"
string => canonify();
^--------^
Error: Expected 1 arguments, received 0 at tests/lint/013_function_call_arg_count.x.cf:5:15
Error: Expected 1 arguments, received 0 for function 'canonify' at tests/lint/013_function_call_arg_count.x.cf:5:15

"string3"
string => canonify("test", "test");
^----------------------^
Error: Expected 1 arguments, received 2 at tests/lint/013_function_call_arg_count.x.cf:9:15
Error: Expected 1 arguments, received 2 for function 'canonify' at tests/lint/013_function_call_arg_count.x.cf:9:15
FAIL: tests/lint/013_function_call_arg_count.x.cf (2 errors)
Failure, 2 errors in total.
17 changes: 17 additions & 0 deletions tests/lint/014_num_args_body.expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

create => "true",
perms => mog("644");
^--------^
Error: Expected 3 arguments, received 1 for body 'mog' at tests/lint/014_num_args_body.x.cf:13:16

create => "true",
perms => mog("644", "root");
^----------------^
Error: Expected 3 arguments, received 2 for body 'mog' at tests/lint/014_num_args_body.x.cf:16:16

create => "true",
perms => mog("644", "root", "root", "root");
^--------------------------------^
Error: Expected 3 arguments, received 4 for body 'mog' at tests/lint/014_num_args_body.x.cf:22:16
FAIL: tests/lint/014_num_args_body.x.cf (3 errors)
Failure, 3 errors in total.
24 changes: 24 additions & 0 deletions tests/lint/014_num_args_body.x.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
body perms mog(mode,user,group)
{
owners => { "$(user)" };
groups => { "$(group)" };
mode => "$(mode)";
}

bundle agent main
{
files:
"/tmp/test1"
create => "true",
perms => mog("644");
"/tmp/test2"
create => "true",
perms => mog("644", "root");
"/tmp/test3"
create => "true",
perms => mog("644", "root", "root");
"/tmp/test4"
create => "true",
perms => mog("644", "root", "root", "root");
}

17 changes: 17 additions & 0 deletions tests/lint/014_num_args_bundle.expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

"test1"
usebundle => test();
^----^
Error: Expected 2 arguments, received 0 for bundle 'test' at tests/lint/014_num_args_bundle.x.cf:5:20

"test2"
usebundle => test("a");
^-------^
Error: Expected 2 arguments, received 1 for bundle 'test' at tests/lint/014_num_args_bundle.x.cf:7:20

"test4"
usebundle => test("a", "b", "c");
^-----------------^
Error: Expected 2 arguments, received 3 for bundle 'test' at tests/lint/014_num_args_bundle.x.cf:11:20
FAIL: tests/lint/014_num_args_bundle.x.cf (3 errors)
Failure, 3 errors in total.
17 changes: 17 additions & 0 deletions tests/lint/014_num_args_bundle.x.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bundle agent main
{
methods:
"test1"
usebundle => test();
"test2"
usebundle => test("a");
"test3"
usebundle => test("a", "b");
"test4"
usebundle => test("a", "b", "c");
}
bundle agent test(a, b)
{
reports:
"$(a) to $(b)";
}
11 changes: 11 additions & 0 deletions tests/lint/014_num_args_bundle_body.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
bundle agent main
{
methods:
"test"
usebundle => test("a", "b");
}
bundle agent test(a, b)
{
reports:
"$(a) to $(b)";
}
Loading