12
12
import pathlib
13
13
import pprint
14
14
import uuid
15
+ from difflib import get_close_matches
15
16
from functools import cached_property
16
17
from typing import List , Optional , Tuple , Union
17
18
@@ -160,16 +161,18 @@ def getReferencesListForJson(self) -> List[str]:
160
161
def mapNamesToSecurityContentObjects (
161
162
cls , v : list [str ], director : Union [DirectorOutputDto , None ]
162
163
) -> list [Self ]:
163
- if director is not None :
164
- name_map = director .name_to_content_map
165
- else :
166
- name_map = {}
164
+ if director is None :
165
+ raise Exception (
166
+ "Direction was 'None' when passed to "
167
+ "'mapNamesToSecurityContentObjects'. This is "
168
+ "an error in the contentctl codebase which must be resolved."
169
+ )
167
170
168
171
mappedObjects : list [Self ] = []
169
172
mistyped_objects : list [SecurityContentObject_Abstract ] = []
170
173
missing_objects : list [str ] = []
171
174
for object_name in v :
172
- found_object = name_map .get (object_name , None )
175
+ found_object = director . name_to_content_map .get (object_name , None )
173
176
if not found_object :
174
177
missing_objects .append (object_name )
175
178
elif not isinstance (found_object , cls ):
@@ -178,22 +181,40 @@ def mapNamesToSecurityContentObjects(
178
181
mappedObjects .append (found_object )
179
182
180
183
errors : list [str ] = []
181
- if len (missing_objects ) > 0 :
184
+ for missing_object in missing_objects :
185
+ if missing_object .endswith ("_filter" ):
186
+ # Most filter macros are defined as empty at runtime, so we do not
187
+ # want to make any suggestions. It is time consuming and not helpful
188
+ # to make these suggestions, so we just skip them in this check.
189
+ continue
190
+ matches = get_close_matches (
191
+ missing_object ,
192
+ director .name_to_content_map .keys (),
193
+ n = 3 ,
194
+ )
195
+ if matches == []:
196
+ matches = ["NO SUGGESTIONS" ]
197
+
198
+ matches_string = ", " .join (matches )
182
199
errors .append (
183
- f"Failed to find the following '{ cls .__name__ } ': { missing_objects } "
200
+ f"Unable to find: { missing_object } \n Suggestions: { matches_string } "
201
+ )
202
+
203
+ for mistyped_object in mistyped_objects :
204
+ matches = get_close_matches (
205
+ mistyped_object .name , director .name_to_content_map .keys (), n = 3
206
+ )
207
+
208
+ errors .append (
209
+ f"'{ mistyped_object .name } ' expected to have type '{ cls .__name__ } ', but actually "
210
+ f"had type '{ type (mistyped_object ).__name__ } '"
184
211
)
185
- if len (mistyped_objects ) > 0 :
186
- for mistyped_object in mistyped_objects :
187
- errors .append (
188
- f"'{ mistyped_object .name } ' expected to have type '{ cls } ', but actually "
189
- f"had type '{ type (mistyped_object )} '"
190
- )
191
212
192
213
if len (errors ) > 0 :
193
- error_string = "\n - " .join (errors )
214
+ error_string = "\n \n - " .join (errors )
194
215
raise ValueError (
195
- f"Found { len (errors )} issues when resolving references Security Content Object "
196
- f"names: \n - { error_string } "
216
+ f"Found { len (errors )} issues when resolving references to ' { cls . __name__ } ' objects: \n "
217
+ f" - { error_string } "
197
218
)
198
219
199
220
# Sort all objects sorted by name
0 commit comments