Skip to content

Commit 5fa173a

Browse files
committed
Separate GL features parsing based on canonical name and calculated graph
Signed-off-by: Tobias Wolf <[email protected]>
1 parent 81f9c28 commit 5fa173a

File tree

1 file changed

+109
-46
lines changed

1 file changed

+109
-46
lines changed

src/gardenlinux/features/parser.py

Lines changed: 109 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -137,34 +137,8 @@ def filter(
137137
:since: 0.7.0
138138
"""
139139

140-
input_features = Parser.get_cname_as_feature_set(cname)
141-
filter_set = input_features.copy()
142-
143-
# @TODO: Remove "special" handling once "bare" is a first-class citizen of the feature graph
144-
if "bare" in input_features:
145-
if not self.graph.has_node("bare"):
146-
self.graph.add_node("bare", content=BARE_FLAVOR_FEATURE_CONTENT)
147-
if not self.graph.has_node("libc"):
148-
self.graph.add_node("libc", content=BARE_FLAVOR_LIBC_FEATURE_CONTENT)
149-
150-
for feature in input_features:
151-
filter_set.update(
152-
networkx.descendants(
153-
Parser._get_graph_view_for_attr(self.graph, "include"), feature
154-
)
155-
)
156-
157-
graph = networkx.subgraph_view(
158-
self.graph,
159-
filter_node=self._get_filter_set_callable(
160-
filter_set, additional_filter_func
161-
),
162-
)
163-
164-
if not ignore_excludes:
165-
Parser._exclude_from_filter_set(graph, input_features, filter_set)
166-
167-
return graph
140+
feature_set = Parser.get_cname_as_feature_set(cname)
141+
return self.filter_based_on_feature_set(feature_set, ignore_excludes, additional_filter_func)
168142

169143
def filter_as_dict(
170144
self,
@@ -184,19 +158,7 @@ def filter_as_dict(
184158
"""
185159

186160
graph = self.filter(cname, ignore_excludes, additional_filter_func)
187-
features = Parser.sort_reversed_graph_nodes(graph)
188-
189-
features_by_type = {}
190-
191-
for feature in features:
192-
node_type = Parser._get_graph_node_type(graph.nodes[feature])
193-
194-
if node_type not in features_by_type:
195-
features_by_type[node_type] = []
196-
197-
features_by_type[node_type].append(feature)
198-
199-
return features_by_type
161+
return self.filter_graph_as_dict(graph)
200162

201163
def filter_as_list(
202164
self,
@@ -216,7 +178,7 @@ def filter_as_list(
216178
"""
217179

218180
graph = self.filter(cname, ignore_excludes, additional_filter_func)
219-
return Parser.sort_reversed_graph_nodes(graph)
181+
return self.filter_graph_as_list(graph)
220182

221183
def filter_as_string(
222184
self,
@@ -236,15 +198,116 @@ def filter_as_string(
236198
"""
237199

238200
graph = self.filter(cname, ignore_excludes, additional_filter_func)
201+
return self.filter_graph_as_string(graph)
202+
203+
def filter_graph_as_dict(
204+
self,
205+
graph: networkx.Graph,
206+
) -> dict:
207+
"""
208+
Filters the features graph and returns it as a dict.
209+
210+
:param graph: Features graph
211+
212+
:return: (dict) List of features for a given cname, split into platform, element and flag
213+
:since: 0.9.2
214+
"""
215+
239216
features = Parser.sort_reversed_graph_nodes(graph)
240217

218+
features_by_type = {}
219+
220+
for feature in features:
221+
node_type = Parser._get_graph_node_type(graph.nodes[feature])
222+
223+
if node_type not in features_by_type:
224+
features_by_type[node_type] = []
225+
226+
features_by_type[node_type].append(feature)
227+
228+
return features_by_type
229+
230+
def filter_graph_as_list(
231+
self,
232+
graph: networkx.Graph,
233+
) -> list:
234+
"""
235+
Filters the features graph and returns it as a list.
236+
237+
:param graph: Features graph
238+
239+
:return: (list) Features list for a given cname
240+
:since: 0.9.2
241+
"""
242+
243+
return Parser.sort_reversed_graph_nodes(graph)
244+
245+
def filter_graph_as_string(
246+
self,
247+
graph: networkx.Graph,
248+
) -> str:
249+
"""
250+
Filters the features graph and returns it as a string.
251+
252+
:param graph: Features graph
253+
254+
:return: (str) Comma separated string with the expanded feature set for the cname
255+
:since: 0.9.2
256+
"""
257+
258+
features = Parser.sort_reversed_graph_nodes(graph)
241259
return ",".join(features)
242260

243-
def _exclude_from_filter_set(graph, input_features, filter_set):
261+
def filter_based_on_feature_set(
262+
self,
263+
feature_set: (str,),
264+
ignore_excludes: bool = False,
265+
additional_filter_func: Optional[Callable[(str,), bool]] = None,
266+
) -> networkx.Graph:
267+
"""
268+
Filters the features graph based on a feature set given.
269+
270+
:param feature_set: Feature set to filter
271+
:param ignore_excludes: Ignore `exclude` feature files
272+
:param additional_filter_func: Additional filter function
273+
274+
:return: (networkx.Graph) Filtered features graph
275+
:since: 0.9.2
276+
"""
277+
278+
filter_set = feature_set.copy()
279+
280+
# @TODO: Remove "special" handling once "bare" is a first-class citizen of the feature graph
281+
if "bare" in feature_set:
282+
if not self.graph.has_node("bare"):
283+
self.graph.add_node("bare", content=BARE_FLAVOR_FEATURE_CONTENT)
284+
if not self.graph.has_node("libc"):
285+
self.graph.add_node("libc", content=BARE_FLAVOR_LIBC_FEATURE_CONTENT)
286+
287+
for feature in feature_set:
288+
filter_set.update(
289+
networkx.descendants(
290+
Parser._get_graph_view_for_attr(self.graph, "include"), feature
291+
)
292+
)
293+
294+
graph = networkx.subgraph_view(
295+
self.graph,
296+
filter_node=self._get_filter_set_callable(
297+
filter_set, additional_filter_func
298+
),
299+
)
300+
301+
if not ignore_excludes:
302+
Parser._exclude_from_filter_set(graph, feature_set, filter_set)
303+
304+
return graph
305+
306+
def _exclude_from_filter_set(graph, feature_set, filter_set):
244307
"""
245-
Removes the given `filter_set` out of `input_features`.
308+
Removes the given `filter_set` out of `feature_set`.
246309
247-
:param input_features: Features
310+
:param feature_set: Features
248311
:param filter_set: Set to filter out
249312
250313
:since: 0.7.0
@@ -259,7 +322,7 @@ def _exclude_from_filter_set(graph, input_features, filter_set):
259322
exclude_list.append(exclude)
260323

261324
for exclude in exclude_list:
262-
if exclude in input_features:
325+
if exclude in feature_set:
263326
raise ValueError(
264327
f"Excluding explicitly included feature {exclude}, unsatisfiable condition"
265328
)

0 commit comments

Comments
 (0)