From 1631c8fc35b36e16ee18cc1d2ef4436cd8a46563 Mon Sep 17 00:00:00 2001 From: Jan Rodak Date: Thu, 16 May 2024 13:39:15 +0200 Subject: [PATCH] Add used rules of component --- utils/profile_tool/common.py | 16 +++++++++ utils/profile_tool/most_used_components.py | 41 ++++++++++++++++++---- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/utils/profile_tool/common.py b/utils/profile_tool/common.py index ae5729451f06..8eea054491fa 100644 --- a/utils/profile_tool/common.py +++ b/utils/profile_tool/common.py @@ -13,3 +13,19 @@ def generate_output(dict_, format, csv_header): for rule_id, rule_count in dict_.items(): print(f_string.format(rule_id, rule_count)) + + +def _format_value_b(value_b, delim): + str_ = "" + if len(value_b) != 0: + values = ", ".join([f"{key}: {value}" for key, value in value_b.items()]) + str_ = f"{delim}{values}" + return str_ + + +def merge_dicts(dict_a, dict_b, delim): + out = {} + for key, value in dict_a.items(): + value_b = dict_b.get(key, {}) + out[key] = str(value) + _format_value_b(value_b, delim) + return out diff --git a/utils/profile_tool/most_used_components.py b/utils/profile_tool/most_used_components.py index 1ca9b9551a48..6c22fb3874b2 100644 --- a/utils/profile_tool/most_used_components.py +++ b/utils/profile_tool/most_used_components.py @@ -5,7 +5,7 @@ import ssg.components from .most_used_rules import _sorted_dict_by_num_value -from .common import generate_output +from .common import generate_output, merge_dicts PYTHON_2 = sys.version_info[0] < 3 @@ -17,10 +17,21 @@ ) -def _count_components(components, rules_list, components_out): +def _count_rules_components(component_name, rules, used_rules_of_components_out): + used_rules = defaultdict(int) + if component_name in used_rules_of_components_out: + used_rules = used_rules_of_components_out[component_name] + for rule in rules: + used_rules[rule] += 1 + used_rules_of_components_out[component_name] = used_rules + + +def _count_components(components, rules_list, components_out, used_rules_of_components_out): for component_name, component in components.items(): - if len(set(component.rules).intersection(set(rules_list))) > 0: + intersection = set(component.rules).intersection(set(rules_list)) + if len(intersection) > 0: components_out[component_name] += 1 + _count_rules_components(component_name, intersection, used_rules_of_components_out) def load_components(product): @@ -33,7 +44,7 @@ def load_components(product): return ssg.components.load(components_dir) -def _process_all_products_from_controls(components_out, products): +def _process_all_products_from_controls(components_out, used_rules_of_components_out, products): if PYTHON_2: raise Exception("This feature is not supported for python2.") @@ -43,14 +54,32 @@ def _process_all_products_from_controls(components_out, products): continue controls_manager = load_controls_manager("./controls/", product) for profile in _get_profiles_for_product(controls_manager, product): - _count_components(components, profile.rules, components_out) + _count_components( + components, profile.rules, components_out, used_rules_of_components_out + ) + + +def _sort_rules_of_components(used_rules_of_components): + out = {} + for key, value in used_rules_of_components.items(): + out[key] = _sorted_dict_by_num_value(value) + return out def command_most_used_components(args): components = defaultdict(int) + used_rules_of_components = {} - _process_all_products_from_controls(components, args.products) + _process_all_products_from_controls(components, used_rules_of_components, args.products) sorted_components = _sorted_dict_by_num_value(components) csv_header = "component_name,count_of_profiles" + if args.used_rules: + csv_header = "component_name,count_of_profiles,used_rules:count_of_profiles" + delim = " " + if args.format == "csv": + delim = "," + sorted_used_rules_of_components = _sort_rules_of_components(used_rules_of_components) + sorted_components = merge_dicts(sorted_components, sorted_used_rules_of_components, delim) + generate_output(sorted_components, args.format, csv_header)