mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 02:24:30 +08:00
- 将验证逻辑从 Python 代码转换为 Bash 脚本实现 - 使用 grep 和正则表达式替换 Python 的字符串匹配功能 - 实现 PascalCase 验证的正则表达式模式 - 添加目录路径和命名空间段的验证逻辑 - 保持原有的排除规则和错误报告格式 - 移除对 Python3 的依赖,仅使用系统内置命令
149 lines
4.1 KiB
Bash
149 lines
4.1 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if ! command -v git >/dev/null 2>&1; then
|
|
echo "git is required to enumerate tracked C# files." >&2
|
|
exit 2
|
|
fi
|
|
|
|
if ! command -v grep >/dev/null 2>&1; then
|
|
echo "grep is required to validate C# naming conventions." >&2
|
|
exit 2
|
|
fi
|
|
|
|
repo_root="$(git rev-parse --show-toplevel)"
|
|
cd "$repo_root"
|
|
|
|
readonly PASCAL_CASE_REGEX='^(?:[A-Z](?=[A-Z][a-z0-9])|[A-Z]{2}(?=$|[A-Z][a-z0-9])|[A-Z][a-z0-9]+)+$'
|
|
|
|
files_checked=0
|
|
declare -a namespace_violations=()
|
|
declare -a directory_violations=()
|
|
declare -A seen_directories=()
|
|
declare -A seen_directory_violations=()
|
|
|
|
is_excluded() {
|
|
local path="$1"
|
|
case "$path" in
|
|
Godot/script_templates|Godot/script_templates/*)
|
|
return 0
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
validate_segment() {
|
|
local segment="$1"
|
|
|
|
if [[ ! "$segment" =~ ^[A-Za-z][A-Za-z0-9]*$ ]]; then
|
|
printf '%s' "must start with a letter and contain only letters or digits"
|
|
return 1
|
|
fi
|
|
|
|
if [[ ! "$segment" =~ ^[A-Z] ]]; then
|
|
printf '%s' "must start with an uppercase letter"
|
|
return 1
|
|
fi
|
|
|
|
if [[ "$segment" =~ ^[A-Z]+$ ]]; then
|
|
if (( ${#segment} <= 2 )); then
|
|
return 0
|
|
fi
|
|
|
|
printf '%s' "acronyms longer than 2 letters must use PascalCase"
|
|
return 1
|
|
fi
|
|
|
|
if ! printf '%s\n' "$segment" | grep -Pq "$PASCAL_CASE_REGEX"; then
|
|
printf '%s' "must use PascalCase; only 2-letter acronyms may stay fully uppercase"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
check_directory_path() {
|
|
local relative_dir="$1"
|
|
local raw_segment=""
|
|
local segment=""
|
|
local reason=""
|
|
local key=""
|
|
|
|
IFS='/' read -r -a raw_segments <<< "$relative_dir"
|
|
for raw_segment in "${raw_segments[@]}"; do
|
|
IFS='.' read -r -a segments <<< "$raw_segment"
|
|
for segment in "${segments[@]}"; do
|
|
if ! reason="$(validate_segment "$segment")"; then
|
|
key="$relative_dir|$segment|$reason"
|
|
if [[ -z "${seen_directory_violations[$key]:-}" ]]; then
|
|
seen_directory_violations["$key"]=1
|
|
directory_violations+=("- $relative_dir -> \"$segment\": $reason")
|
|
fi
|
|
|
|
return
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
while IFS= read -r relative_file; do
|
|
if [[ -z "$relative_file" ]] || is_excluded "$relative_file"; then
|
|
continue
|
|
fi
|
|
|
|
((files_checked += 1))
|
|
|
|
while IFS=: read -r line_number namespace; do
|
|
[[ -z "$line_number" ]] && continue
|
|
|
|
IFS='.' read -r -a segments <<< "$namespace"
|
|
errors=()
|
|
for segment in "${segments[@]}"; do
|
|
if ! reason="$(validate_segment "$segment")"; then
|
|
errors+=(" * $segment: $reason")
|
|
fi
|
|
done
|
|
|
|
if (( ${#errors[@]} > 0 )); then
|
|
namespace_violations+=("- $relative_file:$line_number -> $namespace")
|
|
namespace_violations+=("${errors[@]}")
|
|
fi
|
|
done < <(
|
|
sed '1s/^\xEF\xBB\xBF//' "$relative_file" |
|
|
grep -nE '^[[:space:]]*namespace[[:space:]]+[A-Za-z][A-Za-z0-9_.]*[[:space:]]*([;{]|$)' |
|
|
sed -E 's/^([0-9]+):[[:space:]]*namespace[[:space:]]+([^[:space:];{]+).*/\1:\2/'
|
|
)
|
|
|
|
current_dir="$(dirname "$relative_file")"
|
|
while [[ "$current_dir" != "." ]]; do
|
|
if [[ -z "${seen_directories[$current_dir]:-}" ]]; then
|
|
seen_directories["$current_dir"]=1
|
|
check_directory_path "$current_dir"
|
|
fi
|
|
|
|
current_dir="$(dirname "$current_dir")"
|
|
done
|
|
done < <(git ls-files -- '*.cs')
|
|
|
|
if (( ${#namespace_violations[@]} > 0 || ${#directory_violations[@]} > 0 )); then
|
|
echo "C# naming validation failed."
|
|
|
|
if (( ${#namespace_violations[@]} > 0 )); then
|
|
echo
|
|
echo "Namespace violations:"
|
|
printf '%s\n' "${namespace_violations[@]}"
|
|
fi
|
|
|
|
if (( ${#directory_violations[@]} > 0 )); then
|
|
echo
|
|
echo "Directory violations:"
|
|
printf '%s\n' "${directory_violations[@]}"
|
|
fi
|
|
|
|
exit 1
|
|
fi
|
|
|
|
echo "C# naming validation passed for $files_checked tracked C# files."
|