@@ -549,6 +549,69 @@ const guideline_code_can_be_downloaded = Guideline(;
549549 ),
550550)
551551
552+ function _find_lowercase_duplicates (v)
553+ elts = Dict {String, String} ()
554+ for x in v
555+ lower_x = lowercase (x)
556+ if haskey (elts, lower_x)
557+ return (elts[lower_x], x)
558+ else
559+ elts[lower_x] = x
560+ end
561+ end
562+ return nothing
563+ end
564+
565+ const DISALLOWED_CHARS = [' /' , ' <' , ' >' , ' :' , ' "' , ' /' , ' \\ ' , ' |' , ' ?' , ' *' , Char .(0 : 31 )... ]
566+
567+ const DISALLOWED_NAMES = [" CON" , " PRN" , " AUX" , " NUL" ,
568+ (" COM$i " for i in 1 : 9 ). .. ,
569+ (" LPT$i " for i in 1 : 9 ). .. ]
570+
571+ function meets_file_dir_name_check (name)
572+ # https://stackoverflow.com/a/31976060
573+ idx = findfirst (n -> occursin (n, name), DISALLOWED_CHARS)
574+ if idx != = nothing
575+ return false , " contains character $(DISALLOWED_CHARS[idx]) which may not be valid as a file or directory name on some platforms"
576+ end
577+
578+ base, ext = splitext (name)
579+ if uppercase (name) in DISALLOWED_NAMES || uppercase (base) in DISALLOWED_NAMES
580+ return false , " is not allowed"
581+ end
582+ if endswith (name, " ." ) || endswith (name, r" \s " )
583+ return false , " ends with `.` or space"
584+ end
585+ return true , " "
586+ end
587+
588+ function meets_src_names_ok (pkg_code_path)
589+ src = joinpath (pkg_code_path, " src/" )
590+ isdir (src) || return false , " `src` directory not found"
591+ for (root, dirs, files) in walkdir (src)
592+ files_dirs = Iterators. flatten ((files, dirs))
593+ result = _find_lowercase_duplicates (files_dirs)
594+ if result != = nothing
595+ x = joinpath (root, result[1 ])
596+ y = joinpath (root, result[2 ])
597+ return false , " Found files or directories in `src` which will cause problems on case insensitive filesystems: `$x ` and `$y `"
598+ end
599+
600+ for f in files_dirs
601+ ok, msg = meets_file_dir_name_check (f)
602+ if ! ok
603+ return false , " the name of file or directory $(joinpath (root, f)) $(msg) . This can cause problems on some operating systems or file systems."
604+ end
605+ end
606+ end
607+ return true , " "
608+ end
609+
610+ const guideline_src_names_OK = Guideline (;
611+ info= " `src` files and directories names are OK" ,
612+ check= data -> meets_src_names_ok (data. pkg_code_path),
613+ )
614+
552615function meets_code_can_be_downloaded (registry_head, pkg, version, pr; pkg_code_path)
553616 uuid, package_repo, subdir, tree_hash_from_toml = parse_registry_pkg_info (
554617 registry_head, pkg, version
@@ -909,6 +972,7 @@ function get_automerge_guidelines(
909972 # after `guideline_code_can_be_downloaded` so
910973 # that it can use the downloaded code!
911974 (guideline_version_has_osi_license, check_license),
975+ (guideline_src_names_OK, true ),
912976 (guideline_version_can_be_imported, true ),
913977 (:update_status , true ),
914978 (guideline_dependency_confusion, true ),
@@ -948,6 +1012,7 @@ function get_automerge_guidelines(
9481012 # after `guideline_code_can_be_downloaded` so
9491013 # that it can use the downloaded code!
9501014 (guideline_version_has_osi_license, check_license),
1015+ (guideline_src_names_OK, true ),
9511016 (guideline_version_can_be_imported, true ),
9521017 ]
9531018 return guidelines
0 commit comments