Skip to content

Releases: slowy07/metis

v0.5.0

Choose a tag to compare

@slowy07 slowy07 released this 29 Aug 05:22
v0.5.0
0b6aca6

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 default metis run already targets staged files. --all-files sweeps the whole tracked codebase and never uses the cache. --no-cache bypasses 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.
  • perf subcommand -- performance checks for build time, binary size, and benchmarks via PerfChecksUseCase, configured in the [perf] TOML section. --level quick runs binary size only; --level full (default) also covers build time and benchmarks.
  • deps subcommand -- validates project dependencies across Conan, vcpkg, and CMake FetchContent via DependencyCheckUseCase, with duplicate detection and lockfile awareness. --tree displays a dependency tree; --graph generates a graph.
  • build subcommand -- configure and build the project with CMake via BuildUseCase. 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 via metis <command> --help.
  • sync subcommand -- 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 | sh

Windows (Powershell):

powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/metis/main/install.ps1 | iex"

Arch Linux (AUR):

yay -S metis

v0.4.0

Choose a tag to compare

@slowy07 slowy07 released this 19 Aug 10:15
v0.4.0
ebf5958

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 the make_check factory and run with proper defaults.
  • test subcommand -- runs ctest against a build directory with optional --coverage reporting and line/branch/function threshold enforcement via TestChecksUseCase.
  • sanitizer subcommand -- builds and tests with ASan/UBSan/TSan/LSan via SanitizerChecksUseCase, 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::Check base class with validate()/execute() contract; concrete checks dispatch by command basename via make_check factory.
  • Compiler check fixes -- mode detection (-c/-S/-E) prevents redundant -fsyntax-only injection; --compiler-debug-and-release emits two checks instead of one.
  • Interactive init fixes -- std::to_array compile errors resolved; compiler checks config append moved before file write; default compiler_debug_and_release wired correctly.
  • show_help() updated -- all 7 subcommands now have Usage: examples in --help output.
  • 17 new unit tests -- config generators, config validation, sanitizer checks, SHA-256 verification, TestChecksUseCase.
  • Docs overhaul -- exit codes table expanded to 20 entries; install-gcc renamed to install-compiler throughout; 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 | sh

Windows (Powershell):

powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.ps1 | iex"

v0.3.20

Choose a tag to compare

@slowy07 slowy07 released this 25 Jul 13:12
764e491

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.hpp were superseded by the hexagonal architecture layer and never called.
  • Deleted unused ILogger port: Interface had zero implementations; Logger singleton is used directly everywhere.
  • Deduplicated run_checks_use_case.cpp: Removed local copies of CwdGuard, shell_escape, check_command_exists, and Spinner in favor of the shared utilities in util.hpp and spinner.hpp.
  • Cleaned up CMakeLists.txt: Removed unused SNIFFERCOMMIT_ENABLE_STATIC_LINK option and dead libc detection block.
  • Fixed install.sh: Replaced cargo build (copy-pasted from a Rust installer) with cmake --build. Removed stale CARGO_HOME references.
  • Cleaned up config.hpp.in: Removed unused BuildInfo::print() and #include <ostream>.
  • Fixed clang-tidy warnings: Initialized struct members, renamed short variables, added trailing _ suffix to struct members per .clang-tidy config. Suppressed bugprone-easily-swappable-parameters and cppcoreguidelines-init-variables (too noisy for this codebase).
  • All 19 tests pass.

Install

Linux:

curl -LsSf https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.sh | sh

Windows (Powershell):

powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/slowy07/sniffercommit/main/install.ps1 | iex"

v0.3.15

Choose a tag to compare

@slowy07 slowy07 released this 19 Jun 04:52
2a19fd1

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 | sh

Windows (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

Choose a tag to compare

@slowy07 slowy07 released this 29 May 01:41
v0.3.3
c04fdc3

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-files

requirements:

  • clang-format: must be installed and available in PATH
  • .clang-format config file must be exists (generated via sniffercommit 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 --format

Dependency 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 init

When 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

Choose a tag to compare

@slowy07 slowy07 released this 19 May 16:13
v0.2.1
9ccf979

CMake Scaffolding

sniffercommit init --enable-cmake generates a production-grade CMakeLists.txt and a minimal src/main.cpp:

sniffercommit init --enable-cmake

Creates:

  • CMakeLists.txt — full CMake project configuration
  • src/main.cpp — entry point with main() 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_COMMANDS for 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-tidy was 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-only

Generate src/main.cpp without CMake:

sniffercommit init --generate-src

Creates 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 sniffercommit

sniffercommit v0.1.0

Choose a tag to compare

@slowy07 slowy07 released this 17 May 11:31
v0.1.0
c1ace4a

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-format with 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 --version

Usage

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 120

This creates two files:

  • .sniffercommit.toml — check configuration with sensible defaults
  • .clang-format — formatter style matching your chosen preset

Install pre-commit hooks

sniffercommit install

Generates and installs .git/hooks/pre-commit (and optionally .github/workflows/sniffercommit.yml).

Generate CI workflow only

sniffercommit generate-gha

Run checks manually

# all tracked files
sniffercommit run --all-files

# specific files
sniffercommit run src/main.cpp

# dry-run
sniffercommit run --dry-run --all-files

Test 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-commit

arch linux package

yay -S sniffercommit

install deb package

sudo dpkg -i sniffercommit_0.1.0_*.deb