feat(cpp-object-oriented-modular-refactoring): step 1 - cpp-style-tooling

This commit is contained in:
KOKO\Mimi
2026-08-16 03:19:17 +09:00
parent 0207aa0847
commit a94bafbdc6
6 changed files with 138 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
BasedOnStyle: Google
IndentWidth: 2
ColumnLimit: 80
+25
View File
@@ -0,0 +1,25 @@
Checks: '-*,bugprone-*,clang-analyzer-*,performance-*,readability-identifier-naming'
HeaderFilterRegex: '^(include|src)/fesa/.*'
FormatStyle: file
ExtraArgs: ['-std=c++17']
CheckOptions:
readability-identifier-naming.ClassCase: CamelCase
readability-identifier-naming.StructCase: CamelCase
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.TypeAliasCase: CamelCase
readability-identifier-naming.FunctionCase: CamelCase
readability-identifier-naming.MethodCase: CamelCase
readability-identifier-naming.VariableCase: lower_case
readability-identifier-naming.ParameterCase: lower_case
readability-identifier-naming.LocalVariableCase: lower_case
readability-identifier-naming.PrivateMemberCase: lower_case
readability-identifier-naming.PrivateMemberSuffix: _
readability-identifier-naming.ProtectedMemberCase: lower_case
readability-identifier-naming.ProtectedMemberSuffix: _
readability-identifier-naming.PublicMemberCase: lower_case
readability-identifier-naming.ConstantCase: CamelCase
readability-identifier-naming.ConstantPrefix: k
readability-identifier-naming.EnumConstantCase: CamelCase
readability-identifier-naming.EnumConstantPrefix: k
readability-identifier-naming.NamespaceCase: lower_case
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
+1
View File
@@ -23,6 +23,7 @@ __pycache__/
# local Harness configuration and build outputs # local Harness configuration and build outputs
.harness/config.json .harness/config.json
.harness/build/ .harness/build/
.harness/doxygen/
# phase execution outputs # phase execution outputs
phases/**/phase*-output.json phases/**/phase*-output.json
+10
View File
@@ -8,6 +8,16 @@ set(CMAKE_CXX_EXTENSIONS OFF)
include(cmake/FesaDependencies.cmake) include(cmake/FesaDependencies.cmake)
find_package(Doxygen QUIET)
if(Doxygen_FOUND)
add_custom_target(fesa_docs
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating FESA API documentation"
VERBATIM
)
endif()
enable_testing() enable_testing()
add_subdirectory(src/fesa) add_subdirectory(src/fesa)
+16
View File
@@ -0,0 +1,16 @@
PROJECT_NAME = FESA
PROJECT_NUMBER = 0.1.0
OUTPUT_DIRECTORY = .harness/doxygen
INPUT = include src
EXCLUDE = tests
RECURSIVE = YES
FILE_PATTERNS = *.h *.cpp
EXTRACT_ALL = NO
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_AS_ERROR = YES
GENERATE_HTML = YES
HTML_OUTPUT = html
GENERATE_LATEX = NO
+83
View File
@@ -0,0 +1,83 @@
from pathlib import Path
import re
ROOT = Path(__file__).resolve().parents[1]
def read(path: Path) -> str:
return path.read_text(encoding="utf-8")
def doxygen_assignments(text: str) -> dict[str, str]:
assignments = {}
for line in text.splitlines():
match = re.fullmatch(r"\s*([A-Z][A-Z0-9_]*)\s*=\s*(.*?)\s*", line)
if match is not None:
assignments[match.group(1)] = match.group(2)
return assignments
def test_p_style_001_cpp_style_and_doxygen_tooling_contract():
required_paths = (
ROOT / ".clang-format",
ROOT / ".clang-tidy",
ROOT / "Doxyfile",
)
missing_paths = [path.name for path in required_paths if not path.is_file()]
assert not missing_paths, f"missing C++ policy files: {missing_paths}"
clang_format = read(ROOT / ".clang-format")
for setting in (
"BasedOnStyle: Google",
"IndentWidth: 2",
"ColumnLimit: 80",
):
assert setting in clang_format
clang_tidy = read(ROOT / ".clang-tidy")
for setting in (
"-std=c++17",
"readability-identifier-naming",
"readability-identifier-naming.ClassCase: CamelCase",
"readability-identifier-naming.StructCase: CamelCase",
"readability-identifier-naming.EnumCase: CamelCase",
"readability-identifier-naming.TypeAliasCase: CamelCase",
"readability-identifier-naming.FunctionCase: CamelCase",
"readability-identifier-naming.MethodCase: CamelCase",
"readability-identifier-naming.VariableCase: lower_case",
"readability-identifier-naming.ParameterCase: lower_case",
"readability-identifier-naming.LocalVariableCase: lower_case",
"readability-identifier-naming.PrivateMemberCase: lower_case",
"readability-identifier-naming.PrivateMemberSuffix: _",
"readability-identifier-naming.ProtectedMemberCase: lower_case",
"readability-identifier-naming.ProtectedMemberSuffix: _",
"readability-identifier-naming.PublicMemberCase: lower_case",
"readability-identifier-naming.ConstantCase: CamelCase",
"readability-identifier-naming.ConstantPrefix: k",
"readability-identifier-naming.EnumConstantCase: CamelCase",
"readability-identifier-naming.EnumConstantPrefix: k",
"readability-identifier-naming.NamespaceCase: lower_case",
"readability-identifier-naming.MacroDefinitionCase: UPPER_CASE",
):
assert setting in clang_tidy
doxyfile = doxygen_assignments(read(ROOT / "Doxyfile"))
assert doxyfile["INPUT"].split() == ["include", "src"]
assert doxyfile["EXCLUDE"].split() == ["tests"]
assert doxyfile["WARN_AS_ERROR"] == "YES"
assert doxyfile["OUTPUT_DIRECTORY"] == ".harness/doxygen"
assert doxyfile["HTML_OUTPUT"] == "html"
gitignore_lines = read(ROOT / ".gitignore").splitlines()
assert ".harness/doxygen/" in gitignore_lines
cmake = read(ROOT / "CMakeLists.txt")
assert "find_package(Doxygen QUIET)" in cmake
doxygen_block = re.search(
r"if\(Doxygen_FOUND\)(?P<body>.*?)endif\(\)", cmake, re.DOTALL
)
assert doxygen_block is not None
assert "add_custom_target(fesa_docs" in doxygen_block.group("body")
assert "Doxyfile" in doxygen_block.group("body")
assert re.search(r"add_custom_target\(fesa_docs\s+ALL\b", cmake) is None