Skip to content

Commit d28b570

Browse files
authored
Merge pull request #100 from olehermanse/implies-body
cfengine lint: Ensured we look for bodies when resolving calls in copy_from and action
2 parents 1397248 + fddf492 commit d28b570

4 files changed

Lines changed: 70 additions & 13 deletions

File tree

src/cfengine_cli/lint.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@
5252
"string",
5353
}
5454
PROMISE_BLOCK_ATTRIBUTES = ("path", "interpreter")
55+
5556
IMPLIES_BUNDLE = {"usebundle", "servicebundle", "service_bundle"}
57+
IMPLIES_BODY = {"copy_from", "action"}
58+
# Generally, IMPLIES_BUNDLE and IMPLIES_BODY might not be necessary
59+
# in the future, when we're using syntax-description.json we will
60+
# know if we expect a bundle or body (based on both promise type and attribute name)
61+
# so "guessing" based on only attribute name can be dropped.
62+
5663
KNOWN_FAULTY_FUNCTION_DEFS = {"regex_replace", "peers"}
5764
# Generally, we don't want to allow creating bodies / bundles with the same
5865
# name as a built in function, as it can make things more confusing
@@ -652,19 +659,18 @@ def _lint_node(
652659
f"Error: Call to bundle '{name}' inside custom promise: '{state.promise_type}' {location}"
653660
)
654661
return 1
655-
if state.strict and (
656-
qualified_name not in state.bundles
657-
and (
658-
state.attribute_name in IMPLIES_BUNDLE
659-
or qualified_name not in state.bodies
660-
)
661-
and name not in syntax_data.BUILTIN_FUNCTIONS
662-
):
663-
_highlight_range(node, lines)
664-
print(
665-
f"Error: Call to unknown function / bundle / body '{name}' {location}"
662+
if state.strict and name not in syntax_data.BUILTIN_FUNCTIONS:
663+
allowed_in_bundles = state.attribute_name not in IMPLIES_BODY
664+
allowed_in_bodies = state.attribute_name not in IMPLIES_BUNDLE
665+
found = (allowed_in_bundles and qualified_name in state.bundles) or (
666+
allowed_in_bodies and qualified_name in state.bodies
666667
)
667-
return 1
668+
if not found:
669+
_highlight_range(node, lines)
670+
print(
671+
f"Error: Call to unknown function / bundle / body '{name}' {location}"
672+
)
673+
return 1
668674
if (
669675
name not in syntax_data.BUILTIN_FUNCTIONS
670676
and state.promise_type == "vars"
@@ -757,7 +763,7 @@ def _lint_node(
757763
return 1
758764

759765
qualified_name = _qualify(call, state.namespace)
760-
if qualified_name in state.bundles:
766+
if qualified_name in state.bundles and state.attribute_name not in IMPLIES_BODY:
761767
definitions = state.bundles[qualified_name]
762768
valid_counts = {len(d.get("parameters", [])) for d in definitions}
763769
if len(args) not in valid_counts:

tests/lint/018_implies_body.cf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
body copy_from mycopy(from, server)
2+
{
3+
source => "$(from)";
4+
servers => { "$(server)" };
5+
}
6+
7+
bundle agent main
8+
{
9+
files:
10+
"/tmp/test"
11+
copy_from => mycopy("/src", "host1");
12+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
"/tmp/test1"
3+
copy_from => helper("oops");
4+
^----^
5+
Error: Call to unknown function / bundle / body 'helper' at tests/lint/018_implies_body.x.cf:17:20
6+
7+
"/tmp/test2"
8+
copy_from => unknown_name("oops");
9+
^----------^
10+
Error: Call to unknown function / bundle / body 'unknown_name' at tests/lint/018_implies_body.x.cf:19:20
11+
12+
"/tmp/test3"
13+
copy_from => mycopy("/src");
14+
^------------^
15+
Error: Expected 2 arguments, received 1 for body 'mycopy' at tests/lint/018_implies_body.x.cf:21:20
16+
FAIL: tests/lint/018_implies_body.x.cf (3 errors)
17+
Failure, 3 errors in total.

tests/lint/018_implies_body.x.cf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
body copy_from mycopy(from, server)
2+
{
3+
source => "$(from)";
4+
servers => { "$(server)" };
5+
}
6+
7+
bundle agent helper(arg)
8+
{
9+
reports:
10+
"$(arg)";
11+
}
12+
13+
bundle agent main
14+
{
15+
files:
16+
"/tmp/test1"
17+
copy_from => helper("oops");
18+
"/tmp/test2"
19+
copy_from => unknown_name("oops");
20+
"/tmp/test3"
21+
copy_from => mycopy("/src");
22+
}

0 commit comments

Comments
 (0)