{"id":20757821,"url":"https://github.com/amdmi3/omnilinter","last_synced_at":"2026-03-03T22:00:55.463Z","repository":{"id":221763472,"uuid":"753846511","full_name":"AMDmi3/omnilinter","owner":"AMDmi3","description":"General purpose bulk linter","archived":false,"fork":false,"pushed_at":"2026-01-26T14:59:14.000Z","size":441,"stargazers_count":1,"open_issues_count":13,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-27T03:43:04.058Z","etag":null,"topics":["linter","linting","linting-rules"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AMDmi3.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-02-06T22:35:41.000Z","updated_at":"2026-01-26T14:59:12.000Z","dependencies_parsed_at":"2024-04-09T10:44:06.390Z","dependency_job_id":"de85b02b-bf3c-4d3f-aa9d-2b04bfbee50e","html_url":"https://github.com/AMDmi3/omnilinter","commit_stats":null,"previous_names":["amdmi3/omnilinter"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/AMDmi3/omnilinter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AMDmi3%2Fomnilinter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AMDmi3%2Fomnilinter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AMDmi3%2Fomnilinter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AMDmi3%2Fomnilinter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AMDmi3","download_url":"https://codeload.github.com/AMDmi3/omnilinter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AMDmi3%2Fomnilinter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30063348,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T18:21:05.932Z","status":"ssl_error","status_checked_at":"2026-03-03T18:20:59.341Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["linter","linting","linting-rules"],"created_at":"2024-11-17T09:45:26.384Z","updated_at":"2026-03-03T22:00:55.435Z","avatar_url":"https://github.com/AMDmi3.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# omnilinter\n\n[![CI](https://github.com/AMDmi3/omnilinter/actions/workflows/ci.yml/badge.svg)](https://github.com/AMDmi3/omnilinter/actions/workflows/ci.yml)\n[![GitHub commits (since latest release)](https://img.shields.io/github/commits-since/AMDmi3/omnilinter/latest.svg)](https://github.com/AMDmi3/omnilinter)\n\nDefine path pattern and regular expression rules and match against all\nyour repositories/projects/codebases at once. Use that to push and uphold\ngood practices, chase deprecations, and fix common problems all over\nyour code.\n\n## Example\n\n```\n% cat omnilinter.conf\n[convert deprecated auto_ptr to unique_ptr]\nfiles *.cpp\nmatch /auto_ptr/\n\n[convert setup.py to pyproject.toml]\nfiles setup.py\nnofiles pyproject.toml\n\n[add license information]\nfiles *.py *.c* *.h* *.rs\nnomatch /^..? SPDX-FileCopyrightText:/\n\n[add CI workflow]\nfiles *.py *.c* *.h* *.rs\nnofiles .github/workflows/*.yml\n\n[add project README]\nnofiles /README*\n```\n```\n% omnilinter -c omnilinter.conf my_projects/*\nmy_projects/my_python_project\n  setup.py: convert setup.py to pyproject.toml\n  src/__init__.py: add license information\nmy_project/my_cpp_lib\n  add project README\n  add CI workflow\n  src/main.cpp: add license information\n  src/main.cpp:17: convert deprecated auto_ptr to unique_ptr\n```\n\nSee omnilinter's own [config](.omnilinter.conf) and [author's\nruleset](https://github.com/AMDmi3/omnilinter-rules-amdmi3/) for more\nexamples.\n\n## Running\n\nAt the very least, you need to specify path to config file and paths to directories to check:\n\n```\nomnilinter -c \u003cpath to omnilinter.conf\u003e \u003cdirectory to check\u003e ...\n```\n\nor, 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\n\n```\nomnilinter\n```\n\n### Useful options\n\n- `--tags`, `--skip-tags` - limit operation with a subset of rules.\n- `--format by-root|full-paths|by-rule|by-path` - specify output format.\n- `--color`, `--palette` - tweak output coloring.\n- `--error-exitcode` - exit with specified code if any rule matches, useful for CI and scripts.\n\nSee `omnilinter --help` for all options.\n\n## Config file format\n\nExample `omnilinter.conf`:\n```\nroot /path/to/project1\nroot /path/to/other_projects/*  # patterns are allowed\n\ninclude /path/to/other.conf\n\n[rule title]\ntags tag1,tag2                  # used with --tags, --exclude-tags\nnofiles /README* !/README.txt   # require absence of file\nfiles *.py !*.pyi               # or require presence of a file, in which...\nmatch /Object/ !/^class /       # ...require pattern match...\nnomatch \"^/usr/share/.*\"        # ...or absence of pattern match\n\n[next rule]\n...\n```\n\nAt the beginning of the file, config directives are allowed:\n\n* `root` specifies default directories to operate on. These are only\nused if no roots are specified on the command line. Shell patterns\nare supported here. Non-absolute paths are resolved relative to config\nlocation.\n\n* `include` parses additional configs. Shell patterns are supported here\ntoo, non-absolute paths are resolved relative to config location.\n\nRuleset follows next, in which each rule consists of:\n\n* Bracketed title which is used when reporting matches. Use `]]` if you\nwant to include closing bracket in the title. All other parts are optional.\n\n* `tags` directive with a comma or space separated list of tags to filter\nrules with `--tags` and `--exclude-tags` command line options.\n\n* Path conditions:\n  * `files` which require presence of specific path patterns in the directory.\n  * `nofiles` which require absence thereof.\n\n  Each requires one or more shell pattern (e.g. `*.py` or `/src/*.c*` or\n  `**/tests/*.rs`) and allows exclusions (prefixed by `!`). Backslash\n  escaping and quotes are allowed like in shell (`\"program output \"\\[[0-9]\\].txt`\n  to match `program output [1].txt`).  Patterns without path separators match\n  everywhere (`*.py` matches both `setup.py` and `src/mymodule/__init__.py`),\n  while patterns with path separators only match relative to root.\n\n* Content conditions (only allowed after `files` and only apply to\n  files matched by that specific `files` condition):\n  * `match` requires match of given regular expression pattern in a file.\n  * `nomatch` requires absence of such match.\n\n  These require one or more regular expressions enclosed in (almost) any\n  character (e.g. `/.*/`, `\".*\"`, `|.*|` all work, so escaping can be avoided)\n  and also allow `!`-prefixed exclusions.\n\n  * `size` checks file size with an operator (`\u003e`, `\u003e=`, `\u003c`, '\u003c=`, `=`\n  or `==`, `!=` or `\u003c\u003e`) against given amount of bytes (e.g. `size \u003e= 1024`).\n  * `lines` checks number of lines the same way.\n\nYou may build rather complex trees out of these conditions, for example:\n\n```\n[too big readme for such small rust library]\n# match when there's src/lib.rs...\nfiles src/lib.rs\n# ...but no other .rs files under src/, which along with the\n# previous condition suggest it's a single-file rust library\nnofiles src/**/*.rs !src/lib.rs\n# if there's README file of any kind,...\nfiles /README*\n# ...and it's longer than 25 lines...\nlines \u003e= 25\n# ...unless there's Example: header (implied that it may contain a lot of code)\nnomatch /^#* Example:/\n```\n\nWhen all rule conditions are satisfied, the rule match is reported:\n\n```\nREADME.md: too big readme for such small rust library\n```\n\nThe match may include context:\n* If the very last condition in a rule is `match`, file and line would\n  be reported.\n* Otherwise, if the very last of _path_ conditions was `files`, file\n  would be reported (like in example above).\n* Otherwise, there's no specific context, and the report is for the checked\n  directory in general.\n\nTherefore rule order matters, so preconditions should be specified first, and\nconditions which point to concrete problematic places last.\n\n### Rule templates\n\nRule with special `[!template]` title is not processed as a regular rule, but\ninstead specifies items (tags and conditions) to be prepended to all\nfollowing rules. This is useful to reduce duplication. You may specify\nbodyless `[!template]` rule without any items to reset the template.\n\n## Installation\n\n\u003ca href=\"https://repology.org/project/omnilinter/versions\"\u003e\n    \u003cimg src=\"https://repology.org/badge/vertical-allrepos/omnilinter.svg\" alt=\"Packaging status\" align=\"right\"\u003e\n\u003c/a\u003e\n\nInstall from cargo or from your package repository\n\n```\ncargo install omnilinter\n```\n\n## Author\n\n* [Dmitry Marakasov](https://github.com/AMDmi3) \u003camdmi3@amdmi3.ru\u003e\n\n## License\n\n* [GPL-3.0-or-later](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famdmi3%2Fomnilinter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famdmi3%2Fomnilinter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famdmi3%2Fomnilinter/lists"}