Skip to content

Commit 2ba47b9

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

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
@@ -131,34 +131,8 @@ def filter(
131131
:since: 0.7.0
132132
"""
133133

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

163137
def filter_as_dict(
164138
self,
@@ -178,19 +152,7 @@ def filter_as_dict(
178152
"""
179153

180154
graph = self.filter(cname, ignore_excludes, additional_filter_func)
181-
features = Parser.sort_reversed_graph_nodes(graph)
182-
183-
features_by_type = {}
184-
185-
for feature in features:
186-
node_type = Parser._get_graph_node_type(graph.nodes[feature])
187-
188-
if node_type not in features_by_type:
189-
features_by_type[node_type] = []
190-
191-
features_by_type[node_type].append(feature)
192-
193-
return features_by_type
155+
return self.filter_graph_as_dict(graph)
194156

195157
def filter_as_list(
196158
self,
@@ -210,7 +172,7 @@ def filter_as_list(
210172
"""
211173

212174
graph = self.filter(cname, ignore_excludes, additional_filter_func)
213-
return Parser.sort_reversed_graph_nodes(graph)
175+
return self.filter_graph_as_list(graph)
214176

215177
def filter_as_string(
216178
self,
@@ -230,15 +192,116 @@ def filter_as_string(
230192
"""
231193

232194
graph = self.filter(cname, ignore_excludes, additional_filter_func)
195+
return self.filter_graph_as_string(graph)
196+
197+
def filter_graph_as_dict(
198+
self,
199+
graph: networkx.Graph,
200+
) -> dict:
201+
"""
202+
Filters the features graph and returns it as a dict.
203+
204+
:param graph: Features graph
205+
206+
:return: (dict) List of features for a given cname, split into platform, element and flag
207+
:since: 0.9.2
208+
"""
209+
233210
features = Parser.sort_reversed_graph_nodes(graph)
234211

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

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

257320
for exclude in exclude_list:
258-
if exclude in input_features:
321+
if exclude in feature_set:
259322
raise ValueError(
260323
f"Excluding explicitly included feature {exclude}, unsatisfiable condition"
261324
)

0 commit comments

Comments
 (0)