{"id":20852405,"url":"https://github.com/ryouze/header-warden","last_synced_at":"2025-12-28T05:06:28.684Z","repository":{"id":257742605,"uuid":"859048197","full_name":"ryouze/header-warden","owner":"ryouze","description":"Cross-platform multithreaded CLI tool that identifies and reports missing standard library headers in C++ code.","archived":false,"fork":false,"pushed_at":"2025-01-23T03:47:17.000Z","size":87,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-23T04:24:55.769Z","etag":null,"topics":["cmake","code-analysis","comand-line-tool","cpp","cross-platform","regex"],"latest_commit_sha":null,"homepage":"https://ryouze.net/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryouze.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-18T01:47:40.000Z","updated_at":"2025-01-23T03:47:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"6b7ce6fe-8e64-4316-8eb1-a49be8cf42e7","html_url":"https://github.com/ryouze/header-warden","commit_stats":null,"previous_names":["ryouze/header-warden"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryouze%2Fheader-warden","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryouze%2Fheader-warden/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryouze%2Fheader-warden/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryouze%2Fheader-warden/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryouze","download_url":"https://codeload.github.com/ryouze/header-warden/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243222205,"owners_count":20256227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","code-analysis","comand-line-tool","cpp","cross-platform","regex"],"created_at":"2024-11-18T03:17:33.403Z","updated_at":"2025-12-28T05:06:23.629Z","avatar_url":"https://github.com/ryouze.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# header-warden\n\n[![CI](https://github.com/ryouze/header-warden/actions/workflows/ci.yml/badge.svg)](https://github.com/ryouze/header-warden/actions/workflows/ci.yml)\n[![Release](https://github.com/ryouze/header-warden/actions/workflows/release.yml/badge.svg)](https://github.com/ryouze/header-warden/actions/workflows/release.yml)\n![Release version](https://img.shields.io/github/v/release/ryouze/header-warden)\n\nheader-warden is a cross-platform multithreaded CLI tool that identifies and reports missing standard library headers in C++ code.\n\n\n## Motivation\n\nIn many modern programming languages, such as Python, the use of a standard library module is explicitly declared, making it clear which module is being utilized.\n\n```python\nimport typing\n\ndef foo(bar: typing.List[int]) -\u003e None:\n    pass\n```\n\n\u003e [!NOTE]\n\u003e In [Python \u003e=3.9](https://docs.python.org/3/whatsnew/3.9.html#type-hinting-generics-in-standard-collections), `list[]` can be used directly without using `typing.List`. This is merely for illustration purposes.\n\n\nHowever, in C++, it is possible to use a standard library function without including the corresponding header.\n\n```c++\n// #include \u003cvector\u003e\n#include \u003ciostream\u003e\n\nvoid foo(std::vector\u003cint\u003e bar)  // No error or warning is generated\n{\n}\n```\n\nThis is because they all share the `std` namespace, and headers (e.g., `#include \u003ciostream\u003e`) can include other headers (e.g., `#include \u003cvector\u003e`) internally. This, however, varies between compilers and platforms, which can lead to portability issues (i.e., code that compiles on one platform but not on another).\n\nAs a C++ programmer, you're supposed to memorize *which* standard library functions are included in *which* headers. If you're a perfectionist like me, this quickly becomes very tedious and error-prone.\n\nheader-warden addresses this by encouraging the explicit listing of all standard library functions as comments in the `#include` directive. As a bonus, this also makes it easier for beginners to memorize the required headers for each function.\n\n```c++\n#include \u003calgorithm\u003e  // for std::find\n#include \u003cstring\u003e     // for std::string, std::to_string\n#include \u003cvector\u003e     // for std::vector\n```\n\nAfter running header-warden, you will receive a report that lists all standard library functions used in your code, along with the corresponding `#include` directives. This will help you ensure that all standard library functions are correctly listed as comments after the `#include` directive. Links to [cppreference.com](https://en.cppreference.com/) are also provided for missing functions, making it easy to find the correct header.\n\n```\n-- 1) BARE INCLUDES --\n\n8| #include \u003ciostream\u003e\n-\u003e Bare include directive.\n-\u003e Add a comment to '#include \u003ciostream\u003e', e.g., '#include \u003ciostream\u003e // for std::foo, std::bar'.\n\n-- 2) UNUSED FUNCTIONS --\n\n11| #include \u003calgorithm\u003e  // for std::find\n-\u003e Unused functions listed as comments.\n-\u003e Remove 'std::find' comments from '#include \u003calgorithm\u003e  // for std::find'.\n\n-- 3) UNLISTED FUNCTIONS --\n\n31|     std::sort(result.begin(), result.end());\n-\u003e Unlisted function.\n-\u003e Add 'std::sort' as a comment, e.g., '#include \u003cfoo\u003e // for std::sort'.\n-\u003e Reference: https://duckduckgo.com/?sites=cppreference.com\u0026q=std%3A%3Asort\u0026ia=web\n```\n\nWhat you do with this information is completely up to you. You can choose to add the missing functions to the comments, or you can ignore them. The goal is to make you aware of potential issues in your code.\n\n\n## Features\n\n- Written in modern C++ (C++17).\n- Comprehensive documentation with doxygen-style comments.\n- Automatic third-party dependency management using CMake's [FetchContent](https://www.foonathan.net/2022/06/cmake-fetchcontent/).\n- Multithreaded file processing via [BS::thread_pool](https://github.com/bshoshany/thread-pool).\n- No missing STL headers thanks to this tool (run on itself).\n\n\n### To-Do\n\n- [x] Add multi-threading.\n  - [ ] Double-check the [BS::thread_pool](https://github.com/bshoshany/thread-pool)'s documentation to ensure your usage is correct.\n\n\n## Tested Systems\n\nThis project has been tested on the following systems:\n\n- macOS 14.6 (Sonoma)\n- Manjaro 24.0 (Wynsdey)\n- Windows 11 23H2\n\nAutomated testing is also performed on the latest versions of macOS, GNU/Linux, and Windows using GitHub Actions.\n\n\n## Pre-built Binaries\n\nPre-built binaries are available for macOS (ARM64), GNU/Linux (x86_64), and Windows (x86_64). You can download the latest version from the [Releases](../../releases) page.\n\nTo remove macOS quarantine, use the following commands:\n\n```sh\nxattr -d com.apple.quarantine header-warden-macos-arm64\nchmod +x header-warden-macos-arm64\n```\n\nOn Windows, the OS might complain about the binary being unsigned. You can bypass this by clicking on \"More info\" and then \"Run anyway\".\n\n\n## Requirements\n\nTo build and run this project, you'll need:\n\n- C++17 or higher\n- CMake\n\n\n## Build\n\nFollow these steps to build the project:\n\n1. **Clone the repository**:\n\n    ```sh\n    git clone https://github.com/ryouze/header-warden.git\n    ```\n\n2. **Generate the build system**:\n\n    ```sh\n    cd header-warden\n    mkdir build \u0026\u0026 cd build\n    cmake ..\n    ```\n\n    Optionally, you can disable compile warnings by setting `ENABLE_COMPILE_FLAGS` to `OFF`:\n\n    ```sh\n    cmake .. -DENABLE_COMPILE_FLAGS=OFF\n    ```\n\n3. **Compile the project**:\n\n    To compile the project, use the following command:\n\n    ```sh\n    cmake --build . --parallel\n    ```\n\nAfter successful compilation, you can run the program using `./header-warden`. However, it is highly recommended to install the program, so that it can be run from any directory. Refer to the [Install](#install) section below.\n\n\u003e [!TIP]\n\u003e The mode is set to `Release` by default. To build in `Debug` mode, use `cmake .. -DCMAKE_BUILD_TYPE=Debug`.\n\n\n## Install\n\nIf not already built, follow the steps in the [Build](#build) section and ensure that you are in the `build` directory.\n\nTo install the program, use the following command:\n\n```sh\nsudo cmake --install .\n```\n\nOn macOS, this will install the program to `/usr/local/bin`. You can then run the program from any directory using `header-warden`.\n\n\n## Usage\n\nTo run the program, use the following command:\n\n```sh\nheader-warden\n```\n\nThe program expects at least one argument, which can be a file or directory.\n\n```sh\nheader-warden src/main.cpp\n```\n\n```sh\nheader-warden src\n```\n\nIf a directory is passed, the program will recursively search for files with the following extensions: `.cpp`, `.hpp`, `.h`, `.cxx`, `.cc`, `.hh`, `.hxx`, `.tpp`.\n\nYou can also pass multiple files and directories as arguments.\n\n```sh\nheader-warden ../src ~/dev/app/tests\n```\n\n\u003e [!TIP]\n\u003e On Windows, a modern terminal emulator like [Windows Terminal](https://github.com/microsoft/terminal) is recommended, although the default Command Prompt will display UTF-8 characters correctly.\n\n\n### Multithreading\n\nWhen processing three or more files, multithreading is enabled, and results are printed asynchronously as each file is processed. For 1-2 files, multithreading is disabled to avoid unnecessary overhead. Please note that if you pass a directory, more than two files might be found through recursive search, which will enable multithreading.\n\nWithin each file, however, the app analyzes lines sequentially, one at a time. While it’s technically possible to make this line-by-line analysis multithreaded, doing so would add significant complexity and overhead, as most files are analyzed in milliseconds (e.g., 25 ms in total for all files in this project). Only *exceptionally large files* (e.g., the 11.5MB `assets.cpp` file containing embedded Korean font data in my [aegyo](https://github.com/ryouze/aegyo) app) might benefit from within-file multithreading. For 99% of files, however, this approach would actually *reduce* performance, making the current implementation more efficient for the expected use case.\n\nWith this in mind, large files always appear at the end of the output as they take longer to process, while results for smaller files are displayed immediately.\n\n\u003e [!TIP]\n\u003e The `--no-multithreading` flag can be used to disable multithreading altogether, regardless of the number of files being processed.\n\n\n## Flags\n\n```sh\n[~] $ header-warden --help\nUsage: header-warden [--help] [--version] [--no-bare] [--no-unused]\n                     [--no-unlisted] [--no-multithreading]\n                     paths...\n\nIdentify and report missing headers in C++ code.\n\nPositional arguments:\n  paths                files or directories to process [nargs: 1 or more]\n\nOptional arguments:\n  -h, --help           shows help message and exits\n  -v, --version        prints version information and exits\n  --no-bare            disables bare include directives\n  --no-unused          disables unused functions\n  --no-unlisted        disables unlisted functions\n  --no-multithreading  disables multithreading\n```\n\n\n## Testing\n\nTests are included in the project but are not built by default.\n\nTo enable and build the tests manually, run the following commands from the `build` directory:\n\n```sh\ncmake .. -DBUILD_TESTS=ON\ncmake --build . --parallel\nctest --output-on-failure\n```\n\n\n## Credits\n\n- [argparse](https://github.com/p-ranav/argparse)\n- [BS::thread_pool](https://github.com/bshoshany/thread-pool)\n- [fmt](https://github.com/fmtlib/fmt)\n\n\n## Contributing\n\nAll contributions are welcome.\n\n\n## License\n\nThis project is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryouze%2Fheader-warden","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryouze%2Fheader-warden","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryouze%2Fheader-warden/lists"}