88from os import PathLike
99from pathlib import Path
1010from string import Template
11- from typing import Collection , Optional
11+ from typing import Collection , Optional , Any
1212
1313import networkx as nx
1414from attr import dataclass
@@ -116,7 +116,7 @@ def _treeStr(
116116 # Remove last linebreak as the last line can contain spaces
117117 return s .rstrip (), found
118118
119- def _dropdown (self , items : Collection [str ]) -> str :
119+ def _dropdown (self , items : Collection [str ], sort : bool = True ) -> str :
120120 """
121121 Converts the items into a markdown dropwon list if the length is 10 or more
122122
@@ -127,16 +127,53 @@ def _dropdown(self, items: Collection[str]) -> str:
127127 """
128128
129129 if len (items ) <= self ._DROPDOWN_THRESHOLD :
130- return "<br>" .join ([f"`{ item } `" for item in sorted (items )])
130+ return "<br>" .join (
131+ [f"`{ item } `" for item in (sorted (items ) if sort else items )]
132+ )
131133 else :
132- for first in sorted (items ):
134+ for first in sorted (items ) if sort else items :
133135 return (
134136 f"<details><summary>{ first } ...</summary>"
135- + "<br>" .join ([f"`{ item } `" for item in sorted (items )])
137+ + "<br>" .join (
138+ [f"`{ item } `" for item in (sorted (items ) if sort else items )]
139+ )
136140 + "</details>"
137141 )
138142 return ""
139143
144+ def _format_files (self , files : Collection [str ]) -> list [str ]:
145+ """
146+ Rebuild a dictionary from the comma-separated hierarchy and return a representation with indentation
147+
148+ :param files: List of files
149+
150+ :return: list(str) Sorted and formatted files
151+ :since: 1.0.0
152+ """
153+
154+ dictionary : dict [str , Any ] = {}
155+
156+ def fill_dictionary (d : dict [str , Any ], parts : list [str ]) -> None :
157+ if parts [0 ] not in d :
158+ d [parts [0 ]] = {}
159+ if len (parts ) > 1 :
160+ fill_dictionary (d [parts [0 ]], parts [1 :])
161+
162+ for file in files :
163+ fill_dictionary (dictionary , file .split ("," ))
164+
165+ def dict_to_strs (d : dict [str , Any ], prefix : str = "" ) -> list [str ]:
166+ lines = []
167+ for part in sorted (d ):
168+ if d [part ] == {}:
169+ lines .append (prefix + part )
170+ else :
171+ lines .append (prefix + part + ":" )
172+ lines = lines + dict_to_strs (d [part ], prefix = prefix + " " )
173+ return lines
174+
175+ return dict_to_strs (dictionary )
176+
140177 def _format_nighlty_stats (self ) -> str :
141178 """
142179 Parses nightly_stats file and formats a human readable result
@@ -283,7 +320,7 @@ def sorting_function(files: frozenset[str]) -> tuple[int, str]:
283320 for files in sorted (trees , key = sorting_function ):
284321 flavors , tree = trees [files ]
285322 row = "|"
286- row += self ._dropdown (files )
323+ row += self ._dropdown (self . _format_files ( files ), sort = False )
287324 row += "|"
288325 row += f"**{ round (100 * (len (flavors ) / len (self ._diff_parser .expected_falvors )), 1 )} %** affected<br>"
289326 row += self ._dropdown (flavors )
0 commit comments