11from __future__ import annotations
22
3- import operator
43from functools import cmp_to_key
54
65from gitlab_codeowners_linter .constants import DEFAULT_SECTION
76from gitlab_codeowners_linter .sorting import sort_paths
7+ from gitlab_codeowners_linter .sorting import sort_section_names
88
99
1010def fix (codeowners_data , violations , file_path ):
@@ -13,15 +13,34 @@ def fix(codeowners_data, violations, file_path):
1313
1414 # Are custom section names sorted?
1515 if violations .section_names_sorted :
16+ sort_sections_names_key = cmp_to_key (sort_section_names )
1617 sorted_sections_names = sorted (
1718 codeowners_data [1 :],
18- key = operator . attrgetter ( 'codeowner_section' ) ,
19+ key = sort_sections_names_key ,
1920 )
2021 codeowners_data_updated = []
2122 codeowners_data_updated .append (codeowners_data [0 ])
2223 codeowners_data_updated .extend (sorted_sections_names )
2324 codeowners_data = codeowners_data_updated
2425
26+ # Are there duplicated sections?
27+
28+ if violations .duplicated_sections != []:
29+ # If multiple sections have the same name, they are combined.
30+ # Also, section headings are not case-sensitive.
31+ # For example the entries defined under the sections Documentation
32+ # and DOCUMENTATION are combined, using the case of the first section
33+ i = 0
34+ while i < len (codeowners_data )- 1 :
35+ if codeowners_data [i ].codeowner_section .lower () == codeowners_data [i + 1 ].codeowner_section .lower ():
36+ codeowners_data [i ].comments = codeowners_data [i ].comments + \
37+ codeowners_data [i + 1 ].comments
38+ codeowners_data [i ].entries = codeowners_data [i ].entries + \
39+ codeowners_data [i + 1 ].entries
40+ codeowners_data .pop (i + 1 )
41+ else :
42+ i += 1
43+
2544 # Then fix section's content
2645
2746 codeowners_data_updated = []
@@ -34,14 +53,14 @@ def fix(codeowners_data, violations, file_path):
3453 else :
3554 codeowners_data_updated [- 1 ] = _fix_blank_lines (
3655 codeowners_data_updated [- 1 ])
37- if violations .unsorted_paths_in_sections != []:
38- if not section .codeowner_section in violations .unsorted_paths_in_sections :
56+ if violations .unsorted_paths_in_sections != [] or violations . duplicated_sections != [] :
57+ if not section .codeowner_section in violations .unsorted_paths_in_sections and violations . duplicated_sections == [] :
3958 pass
4059 else :
4160 codeowners_data_updated [- 1 ] = _fix_unsorted_paths (
4261 codeowners_data_updated [- 1 ])
43- if violations .sections_with_duplicate_paths != []:
44- if not section .codeowner_section in violations .sections_with_duplicate_paths :
62+ if violations .sections_with_duplicate_paths != [] or violations . duplicated_sections != [] :
63+ if not section .codeowner_section in violations .sections_with_duplicate_paths and violations . duplicated_sections == [] :
4564 pass
4665 else :
4766 codeowners_data_updated [- 1 ] = _fix_duplicated_paths (
@@ -51,7 +70,7 @@ def fix(codeowners_data, violations, file_path):
5170 pass
5271 else :
5372 codeowners_data_updated [- 1 ] = _fix_nonexisting_paths (
54- codeowners_data_updated [- 1 ], violations .non_existing_paths [violations . sections_with_non_existing_paths . index ( section .codeowner_section )])
73+ codeowners_data_updated [- 1 ], violations .non_existing_paths [section .codeowner_section . lower ( )])
5574 codeowners_data = codeowners_data_updated
5675
5776 _update_codeowners_file (codeowners_data , file_path )
0 commit comments