feat(cpp-object-oriented-modular-refactoring): step 1 - cpp-style-tooling
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 2
|
||||||
|
ColumnLimit: 80
|
||||||
+25
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user