@@ -226,6 +226,7 @@ def validate_module_name_content(name):
226226 # lowercase ASCII alphanumericals, starting with a letter, and possible singular dashes in the middle
227227 r = "[a-z][a-z0-9]*(-[a-z0-9]+)*"
228228 proper_name = name
229+ original_component = name
229230
230231 if is_module_local (name ) or is_module_absolute (name ):
231232 # If one of these are true, the other must be false
@@ -246,6 +247,7 @@ def validate_module_name_content(name):
246247
247248 # only validate the local module's name, not the entire path to it
248249 proper_name = proper_name .split ("/" )[- 1 ]
250+ original_component = proper_name
249251
250252 # allow underscores, only for local and absolute modules
251253 proper_name = proper_name .replace ("_" , "-" )
@@ -264,6 +266,7 @@ def validate_module_name_content(name):
264266 proper_name = strip_right (proper_name , "/" )
265267 # TODO: more validation of the entire path instead of just the name (final component), since the module "name" is actually a path
266268 proper_name = proper_name .split ("/" )[- 1 ]
269+ original_component = proper_name
267270
268271 # allow underscores, only for local and absolute modules
269272 proper_name = proper_name .replace ("_" , "-" )
@@ -274,18 +277,32 @@ def validate_module_name_content(name):
274277 "Module name proper is empty" ,
275278 )
276279
280+ # builds a suggested fix for the module name
281+ suggested_proper_name = re .sub (r"[^a-z0-9]+" , "-" , proper_name .lower ()).strip ("-" )
282+ if suggested_proper_name and re .fullmatch (r , suggested_proper_name ):
283+ last_idx = name .rfind (original_component )
284+ suggested_name = (
285+ name [:last_idx ]
286+ + suggested_proper_name
287+ + name [last_idx + len (original_component ) :]
288+ )
289+ suggestion = " Consider renaming it to '{}'." .format (suggested_name )
290+ else :
291+ suggestion = ""
292+
277293 if proper_name [0 ] not in "abcdefghijklmnopqrstuvwxyz" :
278294 raise CFBSValidationError (
279295 name ,
280- "Module name must start with a lowercase ASCII letter ('{}' starts with '{}')" .format (
281- proper_name , proper_name [0 ]
296+ "Module name must start with a lowercase ASCII letter ('{}' starts with '{}'){} " .format (
297+ proper_name , proper_name [0 ], suggestion
282298 ),
283299 )
284300
285301 if not re .fullmatch (r , proper_name ):
286302 raise CFBSValidationError (
287303 name ,
288- "Module name contains illegal characters (only lowercase ASCII alphanumeric characters and single dash separators are allowed)" ,
304+ "Module name contains illegal characters (only lowercase ASCII alphanumeric characters and single dash separators are allowed)"
305+ + suggestion ,
289306 )
290307
291308 log .debug ("Successfully validated name of module %s" % name )
0 commit comments