Warning Counter (wcnt) is a small command line utility to count the number of warnings in log files, and compare them to defined limits. Useful in CI environments where you want to ensure the number or warnings does not increase.
The kinds of warnings are defined in Wcnt.toml
which should be located at the root of your project.
Limits are defined in Limits.toml
which are then valid for source files in that tree of directories
on the file system. You can have multiple Limits.toml
files and place them where you see fit. Perhaps one
per component, or subsystem, whichever fits your project the best. If the system does not find a Limits.toml
file
when searching for a set limit, it will use 0 for a limit, so be sure you specify your limits!
Below follows an example Wcnt.toml
file, defining rules for the two kinds gcc
and flake8
.
```toml
[gcc]
regex = "^(?P
[flake8]
regex = "^(?P
Inside Wcnt.toml
, you define a map for each "kind" of warning you want to search for, and how to search for it.
Required settings for each are regex
and files
. The regex
value must define a file
capture group, so we know
which file was responsible for each particular warning, and thus, which Limits.toml
should be used.
The capture groups line
, column
, category
and description
are optional and allows the system to disregard
multiples of the same warning (Useful for header files).
The category
key also allows you to define individual limits for different categories.
In order to be able to use per-category limits, your regex must define a category
capture group. Otherwise the system
will abort when parsing the Limits.toml
file. This is to prevent a false sense of security.
Below follows an example Limits.toml
file where flake8
warnings are capped at 300, and gcc
warnings are separated
into a few different categories. You can use inf
to allow any number of warnings, and _
is the wildcard category.
It matches any category you have not already defined. When using per-category limits, it's always wise to include the
wildcard category, otherwise the limit is zero.
```toml flake8 = 300
[gcc] -Wpedantic = 3 -Wcomment = inf -Wunused-variable = 2 _ = 0 ``` Note: Per-category definitions must be at the end of file, because of how TOML works.
When not using per-category limits, all categories are counted towards the same limit. In other words, these two ways
of defining limits are equivalent.
toml
kind = 1
and
toml
[kind]
_ = 1
Limits.toml
filesEvery warning from a source file are counted towards the Limits.toml
file that are closest to it going straight up
file system tree. In the example below, component_a
and component_b
share the limits defined in
project/src/Limit.toml
while component_c
has its own limits. This is useful if you have some component that
should have extra strict, or extra loose rules. Such as a newly developed piece of code, or a vendored
third party dependency or legacy code.
plain
project
├── Wcnt.toml
├── src
│ ├── Limits.toml
│ ├── component_a
│ │ ├── source.c
│ │ ├── interface.h
│ │ └── utility.py
│ ├── component_b
│ │ ├── binary.c
│ │ ├── code.c
│ │ └── interface.h
│ └── component_c
│ ├── Limits.toml
│ ├── rustmodule.rs
│ └── glue.c
└── build
├── compilation.log
└── lint.log
If you've got a particular kind of warning that you do not want to bother with for a certain part of the code base, you
can specify the limit to be inf
, like so:
toml
[kind]
-Wbothersome = inf
This is useful if you've got vendored code, or experimental code, which you do not want or can keep to the same standard
as your production code, but still want to compile with otherwise the exact same settings.
The tool can automatically update/lower and prune your Limits.toml
files.
When you have zero warnings, with the flag --update-limits
the following limits:
toml
[gcc]
-Wpedantic = 3
-Wcomment = 3
-Wunused-variable = 2
turns into
toml
[gcc]
-Wpedantic = 0
-Wcomment = 0
-Wunused-variable = 0
Note: --update-limits
does not touch limits set to inf
.
With the addition of --prune
, the above limits are reduced to
toml
gcc = 0
Note: --prune
also does not touch limits set to inf
.
It is strongly recommended to have a automated recurring task which runs wcnt --update-limits [--prune]
and commits
the results into your repository, so you can ensure that the limits are indeed lowered over time.
In some circumstances, you don't want to (or can't) have all warnings available at once. For example if you compile
your C code using both GCC and MSVC/XCode. Then you can pass arguments using the --only
flag, to run the tool for
only that or those kinds of warnings. This functionality integrates with --update-limits
and does not remove
limits from your Limits.toml
files. If you have recurring jobs automatically making commits to lower your limits,
you will have to take care of any merge conflicts yourself.
```plain $ wcnt --help Warning Counter (wcnt) 0.4.0 Mikael Silvén mikael@silven.nu A program to count your warnings inside log files and comparing them against defined limits.
USAGE: wcnt [FLAGS] [OPTIONS]
FLAGS: -h, --help Prints help information -V, --version Prints version information --update-limits Update the Limit.toml files with lower values if no violations were found. --prune Also aggressively prune Limits.toml files to more minimal forms (requires --update-limits). -v Be more verbose. (-vv for very verbose) --all Also print non-violating warnings. (if verbose or very verbose)
OPTIONS:
--only
-isystem
for these things.\\?\
-style paths you might be in trouble. Until I have published Wcnt to crates.io you can find binaries at the Github Releases Page. Sorry about that.
Wcnt should also build normally with cargo.
plain
cargo build --release
Warning Counter (Wcnt) is licensed under the Apache 2.0 (http://www.apache.org/licenses/LICENSE-2.0) License. It may be used in free software as well as closed-source applications, both for commercial and non-commercial use under the conditions given in the license.
Any contribution intentionally submitted for inclusion in the work must also be Apache2 licensed.