diff --git a/src/cfengine_cli/lint.py b/src/cfengine_cli/lint.py index f5c87ce..50165dc 100644 --- a/src/cfengine_cli/lint.py +++ b/src/cfengine_cli/lint.py @@ -552,15 +552,8 @@ def _lint_node( return 1 if state.promise_type == "vars" and node.type == "promise": attribute_nodes = [x for x in node.children if x.type == "attribute"] - if not attribute_nodes: - _highlight_range(node, lines) - print( - f"Error: Missing attribute value for promiser " - f"{_text(node)[:-1]} inside vars-promise type {location}" - ) - return 1 - - mutually_excl_vars_attrs = { + # Each vars promise must include exactly 1 of these attributes (a value): + vars_types = { "data", "ilist", "int", @@ -569,21 +562,33 @@ def _lint_node( "slist", "string", } + # Attributes are children of a promise, and attribute names are children of attributes + # Need to iterate inside to find the attribute name (data, ilist, int, etc.) + value_nodes = [] + for attr in attribute_nodes: + for child in attr.children: + if child.type != "attribute_name": + continue + if _text(child) in vars_types: + # Ignore the other attributes which are not values + value_nodes.append(child) + + if not value_nodes: + # None of vars_types were found + _highlight_range(node, lines) + print( + f"Error: Missing value for vars promise {_text(node)[:-1]} {location}" + ) + return 1 - promise_type_attrs = { - _text(child): attr_node - for attr_node in attribute_nodes - for child in attr_node.children - if child.type == "attribute_name" - and _text(child) in mutually_excl_vars_attrs - } - - if len(promise_type_attrs) > 1: - for n in promise_type_attrs: - _highlight_range(promise_type_attrs[n], lines) + if len(value_nodes) > 1: + # Too many of vars_types was found + # TODO: We could improve _highlight_range to highlight multiple nodes in a nice way + _highlight_range(value_nodes[-1], lines) + nodes = ", ".join([_text(x) for x in value_nodes]) print( - f"Error: Mutually exclusive attribute values {tuple(promise_type_attrs)} for a single promiser" - f" inside vars-promise {location}" + f"Error: Mutually exclusive attribute values ({nodes})" + f" for a single promiser inside vars-promise {location}" ) return 1 if node.type == "calling_identifier": diff --git a/src/cfengine_cli/masterfiles/generate_release_information.py b/src/cfengine_cli/masterfiles/generate_release_information.py index 39fb45a..6457bc4 100644 --- a/src/cfengine_cli/masterfiles/generate_release_information.py +++ b/src/cfengine_cli/masterfiles/generate_release_information.py @@ -170,21 +170,16 @@ def json_get_save_return(url: str, path: str) -> dict: try: r = requests.get(url) r.raise_for_status() + content = r.content + with open(path, "wb") as f: + f.write(content) + data = json.loads(content) + return data except requests.exceptions.RequestException: raise CFBSNetworkError( f"Downloading of {url} failed - check your Wi-Fi / network settings." ) - content = r.content - - try: - with open(path, "wb") as f: - f.write(content) except OSError: raise CFBSExitError(f"Failed to open and write content to {path}") - - try: - data = json.loads(content) except json.JSONDecodeError: raise CFBSExitError(f"Failed to parse JSON from {url}.") - - return data diff --git a/tests/lint/011_mutually_exclusive_types_vars.cf b/tests/lint/011_mutually_exclusive_types_vars.cf index 0387f61..1093306 100644 --- a/tests/lint/011_mutually_exclusive_types_vars.cf +++ b/tests/lint/011_mutually_exclusive_types_vars.cf @@ -6,12 +6,10 @@ bundle agent foo real => "11.11"; "noerr" - slist => {}; - int => "string"; + int => 12; "noerr" - slist => {} - int => "string"; + slist => {}; "comment" slist => {}, diff --git a/tests/lint/011_mutually_exclusive_types_vars.expected.txt b/tests/lint/011_mutually_exclusive_types_vars.expected.txt index 396c54d..d980510 100644 --- a/tests/lint/011_mutually_exclusive_types_vars.expected.txt +++ b/tests/lint/011_mutually_exclusive_types_vars.expected.txt @@ -1,20 +1,12 @@ - "error" - slist => {}, - ^---------^ - - slist => {}, - int => "10", - ^---------^ - policy => "free", real => "0.5"; - ^-----------^ -Error: Mutually exclusive attribute values ('slist', 'int', 'real') for a single promiser inside vars-promise at tests/lint/011_mutually_exclusive_types_vars.x.cf:4:5 + ^--^ +Error: Mutually exclusive attribute values (slist, int, real) for a single promiser inside vars-promise at tests/lint/011_mutually_exclusive_types_vars.x.cf:4:5 "missing-error"; ^--------------^ -Error: Missing attribute value for promiser "missing-error" inside vars-promise type at tests/lint/011_mutually_exclusive_types_vars.x.cf:18:5 +Error: Missing value for vars promise "missing-error" at tests/lint/011_mutually_exclusive_types_vars.x.cf:16:5 FAIL: tests/lint/011_mutually_exclusive_types_vars.x.cf (2 errors) Failure, 2 errors in total. diff --git a/tests/lint/011_mutually_exclusive_types_vars.x.cf b/tests/lint/011_mutually_exclusive_types_vars.x.cf index 0a5ae3d..14c849b 100644 --- a/tests/lint/011_mutually_exclusive_types_vars.x.cf +++ b/tests/lint/011_mutually_exclusive_types_vars.x.cf @@ -9,11 +9,9 @@ bundle agent foo "noerr" slist => {}; - int => "string"; "noerr" - slist => {} - int => "string"; + string => "string"; "missing-error"; }