4040from cfengine_cli .utils import UserError
4141
4242LINT_EXTENSIONS = (".cf" , ".json" )
43+ DEFAULT_NAMESPACE = "default"
44+ VARS_TYPES = {
45+ "data" ,
46+ "ilist" ,
47+ "int" ,
48+ "real" ,
49+ "rlist" ,
50+ "slist" ,
51+ "string" ,
52+ }
53+ PROMISE_BLOCK_ATTRIBUTES = ("path" , "interpreter" )
54+ KNOWN_FAULTY_FUNCTION_DEFS = {"regex_replace" }
4355
4456
4557@dataclass
@@ -130,7 +142,7 @@ class PolicyFile:
130142 reused when we iterate over it multiple times.
131143
132144 We store filename, raw data (bytes), array of lines, and syntax tree/nodes.
133- This is a but of "duplication", but they are useful for printing nice
145+ This is a bit of "duplication", but they are useful for printing nice
134146 linting errors.
135147
136148 This is intended as a read-only view of the policy file, not to be used for
@@ -140,7 +152,7 @@ class PolicyFile:
140152 - Whether the file is empty
141153 - Whether the file has syntax errors
142154 - Whether the file uses macros (Macros can indicate we need to be less strict)
143- - Things defined and referenced in the file (bundles, bodies, promise types, )
155+ - Things defined and referenced in the file (bundles, bodies, promise types)
144156 """
145157
146158 def __init__ (self , filename : str , snippet : Snippet | None = None ):
@@ -179,7 +191,7 @@ class State:
179191 block_name : str | None = None
180192 promise_type : str | None = None # "vars" | "files" | "classes" | ... | None
181193 attribute_name : str | None = None # "if" | "string" | "slist" | ... | None
182- namespace : str = "default" # "ns" | "default" | ... |
194+ namespace : str = DEFAULT_NAMESPACE # "ns" | "default" | ... |
183195 mode : Mode = Mode .NONE
184196 walking : bool = False
185197 strict : bool = True
@@ -244,7 +256,7 @@ def start_file(self, policy_file: PolicyFile):
244256 assert self .mode != Mode .NONE
245257
246258 self .policy_file = policy_file
247- self .namespace = "default"
259+ self .namespace = DEFAULT_NAMESPACE
248260 self .walking = True
249261
250262 def end_file (self ) -> None :
@@ -562,24 +574,14 @@ def _lint_node(
562574 return 1
563575 if state .promise_type == "vars" and node .type == "promise" :
564576 attribute_nodes = [x for x in node .children if x .type == "attribute" ]
565- # Each vars promise must include exactly 1 of these attributes (a value):
566- vars_types = {
567- "data" ,
568- "ilist" ,
569- "int" ,
570- "real" ,
571- "rlist" ,
572- "slist" ,
573- "string" ,
574- }
575577 # Attributes are children of a promise, and attribute names are children of attributes
576578 # Need to iterate inside to find the attribute name (data, ilist, int, etc.)
577579 value_nodes = []
578580 for attr in attribute_nodes :
579581 for child in attr .children :
580582 if child .type != "attribute_name" :
581583 continue
582- if _text (child ) in vars_types :
584+ if _text (child ) in VARS_TYPES :
583585 # Ignore the other attributes which are not values
584586 value_nodes .append (child )
585587
@@ -658,23 +660,17 @@ def _lint_node(
658660 if (
659661 state .block_keyword == "promise"
660662 and node .type == "attribute_name"
661- and state .attribute_name
662- not in (
663- None ,
664- "path" ,
665- "interpreter" ,
666- )
663+ and state .attribute_name not in (None , * PROMISE_BLOCK_ATTRIBUTES )
667664 ):
668665 _highlight_range (node , lines )
669666 print (
670667 f"Error: Invalid attribute name '{ state .attribute_name } ' in '{ state .block_name } ' custom promise type definition { location } "
671668 )
672669 return 1
673670 if node .type == "call" :
674- known_faulty_defs = {"regex_replace" }
675671 call , _ , * args , _ = node .children # f ( a1 , a2 , a..N )
676672 call = _text (call )
677- if call in known_faulty_defs :
673+ if call in KNOWN_FAULTY_FUNCTION_DEFS :
678674 return 0
679675
680676 args = list (filter ("," .__ne__ , iter (_text (x ) for x in args )))
@@ -986,8 +982,8 @@ def _walk_callback(node: Node, callback: Callable[[Node], int]) -> int:
986982def _parse_policy_file (filename : str ) -> tuple [Tree , list [str ], bytes ]:
987983 """Parse a policy file into a syntax tree using tree sitter.
988984
989- This function is used by PolicyFile constructor, in most cases it will be
990- to call Policyfile (filename) instead of this function."""
985+ This function is used by PolicyFile constructor, in most cases it is better
986+ to call PolicyFile (filename) instead of this function."""
991987 assert os .path .isfile (filename )
992988 PY_LANGUAGE = Language (tscfengine .language ())
993989 parser = Parser (PY_LANGUAGE )
0 commit comments