| Crates.io | omnilinter |
| lib.rs | omnilinter |
| version | 0.7.0 |
| created_at | 2024-03-27 23:09:38.502488+00 |
| updated_at | 2024-04-04 17:51:18.637342+00 |
| description | General purpose bulk linter |
| homepage | https://github.com/AMDmi3/omnilinter |
| repository | https://github.com/AMDmi3/omnilinter |
| max_upload_size | |
| id | 1188502 |
| size | 208,294 |
Define path pattern and regular expression rules and match against all your repositories/projects/codebases at once. Use that to push and uphold good practices, chase deprecations, and fix common problems all over your code.
% cat omnilinter.conf
[convert deprecated auto_ptr to unique_ptr]
files *.cpp
match /auto_ptr/
[convert setup.py to pyproject.toml]
files setup.py
nofiles pyproject.toml
[add license information]
files *.py *.c* *.h* *.rs
nomatch /^..? SPDX-FileCopyrightText:/
[add CI workflow]
files *.py *.c* *.h* *.rs
nofiles .github/workflows/*.yml
[add project README]
nofiles /README*
% omnilinter -c omnilinter.conf my_projects/*
my_projects/my_python_project
setup.py: convert setup.py to pyproject.toml
src/__init__.py: add license information
my_project/my_cpp_lib
add project README
add CI workflow
src/main.cpp: add license information
src/main.cpp:17: convert deprecated auto_ptr to unique_ptr
See omnilinter's own config and author's ruleset for more examples.
At the very least, you need to specify path to config file and paths to directories to check:
omnilinter -c <path to omnilinter.conf> <directory to check> ...
or, if you set directories to check right in the config, and place it in the default location (~/.config/omnilinter/omnilinter.conf) you can just run
omnilinter
--tags, --skip-tags - limit operation with a subset of rules.--format by-root|full-paths|by-rule|by-path - specify output format.--color, --palette - tweak output coloring.--error-exitcode - exit with specified code if any rule matches, useful for CI and scripts.See omnilinter --help for all options.
Example omnilinter.conf:
root /path/to/project1
root /path/to/other_projects/* # patterns are allowed
include /path/to/other.conf
[rule title]
tags tag1,tag2 # used with --tags, --exclude-tags
nofiles /README* !/README.txt # require absence of file
files *.py !*.pyi # or require presence of a file, in which...
match /Object/ !/^class / # ...require pattern match...
nomatch "^/usr/share/.*" # ...or absence of pattern match
[next rule]
...
At the beginning of the file, config directives are allowed:
root specifies default directories to operate on. These are only
used if no roots are specified on the command line. Shell patterns
are supported here. Non-absolute paths are resolved relative to config
location.
include parses additional configs. Shell patterns are supported here
too, non-absolute paths are resolved relative to config location.
Ruleset follows next, in which each rule consists of:
Bracketed title which is used when reporting matches. Use ]] if you
want to include closing bracket in the title. All other parts are optional.
tags directive with a comma or space separated list of tags to filter
rules with --tags and --exclude-tags command line options.
Path conditions:
files which require presence of specific path patterns in the directory.nofiles which require absence thereof.Each requires one or more shell pattern (e.g. *.py or /src/*.c* or
**/tests/*.rs) and allows exclusions (prefixed by !). Backslash
escaping and quotes are allowed like in shell ("program output "\[[0-9]\].txt
to match program output [1].txt). Patterns without path separators match
everywhere (*.py matches both setup.py and src/mymodule/__init__.py),
while patterns with path separators only match relative to root.
Content conditions (only allowed after files and only apply to
files matched by that specific files condition):
match requires match of given regular expression pattern in a file.nomatch requires absence of such match.These require one or more regular expressions enclosed in (almost) any
character (e.g. /.*/, ".*", |.*| all work, so escaping can be avoided)
and also allow !-prefixed exclusions.
size checks file size with an operator (>, >=, <, '<=, =or==, !=or<>) against given amount of bytes (e.g. size >= 1024`).lines checks number of lines the same way.You may build rather complex trees out of these conditions, for example:
[too big readme for such small rust library]
# match when there's src/lib.rs...
files src/lib.rs
# ...but no other .rs files under src/, which along with the
# previous condition suggest it's a single-file rust library
nofiles src/**/*.rs !src/lib.rs
# if there's README file of any kind,...
files /README*
# ...and it's longer than 25 lines...
lines >= 25
# ...unless there's Example: header (implied that it may contain a lot of code)
nomatch /^#* Example:/
When all rule conditions are satisfied, the rule match is reported:
README.md: too big readme for such small rust library
The match may include context:
match, file and line would
be reported.files, file
would be reported (like in example above).Therefore rule order matters, so preconditions should be specified first, and conditions which point to concrete problematic places last.
Rule with special [!template] title is not processed as a regular rule, but
instead specifies items (tags and conditions) to be prepended to all
following rules. This is useful to reduce duplication. You may specify
bodyless [!template] rule without any items to reset the template.
Install from cargo or from your package repository
cargo install omnilinter