Repository navigation
Releases: slowy07/metis
Release list
v0.5.0
v0.5.0: Result Cache, Perf/Deps/Build Subcommands, Per-Command Help
What's Changed
- Result cache for
metis run-- successful check results are now cached in.metis-cache/, keyed by a hash of the check command/args plus per-file size and mtime fingerprints. Unchanged checks on unchanged files are skipped on repeat runs. --diff-only-- check just the diff (staged files) with the cache enabled; the defaultmetis runalready targets staged files.--all-filessweeps the whole tracked codebase and never uses the cache.--no-cachebypasses caching on a diff run.- Cache use-after-free fix -- the cache previously freed its backing storage before checks executed, so no cache entry was ever written; it now lives for the full run and the cache works correctly.
perfsubcommand -- performance checks for build time, binary size, and benchmarks viaPerfChecksUseCase, configured in the[perf]TOML section.--level quickruns binary size only;--level full(default) also covers build time and benchmarks.depssubcommand -- validates project dependencies across Conan, vcpkg, and CMake FetchContent viaDependencyCheckUseCase, with duplicate detection and lockfile awareness.--treedisplays a dependency tree;--graphgenerates a graph.buildsubcommand -- configure and build the project with CMake viaBuildUseCase. Supports--build-dir,--clean,--verbose, and-j/--jobs.- Per-subcommand
--help-- every subcommand (init,install,sync,run,test,sanitizer,deps,build,perf,install-compiler,generate-gha,generate-gitlab) now shows its own detailed usage viametis <command> --help. syncsubcommand -- refreshes hooks/workflows, generates missing tool configs, and validates all configured checks.- Interactive init improvements -- richer prompting and detail information in the init wizard.
- New unit tests -- argparse parsing, security checks, dependency checks, perf checks, and the check cache (store/lookup, arg mismatch, changed-file invalidation).
- Docs overhaul -- usage, architecture, dependency, and formatting docs refreshed for the new subcommands, flags, and cache behavior.
Usage: metis run Modes
--diff-only-- check only the diff (staged files), cache enabled.--all-files-- check every tracked file in the repo, cache disabled.<files...>-- check specific files explicitly.--no-cache-- disable the result cache for a diff run.--detail-- verbose output showing pass/fail per check.
Install
Linux:
curl -LsSf https://raw.githubusercontent.com/slowy07/metis/main/install.sh | shWindows (Powershell):
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/metis/main/install.ps1 | iex"Arch Linux (AUR):
yay -S metisv0.4.0
v0.4.0: New Check Types, Test & Sanitizer Subcommands, SHA-256 Verification
What's Changed
- New check types --
cppcheck,gcc-analyzer,clang-static-analyzer,iwyu(include-what-you-use) are now recognized by themake_checkfactory and run with proper defaults. testsubcommand -- runsctestagainst a build directory with optional--coveragereporting and line/branch/function threshold enforcement viaTestChecksUseCase.sanitizersubcommand -- builds and tests with ASan/UBSan/TSan/LSan viaSanitizerChecksUseCase, reading types from the[sanitizers]TOML section.generate_sanitizer_config()-- new config generator that emits a[sanitizer]section for.sniffercommit.toml.- SHA-256 verification -- Windows GCC installer now verifies downloaded archives against a SHA-256 checksum, with fail-closed behavior on fetch failure.
- Generic check abstraction --
domain::check::Checkbase class withvalidate()/execute()contract; concrete checks dispatch by command basename viamake_checkfactory. - Compiler check fixes -- mode detection (
-c/-S/-E) prevents redundant-fsyntax-onlyinjection;--compiler-debug-and-releaseemits two checks instead of one. - Interactive init fixes --
std::to_arraycompile errors resolved; compiler checks config append moved before file write; defaultcompiler_debug_and_releasewired correctly. show_help()updated -- all 7 subcommands now haveUsage:examples in--helpoutput.- 17 new unit tests -- config generators, config validation, sanitizer checks, SHA-256 verification, TestChecksUseCase.
- Docs overhaul -- exit codes table expanded to 20 entries;
install-gccrenamed toinstall-compilerthroughout; testing section rewritten for GoogleTest + CTest.
Usage: sniffercommit run Modes
--all-files-- check every tracked file in the repo.--staged-- check only git-staged files (default for pre-commit hooks).<files...>-- check specific files explicitly.--detail-- verbose output showing pass/fail per check.
Install
Linux:
curl -LsSf https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.sh | shWindows (Powershell):
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.ps1 | iex"v0.3.20
v0.3.20
This release removes ~3,100 lines of dead code from the old implementation, deduplicates helpers in the check execution path, and fixes the installer's source-build logic.
What's Changed
- Deleted 7 dead source pairs:
tooling_config,executor,config_manager,project_config,precommit_domain,cicd_domain,error_codes.hppwere superseded by the hexagonal architecture layer and never called. - Deleted unused
ILoggerport: Interface had zero implementations;Loggersingleton is used directly everywhere. - Deduplicated
run_checks_use_case.cpp: Removed local copies ofCwdGuard,shell_escape,check_command_exists, andSpinnerin favor of the shared utilities inutil.hppandspinner.hpp. - Cleaned up CMakeLists.txt: Removed unused
SNIFFERCOMMIT_ENABLE_STATIC_LINKoption and dead libc detection block. - Fixed
install.sh: Replacedcargo build(copy-pasted from a Rust installer) withcmake --build. Removed staleCARGO_HOMEreferences. - Cleaned up
config.hpp.in: Removed unusedBuildInfo::print()and#include <ostream>. - Fixed clang-tidy warnings: Initialized struct members, renamed short variables, added trailing
_suffix to struct members per.clang-tidyconfig. Suppressedbugprone-easily-swappable-parametersandcppcoreguidelines-init-variables(too noisy for this codebase). - All 19 tests pass.
Install
Linux:
curl -LsSf https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.sh | shWindows (Powershell):
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.ps1 | iex"v0.3.15
v0.3.15
This release completes a major internal redesign of sniffercommit from a monolithic codebase to a hexagonal + layered architecture, and adds full Windows support (both MSVC/cmd.exe and MinGW/MSYS2).
- No more fork/exec/pipe/waitpid: The last inline POSIX process-spawning code has been replaced with a clean IShellExecutor port interface. The application layer is now fully portable.
- Windows support: Works natively on Windows with MSVC (cmd.exe) and MinGW/MSYS2. ANSI escape sequences are enabled automatically. Cross-compilation via MinGW on Linux is also supported.
- Zero shell-escaping: All git commands now use std::filesystem::current_path() (chdir) instead of cd && git ..., eliminating platform shell quoting issues entirely.
- Smart create_directories: OsFileSystem now returns true when a directory already exists (not an error), matching user expectations.
- interactive spinning loading
Checksum (SHA256)
e1e76353b085339e0802b12582d2748f6d5e41a1b29cb8012661fd137ba08d1a sniffercommit-0.3.15-linux-x86_64
b1df67ccde736f54d953485b0c0edc3d7da7d815b6debefe51d809d00ec37776 sniffercommit-0.3.15-windows-x86_64.exe
Install
Linux:
curl -LsSf https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.sh | shWindows (Powershell):
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.ps1 | iex"Full Changelog: v0.3.15...v0.3.15
v0.3.3
Sniffercommit format Mode
Sniffercommit can run --format using clang-format in-place code formatting
run clang-format in-place on your files without running the full check suite
# format staged files
sniffercommit run --format
# format all traced files
sniffercommit run --format --all-files
# format specific files
sniffercommit run --format src/main.cpp include/foo.hpp
# dry-run
sniffercommit run --format --dry-run --all-filesrequirements:
clang-format: must be installed and available inPATH.clang-formatconfig file must be exists (generated viasniffercommit init)
Format in Pre-Commit Hook
to auto-format on every commit, pass --format to check:
sniffercommit install
# config git hook to use
.git/hooks/pre-commit --formatDependency Management
sniffercommit supports adding external C++ dependencies to your project via CMake FetchContent. Dependencies are declared during sniffercommit init and validated before any files are created.
Overview
When you enable CMake scaffolding (--enable-cmake or interactive mode), sniffercommit can automatically generate FetchContent_Declare blocks in your CMakeLists.txt. Each dependency requires:
| Field | Description | Example |
|---|---|---|
name |
Package name (used for CMake target namespace) | fmt |
git_url |
HTTPS or SSH Git URL ending in .git |
https://github.com/fmtlib/fmt.git |
git_tag |
Branch, tag, or commit SHA to fetch | 11.0.2, main, v3.4.0 |
Quick Start
Interactive Mode
cd my-project
sniffercommit initWhen prompted for CMake options, answer y to add dependencies:
add dependencies [n]: y
enter dependency info (empty name to finish)
dep name []: fmt
git url [https://github.com/fmt/fmt.git]: https://github.com/fmtlib/fmt.git
git tag [main]: 11.0.2
✓ added fmt
dep name []: tomlplusplus
git url [https://github.com/tomlplusplus/tomlplusplus.git]:
git tag [main]: v3.4.0
✓ added tomlplusplus
dep name []:
Press Enter at dep name with no input to finish.
Install
# System-wide install
sudo cmake --install build
# Or create Debian package
cd build && cpack -G DEB
sudo dpkg -i sniffercommit_*.deb
# Install via pacman (AUR)
yay -S sniffercommit
Note
Portable binary currently support musl only, check by `ldd --version``
v0.2.1
CMake Scaffolding
sniffercommit init --enable-cmake generates a production-grade CMakeLists.txt and a minimal src/main.cpp:
sniffercommit init --enable-cmakeCreates:
CMakeLists.txt— full CMake project configurationsrc/main.cpp— entry point withmain()stub
CMake Options
| Flag | Values | Default | Description |
|---|---|---|---|
--cmake-cpp-standard |
17, 20, 23 |
20 |
C++ standard version |
--cmake-target-type |
executable, static, shared, header-only |
executable |
Build target type |
--cmake-enable-testing |
(flag) | off | Add enable_testing() + add_subdirectory(tests) |
--cmake-enable-sanitizers |
(flag) | off | AddressSanitizer + UBSan (Debug only) |
What the generated CMakeLists.txt includes:
cmake_minimum_required(VERSION 3.20)with project declaration- C++ standard enforcement (
CMAKE_CXX_STANDARD_REQUIRED ON, extensions OFF) - Build type configuration (Debug + Release)
CMAKE_EXPORT_COMPILE_COMMANDSfor IDE support- Source file and include directory setup
- Compiler warnings:
-Wall -Wextra -Wpedantic -Wconversion -Wshadow(GCC/Clang) or/W4(MSVC) - Sanitizers: address + undefined behaviour in Debug builds
- clang-tidy integration (if
--enable-clang-tidywas also passed) - clang-format custom target (
make format) - Testing:
enable_testing() + add_subdirectory(tests)(if--cmake-enable-testing) - Installation rules with GNUInstallDirs
Examples
# Minimal C++20 executable project
sniffercommit init --enable-cmake
# C++17 static library with testing
sniffercommit init --enable-cmake --cmake-cpp-standard 17 --cmake-target-type static --cmake-enable-testing
# Full-featured project with clang-tidy + sanitizers
sniffercommit init \
--enable-cmake \
--cmake-cpp-standard 20 \
--cmake-enable-testing \
--cmake-enable-sanitizers \
--enable-clang-tidy \
--tidy-preset strict \
--style google
# Header-only library (no src/main.cpp generated)
sniffercommit init --enable-cmake --cmake-target-type header-onlyGenerate src/main.cpp without CMake:
sniffercommit init --generate-srcCreates only src/main.cpp, no CMakeLists.txt.
Install
# System-wide install
sudo cmake --install build
# Or create Debian package
cd build && cpack -G DEB
sudo dpkg -i sniffercommit_*.deb
# Install via pacman (AUR)
yay -S sniffercommitsniffercommit v0.1.0
sniffercommit
Fast, C++20-powered pre-commit hook and CI generator. Ensures code quality before every push.
Features
- Parallel check execution — run linters concurrently via Bash background jobs
- Pattern-aware filtering — apply checks only to matching file extensions (
.cpp,.hpp, etc.) - Zero runtime dependencies — single static binary; no Python/Node required
- Auto-generate CI workflow — GitHub Actions workflow mirroring local hooks
- .clang-format scaffolding — generate
.clang-formatwith configurable style presets
Dependencies
| Dependency | Purpose |
|---|---|
tomlplusplus |
Header-only TOML config file parser and serializer |
fmt |
Modern formatting library |
Both are fetched automatically at configure time via CMake's FetchContent. No system installation required.
Build
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
# verify
./build/sniffercommit --versionUsage
Initialize a project
cd /path/to/project
sniffercommit init
# optional: specify formatter style
# available: google, llvm, chromium, mozilla, webkit, microsoft, gnu
sniffercommit init --style llvm
# optional: custom project name, indent width, column limit, etc.
sniffercommit init --style google --name my-project --indent-width 4 --column-limit 120This creates two files:
.sniffercommit.toml— check configuration with sensible defaults.clang-format— formatter style matching your chosen preset
Install pre-commit hooks
sniffercommit installGenerates and installs .git/hooks/pre-commit (and optionally .github/workflows/sniffercommit.yml).
Generate CI workflow only
sniffercommit generate-ghaRun checks manually
# all tracked files
sniffercommit run --all-files
# specific files
sniffercommit run src/main.cpp
# dry-run
sniffercommit run --dry-run --all-filesTest the hook
echo "int main(){return 0;}" > test.cpp
git add test.cpp
git commit -m "chore: test sniffercommit"Init Options
| Flag | Description |
|---|---|
--style <name> |
google, llvm, chromium, mozilla, webkit, microsoft, gnu (default: google) |
--name <name> |
Project name (default: current directory name) |
--indent-width <n> |
Indentation width (default: 2) |
--column-limit <n> |
Column limit (default: 100) |
--pointer-alignment <s> |
Pointer alignment: Left, Right, Middle |
--brace-style <s> |
Brace placement: Attach, Allman, etc. |
Debugging
# enable verbose config output
cmake -B build -DSNIFFERCOMMIT_VERBOSE_CONFIG=ON
# build with sanitizers (catch memory bugs)
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DSNIFFERCOMMIT_ENABLE_SANITIZERS=ON
# inspect generated hook
cat .git/hooks/pre-commit | less
# test hook manually (without git)
bash .git/hooks/pre-commitarch linux package
yay -S sniffercommit
install deb package
sudo dpkg -i sniffercommit_0.1.0_*.deb