1+ from copy import deepcopy
2+ from fmf .context import Context
3+ #from fmf.base import Tree
4+ """
5+ generic _definition/:
6+ where: a is defined and b is defined
7+ key1: value1 # override
8+ key2+: value2 # append
9+ key3-: value3 # remove
10+ key4?: value4 # define if not defined
11+
12+ plan_definition/:
13+ where: execute is defined and discovery is defined
14+
15+ # append to prepare phase
16+ prepare+:
17+ name: some name
18+ how: shell
19+ script: systemctl start httpd
20+ # create reporting if not defined
21+ report?:
22+ how: html
23+ open: true
24+
25+ # override provision by own definition
26+ provision:
27+ how: virtual
28+ image: fedora-37
29+
30+
31+
32+ """
33+
34+
35+ class ProfileError (Exception ):
36+ pass
37+
38+
39+ class ProfileWithoutWhereStatement (ProfileError ):
40+ pass
41+
42+
43+ class Profile :
44+
45+ def __init__ (self , rule : dict , name = None ):
46+ self ._raw_rule = rule
47+ self .name = name
48+ if "where" not in self ._raw_rule .keys ():
49+ raise ProfileWithoutWhereStatement
50+ self .where = self ._raw_rule .pop ("where" )
51+ self .rules = deepcopy (self ._raw_rule )
52+
53+ def _check_if_fmf_node_match (self , node ):
54+ context = Context (** node .data )
55+ return context .matches (self .where )
56+
57+ def _apply_rule (self , node ):
58+
59+ if not self ._check_if_fmf_node_match (node ):
60+ return
61+ for rule in self .rules :
62+ if isinstance (rule , str ) and rule .endswith ("?" ):
63+ rule_clear = rule [:- 1 ]
64+ data = {rule_clear : self .rules [rule ]}
65+ if rule_clear in node .data :
66+ # do not override if defined
67+ continue
68+ else :
69+ data = {rule : self .rules [rule ]}
70+ node ._merge_special (node .data , data )
71+
72+ def apply_rule (self , node ):
73+ for item in node .climb ():
74+ self ._apply_rule (item )
0 commit comments