{"id":15056434,"url":"https://github.com/inaka/elvis_core","last_synced_at":"2026-04-02T00:56:28.553Z","repository":{"id":37803250,"uuid":"46725535","full_name":"inaka/elvis_core","owner":"inaka","description":"The core of an Erlang linter","archived":false,"fork":false,"pushed_at":"2025-05-03T13:28:46.000Z","size":1231,"stargazers_count":66,"open_issues_count":33,"forks_count":59,"subscribers_count":38,"default_branch":"main","last_synced_at":"2025-05-03T14:32:42.854Z","etag":null,"topics":["elvis","elvis-core","erlang","hacktoberfest","linter","style-checker"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inaka.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-11-23T14:25:40.000Z","updated_at":"2025-05-03T13:28:49.000Z","dependencies_parsed_at":"2024-05-21T21:42:00.080Z","dependency_job_id":"5fe02acb-2cb9-4192-aba6-2f57edbc5062","html_url":"https://github.com/inaka/elvis_core","commit_stats":{"total_commits":531,"total_committers":54,"mean_commits":9.833333333333334,"dds":0.6195856873822976,"last_synced_commit":"6be281face7ba131688da3880214b9399855fbb9"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Felvis_core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Felvis_core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Felvis_core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Felvis_core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inaka","download_url":"https://codeload.github.com/inaka/elvis_core/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319715,"owners_count":22051072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["elvis","elvis-core","erlang","hacktoberfest","linter","style-checker"],"created_at":"2024-09-24T21:51:24.109Z","updated_at":"2026-04-02T00:56:28.541Z","avatar_url":"https://github.com/inaka.png","language":"Erlang","funding_links":[],"categories":["Erlang"],"sub_categories":[],"readme":"# `elvis_core` [![GitHub Actions CI](https://github.com/inaka/elvis_core/workflows/build/badge.svg)](https://github.com/inaka/elvis_core/actions) [![Erlang Support](https://img.shields.io/badge/Erlang/OTP-26+-blue)](https://www.erlang.org)\n\n`elvis_core` is the core library for the [`elvis`](https://github.com/inaka/elvis) Erlang style\nreviewer. It is also used by [`rebar3_lint`](https://github.com/project-fifo/rebar3_lint) for easier\nintegration into your Erlang libraries or applications.\n\nIt includes the mechanisms to apply rules to your Erlang code, as well as their implementation.\n\nIt implements [pre-defined rules](#pre-defined-rules), but also supports\n[user-defined ones](#user-defined-rules).\n\n## Usage\n\n### As a command-line tool\n\nThe [`elvis`](https://github.com/inaka/elvis) command-line tool uses `elvis_core` extensively, so\ndo check that project for a concrete example on how you could use it for your own purposes.\n\n### As a `rebar3` plugin\n\nThe [`rebar3_lint`](https://github.com/project-fifo/rebar3_lint) plugin eases integration of the\nstyle reviewer into your application or library. Be sure to check that out for further information.\n\n### From the Erlang shell\n\nAfter adding `elvis_core` as a dependency to your project and starting a shell, you will need to\nmake sure the application is started:\n\n```erlang\n1\u003e {ok, _} = application:ensure_all_started(elvis_core).\n{ok,[katana_code,elvis_core]}\n2\u003e\n```\n\nOnce this is done you can apply the style rules in the following ways.\n\n#### Loading configuration from a file\n\n```erlang\n1\u003e elvis_core:rock({config_file, \"elvis.config\"}).\nLoading src/elvis_code.erl\n# src/elvis_code.erl [OK]\nLoading src/elvis_config.erl\n# src/elvis_config.erl [OK]\nLoading src/elvis_core.erl\n# src/elvis_core.erl [OK]\nLoading src/elvis_file.erl\n# src/elvis_file.erl [OK]\n...\nok\n2\u003e\n```\n\nThis will load the [configuration](#configuration), specified in file `elvis.config`, from the\ncurrent directory.\n\nIf `elvis.config` is not present, the application will fall back to searching for configuration\nparameters in `rebar.config`. If `rebar.config` is also unavailable, the application proceeds to\nperform a tertiary lookup within its application environment (which can also be set via the\n`app/sys.config` file, or e.g., via `application:set_env(elvis_core, Key, Value).` for the required\nsettings.\n\n#### Providing configuration as a value\n\nAnother option for using `elvis_core` from the shell is to explicitly provide the configuration as\nan argument to `elvis_core:rock/1`:\n\n```erlang\n1\u003e ElvisConfig = [#{files =\u003e [\"src/elvis_rule.erl\"], ruleset =\u003e erl_files}].\n[#{files =\u003e [\"src/elvis_rule.erl\"],rules =\u003e []}]\n2\u003e elvis_core:rock({config, ElvisConfig}).\nLoading src/elvis_rule.erl\n# src/elvis_rule.erl [OK]\nok\n3\u003e\n```\n\n#### Output for failing rules\n\nWe have only presented results where all files were well-behaved (i.e. they respect all the rules),\nso here's an example of how the output looks when files break some of the rules:\n\n```text\n# test/examples/british_behaviour_spelling.erl [FAIL]\n  - state_record_and_type (https://github.com/inaka/elvis_core/tree/main/doc_rules/elvis_style/state_record_and_type.md)\n    - This module implements an OTP behavior but is missing a '#state{}' record.\n# test/examples/fail_always_shortcircuit.erl [FAIL]\n  - always_shortcircuit (https://github.com/inaka/elvis_core/tree/main/doc_rules/elvis_style/always_shortcircuit.md)\n    - At line 5, column 45, unexpected non-shortcircuiting operator 'or' was found; prefer 'orelse'.\n```\n\n## Configuration\n\nAn `elvis.config` file looks something like this:\n\n```erlang\n[\n    {config, [\n        #{\n            files =\u003e [\"src/*.erl\"],\n            ruleset =\u003e erl_files\n        },\n        #{\n            files =\u003e [\"include/*.hrl\"],\n            ruleset =\u003e hrl_files\n        },\n        #{\n            files =\u003e [\"rebar.config\"],\n            ruleset =\u003e rebar_config\n        }\n    ]},\n    % output_format (optional): how to format the output.\n    % Possible values are 'plain', 'colors' or 'parsable' (default='colors').\n    {output_format, colors},\n    % verbose (optional): when 'true' more information will\n    % be printed (default=false).\n    {verbose, true},\n    % no_output (optional): when 'true' nothing will be printed\n    % (default=false).\n    {no_output, false},\n    % parallel: determine how many files will be\n    % analyzed in parallel (default=1).\n    {parallel, 1}\n].\n```\n\nTo look at what is considered the \"current default\" configuration, do:\n\n```erlang\nrebar3 shell\n...\n1\u003e elvis_config:default().\n[#{files =\u003e [\"apps/**/src/*.erl\",\"src/*.erl\"],\n   ruleset =\u003e erl_files},\n #{files =\u003e\n       [\"apps/**/src/*.hrl\",\"apps/**/include/*.hrl\",\n        \"src/*.hrl\",\"include/*.hrl\"],\n   ruleset =\u003e hrl_files},\n #{files =\u003e [\"rebar.config\"],\n   ruleset =\u003e rebar_config},\n #{files =\u003e [\".gitignore\"],\n   ruleset =\u003e gitignore}]\n2\u003e\n```\n\n**Note**: this element might change with time. The above was what was generated when this\ndocumentation was updated.\n\n### Files, rules and rulesets\n\nThe `files` key is a list of glob patterns that tell `elvis_core` which files to analyse. Each\npattern uses [`filelib:wildcard/1`](https://erlang.org/doc/man/filelib.html#wildcard-1), so you can\nuse patterns like `\"src/*.erl\"` or `\"apps/**/src/*.erl\"`. Matching files are run through the\npre-defined rules in the specified `ruleset`.\n\nIf you want to override the [pre-defined rules](#pre-defined-rules), for a given ruleset, you need\nto specify them in a `rules` key which is a list of items with the following structure\n`{RuleNamespace, Rule, RuleConfig}`, or `{RuleNamespace, Rule}` - if the rule takes no configuration\nvalues. You can also `disable` certain rules if you want to, by specifying them in the `rules` key\nand passing `disable` as a third argument.\n\n`RuleNamespace` is an Erlang module that implements the `elvis_rule` behaviour.\n`Rule` is a function exported from `RuleNamespace`.\n\n#### Disabling Rules\n\n**IMPORTANT**: `disable` will only work if you also provided a `ruleset` as shown above.\n\nLet's say you like your files to have a maximum of 90 characters per line and you also like to use\ntabs instead of spaces. In that case, you need to override `erl_files`'s `ruleset` pre-defined\n`rules` as follows:\n\n```erlang\n#{\n    files =\u003e [\"src/*.erl\"],\n    rules =\u003e [\n        % change max_line_length from 100 to 90\n        {elvis_text_style, max_line_length, #{limit =\u003e 90}},\n        % disable no_tabs\n        {elvis_text_style, no_tabs, disable}\n    ],\n    ruleset =\u003e erl_files\n}.\n```\n\n#### Ignoring modules\n\nYou can also `ignore` modules at a _check level_ or at a _ruleset (group of checks) level_:\n\n- at a _check level_, you set the `ignore` option in the rule you want to ignore, e.g.:\n\n```erlang\n{elvis_style, no_debug_call, #{ ignore =\u003e [elvis, elvis_utils, \"not_a_module.hrl\"] }}\n```\n\n(we are telling `elvis` to **ignore** the `elvis` and `elvis_utils` modules and the\n`not_a_module.hrl` file (as a string, since it's not a module) when executing the\n`no_debug_call` check. You can also use wildcard patterns: `'_'` in any position matches any\nmodule, function, or arity (e.g. `[{mod, '_'}]` for all functions in a module, `[{'_', fun}]` for a\nfunction in any module).\n\n- at a _ruleset (group of checks) level_, you set the `ignore` option for the group you want to\nignore, e.g.:\n\n```erlang\n#{\n    files =\u003e [\"src/*.erl\"],\n    ruleset =\u003e erl_files,\n    ignore =\u003e [module1, module4, \"path/to/header_file.hrl\"]\n}.\n```\n\nWith this configuration, none of the checks for `erl_files` is applied to `module1`, `module4`,\nor `path/to/header_file.hrl`.\n\n##### `.gitignore`\n\nIn addition to custom ignore rules, `.gitignore` patterns are automatically honored during\nexecution to skip unnecessary paths.\n\n### Formatting\n\nOption `output_format` allows you to configure the output format. Possible values are `colors`,\n`plain` and `parsable`. The latter could be used for automated parsing and has a format very close\nto the one presented by `dialyzer`, like `\u003cfile\u003e:\u003cline\u003e:\u003crule\u003e:\u003cmessage\u003e`:\n\n\u003c!-- markdownlint-disable MD013 --\u003e\n```text\ntest/examples/british_behaviour_spelling.erl:-1:state_record_and_type:This module implements an OTP behavior but is missing a '#state{}' record.\ntest/examples/fail_always_shortcircuit.erl:5:always_shortcircuit:At line 5, column 45, unexpected non-shortcircuiting operator ''or'' was found; prefer 'orelse'.\n```\n\u003c!-- markdownlint-enable MD013 --\u003e\n\nThe default value for the `output_format` option is `colors`.\n\n### Verbosity\n\nIt is possible to tell `elvis_core` to produce a more verbose output, using the `verbose` option.\nThe value provided is a boolean, either `true` or `false`.\n\nThe default value for the `verbose` option is `false`.\n\nOn the other hand, if no output is desired then the value for the `no_output` option should be\n`true`.\n\nThe default value for the `no_output` option is `false`.\n\n### Parallel execution\n\nIn order to speed up the analysis process, you can use the `parallel` option.\n\nIts value indicates how many processes to use at the same time to apply the style rules to all the\nfiles gathered. The provided number should be less than or equal to the available cores, since any\nvalue higher than that won't report any speedup benefits.\n\nThe default value for `parallel` is `1`.\n\n### Warnings-as-errors\n\nThe `warnings_as_errors` parameter determines how the analysis execution influences your system's\nexit code. This is particularly useful for governing build pipelines.\n\n- `true` (default): any detected warning or error will cause the process to fail with a non-zero\nexit code. Use this to enforce strict code quality standards.\n\n- `false`: the analysis will print all findings to the console, but the process will return an exit\ncode of 0. This allows the build to continue even if issues are found.\n\n## Configuration examples\n\nYou can find examples for configuration files in this project's\n[`config`](https://github.com/inaka/elvis_core/tree/HEAD/config) directory.\n\n## Application environment\n\nOptions `output_format`, `verbose`, `no_output`, and `parallel` can also be set as application-level\nenvironment variables, i.e. as they would be found by `application:get_env/2,3`.\n\n## Rules\n\n### Pre-defined rules\n\nA reference to all pre-defined rules (and some other information) implemented in `elvis_core` is in\n[RULES.md](RULES.md).\n\n### User-defined rules\n\nTo implement your own rules, see the [User-defined rules](RULES.md#user-defined-rules) section in\n[RULES.md](RULES.md) for the full interface, APIs, and a complete example.\n\n## Versioning\n\nFrom 5.x, `elvis_core` adheres to [Semantic Versioning](https://semver.org/). All breaking changes\nand upgrade paths for major versions are documented in [MIGRATION.md](MIGRATION.md).\n\n## Contributing and reporting bugs\n\nIf you find any **bugs** or have other **problems** using this library,\n[open an issue](https://github.com/inaka/elvis/issues/new) in this repository (or even a pull\nrequest 😃).\n\n## References\n\nInspired by [HoundCI](https://houndci.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finaka%2Felvis_core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finaka%2Felvis_core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finaka%2Felvis_core/lists"}