tsl-devkit/docs/standards/playbook/tests/templates/validate_cpp_templates.sh

354 lines
10 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env sh
# C++ 模板验证脚本
set -eu
echo "========================================"
echo "⚙️ C++ 模板验证"
echo "========================================"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLAYBOOK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
TEMPLATES_DIR="$PLAYBOOK_ROOT/templates/cpp"
VALIDATION_PASSED=0
VALIDATION_FAILED=0
ERRORS_FILE="/tmp/cpp_template_validation_errors.txt"
REPORT_FILE="$SCRIPT_DIR/cpp_validation_report.txt"
> "$ERRORS_FILE"
> "$REPORT_FILE"
echo "📁 模板目录: $TEMPLATES_DIR"
echo ""
# ============================================
# 辅助函数
# ============================================
validate_file_exists() {
local file="$1"
local description="$2"
if [ -f "$file" ]; then
echo "$description: $(basename "$file")"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
return 0
else
echo "$description: $(basename "$file") - 文件不存在"
echo "文件不存在: $file" >> "$ERRORS_FILE"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
return 1
fi
}
validate_cmake_syntax() {
local file="$1"
local description="$2"
# 基础语法检查
if [ ! -s "$file" ]; then
echo "$description: 文件为空"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
return 1
fi
# 检查必要的 CMake 命令
local has_errors=0
if ! grep -q "cmake_minimum_required" "$file"; then
echo " ✗ 缺少 cmake_minimum_required"
has_errors=1
fi
if ! grep -q "project(" "$file"; then
echo " ✗ 缺少 project()"
has_errors=1
fi
if [ $has_errors -eq 0 ]; then
echo "$description: CMake 基础语法正确"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
return 0
else
echo "$description: CMake 语法检查失败"
echo "CMake 语法错误: $file" >> "$ERRORS_FILE"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
return 1
fi
}
# ============================================
# 验证 CMakeLists.txt
# ============================================
echo "🔍 验证 CMakeLists.txt"
CMAKE_FILE="$TEMPLATES_DIR/CMakeLists.txt"
if validate_file_exists "$CMAKE_FILE" "CMakeLists.txt"; then
# 验证 CMake 语法
validate_cmake_syntax "$CMAKE_FILE" "CMakeLists.txt"
echo " 📋 检查 C++23 配置:"
# 检查 C++23 标准
if grep -q "CMAKE_CXX_STANDARD 23" "$CMAKE_FILE"; then
echo " ✓ 配置了 C++23 标准"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ✗ 未配置 C++23 标准"
echo "未配置 C++23: $CMAKE_FILE" >> "$ERRORS_FILE"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
fi
# 检查 Modules 支持
if grep -q "CMAKE_CXX_SCAN_FOR_MODULES" "$CMAKE_FILE"; then
echo " ✓ 启用了 C++ Modules 扫描"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ⚠️ 未启用 C++ Modules 扫描(可选)"
fi
# 检查 import std; 支持
if grep -q "CMAKE_EXPERIMENTAL_CXX_IMPORT_STD" "$CMAKE_FILE"; then
echo " ✓ 启用了 import std; 支持"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ⚠️ 未启用 import std; 支持(可选)"
fi
# 检查编译命令导出
if grep -q "CMAKE_EXPORT_COMPILE_COMMANDS" "$CMAKE_FILE"; then
echo " ✓ 启用了编译命令导出(用于 clangd"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ⚠️ 未启用编译命令导出"
fi
fi
echo ""
# ============================================
# 验证 .clang-format
# ============================================
echo "🔍 验证 .clang-format"
CLANG_FORMAT="$TEMPLATES_DIR/.clang-format"
if validate_file_exists "$CLANG_FORMAT" ".clang-format"; then
# 验证 YAML 语法
if command -v yamllint >/dev/null 2>&1; then
if yamllint -d relaxed "$CLANG_FORMAT" >/dev/null 2>&1; then
echo " ✓ YAML 语法正确"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ✗ YAML 语法错误"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
fi
fi
# 验证关键配置
echo " 📋 检查格式化配置:"
if grep -q "^Language:" "$CLANG_FORMAT" && grep -q "Cpp" "$CLANG_FORMAT"; then
echo " ✓ 配置了 Language: Cpp"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
if grep -q "^BasedOnStyle:" "$CLANG_FORMAT"; then
style=$(grep "^BasedOnStyle:" "$CLANG_FORMAT" | awk '{print $2}')
echo " ✓ 基于风格: $style"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
if grep -q "^Standard:" "$CLANG_FORMAT"; then
std=$(grep "^Standard:" "$CLANG_FORMAT" | awk '{print $2}')
echo " ✓ C++ 标准: $std"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
# 检查缩进配置
if grep -q "^IndentWidth:" "$CLANG_FORMAT"; then
echo " ✓ 配置了缩进宽度"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
fi
echo ""
# ============================================
# 验证 .clangd
# ============================================
echo "🔍 验证 .clangd"
CLANGD="$TEMPLATES_DIR/.clangd"
if validate_file_exists "$CLANGD" ".clangd"; then
# 验证 YAML 语法
if command -v yamllint >/dev/null 2>&1; then
if yamllint -d relaxed "$CLANGD" >/dev/null 2>&1; then
echo " ✓ YAML 语法正确"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ✗ YAML 语法错误"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
fi
fi
# 验证 CompileFlags
echo " 📋 检查 clangd 配置:"
if grep -q "CompileFlags:" "$CLANGD"; then
echo " ✓ 包含 CompileFlags 配置"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
# 检查 C++23 标准
if grep -q "std=c++23" "$CLANGD"; then
echo " ✓ 配置了 -std=c++23"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
fi
# 验证 CompilationDatabase
if grep -q "CompilationDatabase:" "$CLANGD"; then
echo " ✓ 配置了 CompilationDatabase 路径"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
# 验证 Index 配置
if grep -q "Index:" "$CLANGD"; then
echo " ✓ 配置了索引选项"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
fi
echo ""
# ============================================
# 验证 conanfile.txt
# ============================================
echo "🔍 验证 conanfile.txt"
CONANFILE="$TEMPLATES_DIR/conanfile.txt"
if validate_file_exists "$CONANFILE" "conanfile.txt"; then
echo " 📋 检查 Conan 配置:"
# 验证必要的节
if grep -q "^\[requires\]" "$CONANFILE"; then
echo " ✓ 包含 [requires] 配置"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ⚠️ 缺少 [requires] 配置(可选)"
fi
if grep -q "^\[generators\]" "$CONANFILE"; then
echo " ✓ 包含 [generators] 配置"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
# 检查 CMakeDeps 和 CMakeToolchain
if grep -q "CMakeDeps" "$CONANFILE"; then
echo " ✓ 配置了 CMakeDeps 生成器"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
if grep -q "CMakeToolchain" "$CONANFILE"; then
echo " ✓ 配置了 CMakeToolchain 生成器"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
fi
if grep -q "^\[options\]" "$CONANFILE"; then
echo " ✓ 包含 [options] 配置"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
fi
echo ""
# ============================================
# 验证 CMakeUserPresets.json
# ============================================
echo "🔍 验证 CMakeUserPresets.json"
CMAKE_PRESETS="$TEMPLATES_DIR/CMakeUserPresets.json"
if validate_file_exists "$CMAKE_PRESETS" "CMakeUserPresets.json"; then
# 验证 JSON 语法
if command -v python3 >/dev/null 2>&1; then
if python3 -m json.tool "$CMAKE_PRESETS" >/dev/null 2>&1; then
echo " ✓ JSON 语法正确"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
else
echo " ✗ JSON 语法错误"
VALIDATION_FAILED=$((VALIDATION_FAILED + 1))
fi
fi
# 验证配置项
echo " 📋 检查 CMake Presets:"
if grep -q "\"version\"" "$CMAKE_PRESETS"; then
echo " ✓ 包含 version 字段"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
if grep -q "\"configurePresets\"" "$CMAKE_PRESETS"; then
echo " ✓ 包含 configurePresets"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
if grep -q "\"buildPresets\"" "$CMAKE_PRESETS"; then
echo " ✓ 包含 buildPresets"
VALIDATION_PASSED=$((VALIDATION_PASSED + 1))
fi
fi
echo ""
# ============================================
# 生成验证报告
# ============================================
echo "========================================"
echo "📊 验证结果统计"
echo "========================================"
echo "✅ 通过: $VALIDATION_PASSED"
echo "❌ 失败: $VALIDATION_FAILED"
echo "📈 通过率: $(awk "BEGIN {printf \"%.1f\", ($VALIDATION_PASSED * 100.0) / ($VALIDATION_PASSED + $VALIDATION_FAILED)}")%"
echo ""
# 写入报告文件
{
echo "C++ 模板验证报告"
echo "===================="
echo ""
echo "验证时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "模板目录: $TEMPLATES_DIR"
echo ""
echo "统计结果:"
echo " 通过: $VALIDATION_PASSED"
echo " 失败: $VALIDATION_FAILED"
echo " 通过率: $(awk "BEGIN {printf \"%.1f\", ($VALIDATION_PASSED * 100.0) / ($VALIDATION_PASSED + $VALIDATION_FAILED)}")%"
echo ""
if [ -s "$ERRORS_FILE" ]; then
echo "错误详情:"
cat "$ERRORS_FILE"
fi
} > "$REPORT_FILE"
echo "📄 详细报告: $REPORT_FILE"
echo "========================================"
# 清理临时文件
rm -f "$ERRORS_FILE"
# 返回结果
if [ "$VALIDATION_FAILED" -eq 0 ]; then
echo "✅ 所有 C++ 模板验证通过"
exit 0
else
echo "❌ C++ 模板验证失败 ($VALIDATION_FAILED 个错误)"
exit 1
fi