diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..52ee916 --- /dev/null +++ b/.clang-format @@ -0,0 +1,60 @@ +--- +BasedOnStyle: LLVM +ColumnLimit: 80 +AlignArrayOfStructures: Left +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: true + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseArrows: false + AlignCaseColons: false +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseExpressionOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AllowShortNamespacesOnASingleLine: false +BreakBinaryOperations: RespectPrecedence +BreakTemplateDeclarations: Yes +IndentWidth: 4 +RemoveEmptyLinesInUnwrappedLines: true +SpaceInEmptyBlock: true +SpacesBeforeTrailingComments: 2 +TabWidth: 4 +... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..8ab63b3 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,54 @@ +--- +Checks: >- + clang-diagnostic-*, + clang-analyzer-*, + bugprone-*, + cppcoreguidelines-*, + misc-*, + modernize-*, + performance-*, + readability-*, + portability-*, + + -bugprone-easily-swappable-parameters, + -modernize-use-nodiscard, + -readability-braces-around-statements, + + +WarningsAsErrors: >- + clang-analyzer-core.*, + clang-analyzer-cplusplus.*, + clang-analyzer-security.*, + clang-analyzer-unix.*, + performance-move-const-arg, + performance-unnecessary-value-param, + readability-duplicate-include, + +HeaderFileExtensions: + - '' + - h + - hh + - hpp + - hxx +ImplementationFileExtensions: + - c + - cc + - cpp + - cxx +HeaderFilterRegex: '.*\.(c|cxx|cpp)$' +ExcludeHeaderFilterRegex: '' +FormatStyle: none +User: Nyx4 +CheckOptions: + readability-identifier-naming.ConstantCase: UPPER_CASE + readability-identifier-naming.ClassConstantCase: UPPER_CASE + readability-identifier-naming.ClassCase: CamelCase + readability-identifier-naming.ClassMethodCase: lower_case + readability-identifier-naming.ClassMemberCase: lower_case + readability-identifier-naming.FunctionCase: lower_case + readability-identifier-naming.VariableCase: lower_case + readability-function-size.StatementThreshold: 42 + readability-function-size.NestingThreshold: 5 +SystemHeaders: false +UseColor: true +... diff --git a/.github/workflows/on-push.yaml b/.github/workflows/on-push.yaml new file mode 100644 index 0000000..c973d1c --- /dev/null +++ b/.github/workflows/on-push.yaml @@ -0,0 +1 @@ +# TODO: Add some checks to run on-push. \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7bd455d --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Linker files +*.ilk + +# Debugger Files +*.pdb + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# debug information files +*.dwo + +# CMake tempoorary files and folders +build/ +.cache/ +Testing/ +CMakeFiles/ +Makefile +compile_commands.json +cmake_install.cmake +CMakeCache.txt + +# Documentation artifacts +sphinx_docs/_build/ +sphinx_docs/_doxygen/ +__pycache__/ +*.pyc diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..aac737b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,90 @@ +fail_fast: false +repos: + - repo: local + hooks: + - id: enable-testing + name: Enable testing configuration + entry: cmake + language: system + args: [-B build, -DBUILD_TESTING=ON] + pass_filenames: false + always_run: true + + - id: build + name: Build the project using cmake + entry: cmake + language: system + args: [--build, build] + pass_filenames: false + always_run: true + + - id: test + name: Test the project using ctest + entry: ctest + language: system + args: [--test-dir build, --output-on-failure] + pass_filenames: false + always_run: true + + - repo: https://github.com/pocc/pre-commit-hooks + rev: v1.3.5 + hooks: + - id: clang-format + args: ["-i"] + - id: clang-tidy + args: ["-p=build"] + - id: cppcheck + args: ["--enable=all", "-Iinclude/", "--quiet", "src", "--suppress=normalCheckLevelMaxBranches", "--suppress=checkersReport", "--suppress=missingIncludeSystem", "--suppress=useStlAlgorithm", "--suppress=unusedFunction", "--suppress=unusedStructMember", "--suppress=unmatchedSuppression", "--inline-suppr"] + + - repo: https://github.com/crate-ci/typos + rev: v1.40.0 + hooks: + - id: typos + + - repo: https://github.com/commitizen-tools/commitizen + rev: v4.10.0 + hooks: + - id: commitizen + - id: commitizen-branch + stages: [pre-push] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-added-large-files + name: "📁 filesystem/🤏 size · Prevent giant files from being committed" + args: [ '--maxkb=2000' ] + - id: check-executables-have-shebangs + name: "📁 filesystem/⚙️ exec · Verify shebang presence" + - id: check-shebang-scripts-are-executable + name: "📁 filesystem/⚙️ exec · Verify script permissions" + - id: check-case-conflict + name: "📁 filesystem/📝 names · Check case sensitivity" + - id: check-illegal-windows-names + name: "📁 filesystem/📝 names · Validate Windows filenames" + - id: check-symlinks + name: "📁 filesystem/🔗 symlink · Check symlink validity" + - id: destroyed-symlinks + name: "📁 filesystem/🔗 symlink · Detect broken symlinks" + - id: check-json + name: "📁 filesystem/📃 data format · Load all json to verify syntax" + - id: check-toml + name: "📁 filesystem/📃 data format · Load all toml to verify syntax" + - id: check-xml + name: "📁 filesystem/📃 data format · Load all xml to verify syntax" + - id: check-yaml + name: "📁 filesystem/📃 data format · Load all yaml to verify syntax" + - id: forbid-submodules + name: "📁 filesystem/📦 submodules · Detect broken symlinks" + - id: mixed-line-ending + name: "🪟 windows/💔 use UNIX · Use LF as line ending on Windows 🥺" + args: [ '--fix=lf' ] + - id: check-ast + name: "🐍 python/🏴 syntax · Check files parse as valid python" + - id: check-docstring-first + name: "🐍 python/🏴 syntax · Check code is after the docstring" + - id: detect-private-key + name: "🐍 python/🔐 secrets · Checks for the existence of private keys" + - id: name-tests-test + name: "🐍 python/📝 names · Check test files are named correctly" + args: [ '--pytest-test-first' ] diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..12bbfc9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +## 0.1.0 (2026-01-02) + +### Added + +- A SFML Based GUI +- Interactive Maze Editor +- File Explorer Save/Load +- Eller's and Recursive Backtracking algorithm for Maze Generation +- Step Generation Option. +- BFS, DFS, Wall Follower, Flood Fill and A* solving algorithms. +- Step Solve and Instant Solve options. +- Option to change Animation Speed. +- Option to change Maze Size. +- MVC Style Architecture \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a67b639 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,122 @@ +# Specifies the minimum version of CMake required to process this file. +# Using a range (3.50..4.0) ensures compatibility with modern features. +cmake_minimum_required(VERSION 3.50..4.2) + +# Defines the project name and enables the C++ compiler. +project(MicroMouse-Simulator LANGUAGES CXX) + +# Sets the C++ standard for the entire project to C++17. +# This ensures consistency across all source files and compilers. +set(CMAKE_CXX_STANDARD 17) + +set(CXX_EXPORT_BUILD_COMMANDS ON) + +# --- SFML Integration using FetchContent (Source Code) --- +include(FetchContent) +FetchContent_Declare( + sfml + GIT_REPOSITORY https://github.com/SFML/SFML.git + GIT_TAG 2.6.1 +) + +# Configure SFML options to build only what we need, statically +set(SFML_BUILD_WINDOW ON CACHE BOOL "" FORCE) +set(SFML_BUILD_GRAPHICS ON CACHE BOOL "" FORCE) +set(SFML_BUILD_SYSTEM ON CACHE BOOL "" FORCE) +set(SFML_BUILD_AUDIO OFF CACHE BOOL "" FORCE) +set(SFML_BUILD_NETWORK OFF CACHE BOOL "" FORCE) +set(SFML_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +set(SFML_BUILD_DOC OFF CACHE BOOL "" FORCE) +set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) # Force static linking + +FetchContent_MakeAvailable(sfml) + +# Note: FetchContent_MakeAvailable(sfml) provides the targets SFML::Graphics, SFML::Window, etc. +# directly, so find_package is not needed. The targets will handle include directories automatically. + +# --- GoogleTest Integration (Conditional) --- + +# This block executes only if the user configures CMake with -DBUILD_TESTING=ON. +if(BUILD_TESTING) + include(FetchContent) + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + # Use a specific stable commit or tag (like release-1.14.0) for reliability. + GIT_TAG 52eb8108c5bdec04579160ae17225d66034bd723 + # Recommended: Add DOWNLOAD_EXTRACT_TIMESTAMP TRUE for build robustness (CMP0135). + ) + + # Makes the googletest targets (GTest::gtest, GTest::gtest_main, etc.) available + # for linking in subsequent targets (like mms-test). + FetchContent_MakeAvailable(googletest) + + # Include the CTest module for test registration and management. + include(CTest) + + # Add the 'tests' subdirectory, which contains its own CMakeLists.txt file. + add_subdirectory(tests) +endif() + +# --- Core Logic Library Definition --- + +# Define the source files that contain the reusable application logic. +set(CORE_SOURCES + src/model/generators/RecursiveBacktracker.cpp + src/model/generators/EllersGenerator.cpp + src/model/MazeUtils.cpp + src/view/UI.cpp + src/view/UIComponents.cpp + src/controller/Simulator.cpp + src/model/solvers/BFSSolver.cpp + src/model/solvers/DFSSolver.cpp + src/model/solvers/AStarSolver.cpp + src/model/solvers/FloodFillSolver.cpp + src/model/solvers/WallFollowerSolver.cpp +) + +# Create a Static Library target. This bundles the core logic into a reusable +# library that can be linked by both the main executable and the test executable. +add_library(mms-core STATIC ${CORE_SOURCES}) + +# Configure Include Directories for mms-core +# Set the project's header directory as PUBLIC for the 'mms-core' library. +target_include_directories(mms-core + PUBLIC + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/include/model + ${CMAKE_SOURCE_DIR}/include/view + ${CMAKE_SOURCE_DIR}/include/controller +) +target_link_libraries(mms-core PUBLIC sfml-graphics sfml-window sfml-system) +if(WIN32) + target_link_libraries(mms-core PUBLIC comdlg32) +endif() +target_compile_definitions(mms-core PUBLIC SFML_STATIC) +# The PUBLIC keyword ensures that any target that links to 'mms-core' (like 'mms' +# and 'mms-test') automatically inherits this include path. + +# --- Main Executable Definition --- + +# Define the source file(s) for the application entry point. +set(APP_SOURCES src/Main.cpp) + +# Create the main executable target +add_executable(mms ${APP_SOURCES}) + +# Link the core logic library and SFML to the main executable. +# PRIVATE linkage means the executable uses the library internally, +# but downstream targets don't need to know about it (standard best practice). +# Link the core logic library and SFML to the main executable. +# PRIVATE linkage means the executable uses the library internally, +# but downstream targets don't need to know about it (standard best practice). +target_link_libraries(mms PRIVATE mms-core sfml-graphics sfml-window sfml-system) + +# Define SFML_STATIC to ensure headers use static linkage conventions +target_compile_definitions(mms PRIVATE SFML_STATIC) + +# --- Assets Management --- +# Copy the assets directory to the build directory so the executable can find them +file(COPY "${CMAKE_SOURCE_DIR}/assets" DESTINATION "${CMAKE_BINARY_DIR}") + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d8329fa --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,727 @@ +# Contributing to MicroMouse Simulator + +Thank you for your interest in contributing to the MicroMouse Simulator project! This guide will help you get started with contributing code, reporting issues, and following our development practices. + +--- + +## Table of Contents + +- [Getting Started](#getting-started) +- [Development Workflow](#development-workflow) +- [Coding Standards](#coding-standards) +- [Development Tools Setup](#development-tools-setup) +- [Build System](#build-system) +- [Pre-commit Hooks](#pre-commit-hooks) +- [Testing Guidelines](#testing-guidelines) +- [Submitting Changes](#submitting-changes) +- [Reporting Issues](#reporting-issues) +- [Review Process](#review-process) + +--- + +## Getting Started + +### Prerequisites + +Before contributing, ensure you have: + +- **Git** installed and configured +- **CMake** (version 3.50 to 4.2) +- **C++ Compiler** (GCC, Clang, MSVC, or MinGW) which supports C++11 and above +- **Clang-Format** (preferably from the LLVM toolchain) +- **Clang-Tidy** (for static analysis) +- **Python 3** (for pre-commit hooks) +- **VSCode** (recommended IDE) + +### Setting Up Your Development Environment + +1. **Fork the Repository** + + Click the "Fork" button on GitHub and **disable** the "Copy the main branch only" option to ensure you get the `dev` branch. + +2. **Clone Your Fork** +```bash + git clone https://github.com/YOUR_USERNAME/MicroMouse-Simulator + cd MicroMouse-Simulator +``` + +3. **Add Upstream Remote** +```bash + git remote add upstream https://github.com/kr8457/MicroMouse-Simulator +``` + +4. **Switch to Development Branch** +```bash + git checkout dev +``` + +5. **Set Up Pre-commit Hooks** +```bash + # Install pre-commit (if not already installed) + pip install pre-commit + + # Install the git hooks + pre-commit install + + # Optionally install the pre-push hook for commitizen + pre-commit install --hook-type pre-push +``` + +6. **Install Commitizen** +```bash + # Install commitizen (required for creating properly formatted commits) + pip install commitizen + + # Verify installation + cz version +``` + +7. **Keep Your Fork Synchronized** +```bash + git fetch upstream + git merge upstream/dev +``` + +--- + +## Development Workflow + +### Branching Model + +We follow a **feature branch workflow** with two main branches: + +- **`main`**: Production-ready code (protected, no direct pushes) +- **`dev`**: Active development branch (all features merge here first) + +### Creating a Feature Branch + +1. **Ensure you're on the latest `dev` branch:** +```bash + git checkout dev + git pull upstream/dev +``` + +2. **Create a descriptive feature branch:** +```bash + # Use descriptive names that explain what you're working on + git checkout -b feature/add-dijkstra-algorithm + git checkout -b fix/maze-generation-bug + git checkout -b docs/update-readme +``` + + **Branch naming conventions:** + - `feature/` - New features or enhancements + - `fix/` - Bug fixes + - `docs/` - Documentation updates + - `refactor/` - Code refactoring + - `test/` - Test additions or modifications + +For additional types, visit [Conventional Branch](https://conventional-branch.github.io/). + +3. **Make your changes and commit regularly:** +```bash + # Stage your changes + git add . + + # Commit using commitizen (recommended) + # Make sure commitizen is installed: pip install commitizen + cz commit +``` + +> [!NOTE] +> If you haven't installed commitizen yet, see the [Commitizen Installation](#commitizen-configuration) section. + +4. **Push your branch to your fork:** +```bash + git push -u origin feature/add-dijkstra-algorithm +``` + +5. **Create a Pull Request:** + - Go to GitHub and open a PR from your branch to the `dev` branch + - Fill out the PR with details about your changes + - [Link](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) any relevant issues. + +### Syncing Your Fork + +Always keep your fork up to date: +```bash +# Fetch upstream changes +git fetch upstream + +# Update your local dev branch +git checkout dev +git merge upstream/dev + +# Push updated dev branch to your fork +git push origin dev + +# Update your feature branch with latest dev changes +git checkout your-feature-branch +git rebase dev +``` + +> [!IMPORTANT] +> Always run `git fetch upstream` regularly to keep your local repository synchronized with the remote. + +--- + +## Coding Standards + +### Naming Conventions + +#### 1. File Names +Use **PascalCase** for all source files: +``` +Correct: +- MazeGen.cpp / MazeGen.hpp +- PathFinder.cpp / PathFinder.hpp +- RobotController.cpp / RobotController.hpp + +Incorrect: +- maze_gen.cpp +- pathfinder.cpp +- robot-controller.cpp +``` + +**File Extensions:** +- `.cpp` - C++ source files +- `.hpp` - C++ header files + +#### 2. Variable Names +Use **snake_case** for variables. Names should be descriptive and self-explanatory: +```cpp +Correct: +int cell_count; +double path_length; +bool is_visited; +std::vector current_path; + +Incorrect: +int cc; +double pl; +bool v; +std::vector cp; +``` + +#### 3. Class Names +Use **PascalCase** for class names: +```cpp +Correct: +class MazeGenerator; +class PathFinder; +class RobotController; + +Incorrect: +class maze_generator; +class pathfinder; +class robot_controller; +``` + +#### 4. Function Names +Use **snake_case** for function names: +```cpp +Correct: +void generate_maze(); +int calculate_distance(); +bool is_wall_present(); + +Incorrect: +void generateMaze(); +int calculateDistance(); +bool isWallPresent(); +``` + +#### 5. Constants and Macros +Use **UPPER_SNAKE_CASE** for all constants, including global constants, class constants, and local `static constexpr` values: +```cpp +Correct: +const int MAX_MAZE_SIZE = 16; +static constexpr float K_SIDEBAR_WIDTH = 280.0F; + +Incorrect: +const int maxMazeSize = 16; +``` + +#### 6. Global Variables and State +Avoid non-const global variables. If global state is necessary, encapsulate it in a `struct` within an anonymous namespace to maintain modularity and satisfy static analysis (`cppcoreguidelines-avoid-non-const-global-variables`): + +```cpp +namespace { + struct SimulationState { + int maze_rows = 16; + bool is_solving = false; + }; + SimulationState G_STATE; +} +``` + +--- + +## Development Tools Setup + +### Clang-Format Configuration + +Clang-Format ensures consistent code formatting across the project. The project uses a custom `.clang-format` configuration file based on LLVM style with modifications. + +#### Installation + +Install the LLVM toolchain to get Clang-Format: + +**Windows:** +```bash +# Download from https://releases.llvm.org/ +# Or use Chocolatey +choco install llvm +``` + +**Linux (Ubuntu/Debian):** +```bash +sudo apt-get install clang-format +``` + +**macOS:** +```bash +brew install clang-format +``` + +#### VSCode Integration + +The project uses **clangd** for language server functionality, which includes formatting via clang-format. + +1. **Install the clangd extension** in VSCode (not the C/C++ extension) +2. **Disable the C/C++ extension** if it's installed to avoid conflicts +3. **Configure clangd** by adding to your VSCode `settings.json`: +```json +{ + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}/build", + "--clang-tidy", + "--format-style=file" + ], + "clangd.path": "clangd", + "[cpp]": { + "editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd", + "editor.formatOnSave": true + }, +} +``` + +4. **Generate compilation database** (required for clangd): +```bash +# Configure the build (compilation database is automatically generated) +cmake -B build +``` + +> [!NOTE] +> The `CXX_EXPORT_BUILD_COMMANDS` option is already enabled by default in the project's `CMakeLists.txt`, so the compilation database (`compile_commands.json`) will be automatically generated in the `build/` directory when you configure CMake. No additional flags are needed. + +#### Manual Formatting + +Format a single file: +```bash +clang-format -i src/MazeGen.cpp +``` + +Format all files: +```bash +# Works on git bash if you are on Windows +find src include -name "*.cpp" -o -name "*.hpp" | xargs clang-format -i +``` + +### Clang-Tidy Configuration + +Clang-Tidy provides static analysis and linting for C++ code. The project uses a comprehensive `.clang-tidy` configuration file. + +#### VSCode Integration + +Clang-Tidy is integrated with clangd. See the [Clang-Format VSCode Integration](#vscode-integration) section above for setup instructions. The clangd extension will automatically use clang-tidy when configured with the `--clang-tidy` argument. + +> [!IMPORTANT] +> Do not install the C/C++ extension by Microsoft when using clangd, as they conflict with each other. Only use the clangd extension. + +#### Running Clang-Tidy Manually +```bash +clang-tidy src/filename.cpp -p build/ +``` + +--- + +## Build System + +### CMake Configuration + +The project uses CMake for building. The main `CMakeLists.txt` file defines: + +- **Minimum CMake Version**: 3.50 (supports up to 4.2) +- **C++ Standard**: C++11 or above +- **Compilation Database**: Automatically exported to `build/compile_commands.json` (required for clangd) +- **Project Structure**: + - `mms-core`: Static library containing core logic (`src/MazeGen.cpp`) + - `mms`: Main executable (`src/Main.cpp`) + - `mms-test`: Test executable (only built when `BUILD_TESTING=ON`) + +### Building the Project + +#### Basic Build +```bash +# Configure the build +cmake -B build + +# Build the project +cmake --build build +``` + +#### Building with Tests +```bash +# Configure with testing enabled +cmake -B build -DBUILD_TESTING=ON + +# Build the project +cmake --build build + +# Run tests +ctest --test-dir build --output-on-failure +``` + +### Project Structure + +``` +MicroMouse-Simulator/ +├── CMakeLists.txt # Main build configuration +├── include/ # Header files (.hpp) +├── src/ # Source files (.cpp) +├── tests/ # Test files +``` + +--- + +## Pre-commit Hooks + +The project uses pre-commit hooks to automatically check code quality before commits. Configuration is in `.pre-commit-config.yaml`. + +### Setup + +After cloning the repository: +```bash +# Install pre-commit (if not already installed) +pip install pre-commit + +# Install the git hooks +pre-commit install + +# Install pre-push hook for commitizen +pre-commit install --hook-type pre-push +``` + +### Hooks Overview + +The pre-commit configuration includes: + +#### Local Hooks (Always Run) +- **enable-testing**: Configures CMake with `BUILD_TESTING=ON` +- **build**: Builds the project using CMake +- **test**: Runs tests using CTest + +#### Code Quality Hooks +- **clang-format**: Formats C++ code automatically +- **clang-tidy**: Runs static analysis on C++ code +- **cppcheck**: Performs additional static analysis on source files + +#### Documentation Hooks +- **markdownlint**: Lints markdown files using `.mdl.rb` configuration +- **typos**: Checks for common typos in code and documentation + +#### Commit Hooks +- **commitizen**: Validates commit messages follow Conventional Commits format +- **commitizen-branch**: Validates branch names (runs on pre-push) + +#### File System Hooks +- **check-added-large-files**: Prevents files larger than 200KB +- **check-executables-have-shebangs**: Verifies executable files have shebangs +- **check-case-conflict**: Detects case sensitivity issues +- **check-illegal-windows-names**: Validates Windows filename compatibility +- **check-symlinks**: Validates symlinks +- **check-json/toml/xml/yaml**: Validates configuration file syntax +- **mixed-line-ending**: Enforces LF line endings (fixes Windows CRLF) + +#### Python Hooks (if applicable) +- **check-ast**: Validates Python syntax +- **check-docstring-first**: Ensures docstrings come first +- **detect-private-key**: Prevents committing private keys +- **name-tests-test**: Validates test file naming + +### Running Hooks Manually + +Test all hooks: +```bash +pre-commit run --all-files +``` + +Test a specific hook: +```bash +pre-commit run clang-format --all-files +``` + +### Bypassing Hooks (Not Recommended) + +If you need to bypass hooks (e.g., for WIP commits): +```bash +git commit --no-verify -m "WIP: temporary commit" +``` + +> [!WARNING] +> Only bypass hooks for temporary commits. All final commits should pass all hooks. + +--- + +## Commitizen Configuration + +The project uses Commitizen (configured in `cz.yaml`) to enforce consistent commit message formatting. + +### Installation + +Before using Commitizen, you need to install it: + +```bash +# Install commitizen using pip +pip install commitizen + +# Verify installation +cz version +``` + +**Alternative installation methods:** + +**Windows (using Chocolatey):** +```bash +choco install commitizen +``` + +**macOS (using Homebrew):** +```bash +brew install commitizen +``` + +### Using Commitizen + +Instead of `git commit`, use: +```bash +# Interactive commit message creation (recommended) +cz commit +``` + +This will guide you through creating a properly formatted commit message following the Conventional Commits specification. + +### Commit Message Format + +When using `git commit` directly (not recommended, but validated by pre-commit), follow the **Conventional Commits** format: +``` +(): + + + +