• Stars
    star
    61
  • Rank 497,051 (Top 10 %)
  • Language
    Erlang
  • License
    Other
  • Created almost 9 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The core of an Erlang linter

elvis_core

GitHub Actions CI Erlang Support

elvis_core is the core library for the elvis Erlang style reviewer. It is also used by rebar3_lint for easier integration into your Erlang libraries or applications.

It includes the mechanisms to apply rules to your Erlang code, as well as their implementation.

It implements pre-defined rules, but also supports user-defined ones.

Usage

As a library

The elvis command-line tool uses elvis_core extensively, so do check that project for a concrete example on how you could use it for your own purposes.

As a rebar3 plugin

The rebar3_lint plugin eases integration of the style reviewer into your application or library. Be sure to check that out for further information.

From the Erlang shell

After adding elvis_core as a dependency to your project and starting a shell, you will need to make sure the application is started:

1> {ok, _} = application:ensure_all_started(elvis_core).
{ok,[zipper,katana_code,elvis_core]}
2>

Once this is done you can apply the style rules in the following ways.

Loading configuration from a file

1> ElvisConfig = elvis_config:from_file("elvis.config").
<loaded_config>
2> elvis_core:rock(ElvisConfig).
# src/elvis_core.erl [OK]
# src/elvis_result.erl [OK]
# src/elvis_style.erl [OK]
# src/elvis_utils.erl [OK]
ok
3>

This will load the configuration, specified in file elvis.config, from the current directory. If no configuration is found {invalid_config, _} is thrown.

Providing configuration as a value

Another option for using elvis_core from the shell is to explicitly provide the configuration as an argument to elvis_core:rock/1:

1> ElvisConfig = [#{dirs => ["src"], filter => "*.erl", rules => []}].
[#{dirs => ["src"],filter => "*.erl",rules => []}]
2> elvis_core:rock(ElvisConfig).
Loading src/elvis_core.erl
# src/elvis_core.erl [OK]
Loading src/elvis_result.erl
# src/elvis_result.erl [OK]
Loading src/elvis_style.erl
# src/elvis_style.erl [OK]
Loading src/elvis_utils.erl
# src/elvis_utils.erl [OK]
ok
3>

Output for failing rules

We have only presented results where all files were well-behaved (i.e. they respect all the rules), so here's an example of how the output looks when files break some of the rules:

# ../../test/examples/fail_line_length.erl [FAIL]
  - line_length
    - Line 14 is too long: "    io:format(\"This line is 81 characters long and should be detected, yeah!!!\").".
    - Line 20 is too long: "    io:format(\"This line is 90 characters long and should be detected!!!!!!!!!!!!!!!!!!\").".
# ../../test/examples/fail_no_tabs.erl [FAIL]
  - no_tabs
    - Line 6 has a tab at column 0.
    - Line 15 has a tab at column 0.
# ../../test/examples/small.erl [OK]

Configuration

An elvis.config file looks something like this:

[{elvis, [
    {config, [
        #{ dirs    => ["src"]
         , filter  => "*.erl"
         , ruleset => erl_files }
      , #{ dirs    => ["include"]
         , filter  => "*.hrl"
         , ruleset => hrl_files }
      , #{ dirs    => ["."]
         , filter  => "rebar.config"
         , ruleset => rebar_config }
      , #{ dirs    => ["."]
         , filter  => "elvis.config"
         , ruleset => elvis_config }
    ]}
    % output_format (optional): how to format the output.
    % Possible values are 'plain', 'colors' or 'parsable' (default='colors').
  , {output_format, colors}
    % verbose (optional): when 'true' more information will
    % be printed (default=false).
  , {verbose, true}
    % no_output (optional): when 'true' nothing will be printed
    % (default=false).
  , {no_output, false}
    % parallel: determine how many files will be
    % analyzed in parallel (default=1).
  , {parallel, 1}
]}].

Files, rules and rulesets

The dirs key is a list that tells elvis_core where it should look for the files that match filter, which will be run through each of the pre-defined rules in the specified ruleset. filter can contain ** for further matching (it uses filelib:wildcard/1 under the hood).

If you want to override the pre-defined rules, for a given ruleset, you need to specify them in a rules key which is a list of items with the following structure {Module, Function, RuleConfig}, or {Module, Function} - if the rule takes no configuration values. You can also disable certain rules if you want to, by specifying them in the rules key and passing disable as a third parameter.

Disabling Rules

IMPORTANT: disable will only work if you also provided a ruleset as shown above.

Let's say you like your files to have a maximum of 90 characters per line and you also like to use tabs instead of spaces. In that case, you need to override erl_files's ruleset pre-defined rules as follows:

#{ dirs => ["src"]
 , filter => "*.erl"
 , rules => [
       {elvis_text_style, line_length, #{ limit => 90 }} % change line_length from 100 to 90
     , {elvis_text_style, no_tabs, disable} % disable no_tabs
   ]
 , ruleset => erl_files
 }.

Ignoring modules

You can also ignore modules at a check level or at a ruleset (group of checks) level:

  • at a check level, you set the ignore option in the rule you want to ignore, e.g.:
{elvis_style, no_debug_call, #{ ignore => [elvis, elvis_utils] }}

(we are telling elvis to ignore the elvis and elvis_utils modules when executing the no_debug_call check.

  • at a ruleset (group of checks) level, you set the ignore option for the group you want to ignore, e.g.:
#{ dirs => ["src"]
 , filter => "*.erl"
 , ruleset => erl_files
 , ignore => [module1, module4]
}.

With this configuration, none of the checks for erl_files is applied to module1 or module4.

Formatting

Option output_format allows you to configure the output format. Possible values are colors, plain and parsable. The latter could be used for automated parsing and has a format very close to the one presented by dialyzer, like <file>:<line>:<rule>:<message>:

src/example.erl:1:god_modules:This module has too many functions (56). Consider breaking it into a number of modules.
src/example_a.erl:341:no_debug_call:Remove the debug call to io:format/2 on line 341.
src/example_a.erl:511:used_ignored_variable:Ignored variable is being used on line 511 and column 54.
src/example_a.erl:1252:used_ignored_variable:Ignored variable is being used on line 1252 and column 21.

The default value for the output_format option is colors.

Verbosity

It is possible to tell elvis_core to produce a more verbose output, using the verbose option. The value provided is a boolean, either true or false.

The default value for the verbose option is false.

On the other hand, if no output is desired then the value for the no_output option should be true.

The default value for the no_output option is false.

Parallel execution

In order to speed up the analysis process, you can use the parallel option.

Its value indicates how many processes to use at the same time to apply the style rules to all the files gathered. The provided number should be less than or equal to the available cores, since any value higher than that won't report any speedup benefits.

The default value for parallel is 1.

Configuration examples

You can find examples for configuration files in this project's config directory.

Application environment

Options output_format, verbose, no_output, and parallel can also be set as application-level environment variables, i.e. as they would be found by application:get_env/2,3.

Rules

Pre-defined rules

A reference to all pre-defined rules (and some other information) implemented in elvis_core can be found in this repository's RULES.md.

User-defined rules

The implementation of a new rule is a function that takes 3 arguments in the following order:

  1. t:elvis_config:config(): the value of option config as found in the configuration,
  2. t:elvis_file:file(): the file to be analyzed,
  3. t:erlang:map(): a configuration map specific to your user-defined rule.

This means you can define rules of your own (user-defined rules) as long as the functions that implement them respect this interface.

Contributing and reporting bugs

If you find any bugs or have other problems using this library, open an issue in this repository (or even a pull request πŸ˜ƒ).

References

Inspired by HoundCI.

More Repositories

1

erlang_guidelines

Inaka's Erlang Coding Guidelines
Erlang
619
star
2

EventSource

A simple Swift client library for the Server Sent Events (SSE)
Swift
483
star
3

galgo

When you want your logs to be displayed on screen
Java
427
star
4

elvis

Erlang Style Reviewer
Erlang
424
star
5

apns4erl

Apple Push Notification Server for Erlang
Erlang
369
star
6

TinyTask

A Tiny Task Library
Java
324
star
7

worker_pool

Erlang worker pool
Erlang
274
star
8

sumo_db

Erlang Persistency Framework
Erlang
173
star
9

shotgun

For the times you need more than just a gun.
Erlang
166
star
10

Dayron

A repository `similar` to Ecto.Repo that maps to an underlying http client, sending requests to an external rest api instead of a database
Elixir
159
star
11

cowboy_swagger

Swagger integration for Cowboy (built on trails)
Erlang
120
star
12

gold_fever

A Treasure Hunt for Erlangers
Erlang
86
star
13

Jayme

Abstraction layer that eases RESTful interconnections in Swift
Swift
81
star
14

guidelines

General Inaka Guidelines
75
star
15

cowboy-trails

A couple of improvements over Cowboy Routes
Erlang
71
star
16

jem.js

Just Erlang Maps for Javascript
JavaScript
69
star
17

sheldon

Very Simple Erlang Spell Checker
Erlang
62
star
18

niffy

Inline C code in Erlang modules to build NIFs
Erlang
60
star
19

sumo_rest

Generic cowboy handlers to work with Sumo
Erlang
59
star
20

serpents

Multi-Player Game on top of HDP protocol
Erlang
56
star
21

xref_runner

Erlang Xref Runner (inspired in rebar xref)
Erlang
50
star
22

erlang-github

Github API client
Erlang
46
star
23

lasse

SSE handler for Cowboy
Erlang
45
star
24

beam_olympics

Let's find the fastest beamer!
Erlang
39
star
25

fiar

Four in a Row - A game to learn Erlang
Erlang
36
star
26

zipper

Generic Zipper implementation in Erlang
Erlang
34
star
27

ios-xmpp-sample

Blog post sample project.
Swift
33
star
28

kotlillon

Android Kotlin Examples
Kotlin
33
star
29

katana-test

Meta Testing Utilities for common_test
Erlang
32
star
30

match_stream

A sample project to show in our scale blog post
JavaScript
30
star
31

phoenix_passwordless_login

Phoenix Passwordless Login
Elixir
29
star
32

KillerTask

Android AsyncTask wrapper library, written in Kotlin
Kotlin
26
star
33

canillita

Simple Paperboy-themed PubSub
Erlang
26
star
34

lewis

Rock your Android
Java
22
star
35

tirerl

Erlang interface to Elastic Search
Erlang
19
star
36

itweet

Twitter Stream API on ibrowse
Erlang
18
star
37

katana-code

Code Utilities for Erlang
Erlang
17
star
38

pusherman

queuing system for push notifications
Erlang
17
star
39

galgo-ios

When you want your logs to be displayed on screen
Objective-C
16
star
40

lsl

NIM in Erlang
Erlang
15
star
41

credo_server

Credo Server
Elixir
15
star
42

FadeButton

Fading effects for UIButtons made simple
Swift
15
star
43

Jolly

Jolly Chimp that keeps track of our Github Repos
Swift
12
star
44

rpsls

Rock Paper Scissors Lizzard Spock World Championship in Erlang
Erlang
12
star
45

ikbot

An elixir based customizable hipchat bot
Elixir
12
star
46

nconf

Nested Configuration Manager for Erlang Applications
Erlang
12
star
47

pushito

APNS over HTTP/2
Elixir
11
star
48

rest_guidelines

REST API Design Guidelines
11
star
49

fetjaba

From Erlang To Java and Back Again
Erlang
9
star
50

sumo_db_pgsql

PostgreSQL adapter for sumo_db.
Erlang
9
star
51

jinterface_stdlib

Erlang stdlib implementation on Java, based on JInterface
Java
9
star
52

IKCapture

Snapchat-Like Image Capture Library
Objective-C
8
star
53

MediaPickerController

Neat API for presenting the classical action sheet for picking an image or video from the device or camera.
Swift
8
star
54

PictureViewMaster

Interactive image projector.
Swift
8
star
55

toy_kv

A simple and reduced Key-Value Store written in Erlang
Erlang
7
star
56

ColorPicker

Color Picker for Swift
Swift
7
star
57

swift_guidelines

Inaka's Swift Coding Guidelines
7
star
58

spellingci

Spelling CI Server
Erlang
7
star
59

talks

Sources and pdfs of our talks and speeches
TeX
6
star
60

bookmarks

A collection of bookmarks for Inakos
6
star
61

IKJayma

RESTful API abstraction for Server Interconnection
Objective-C
6
star
62

hexer

Hex.pm integration in escript format.
Erlang
6
star
63

hexer.mk

erlang.mk plugin for hexer
Makefile
5
star
64

android_guidelines

Inaka's Android Development Guidelines
5
star
65

elvis.mk

3rd party erlang.mk plug-in for Elvis
Shell
5
star
66

plixir

Poker + Elixir + Phoenix
CSS
5
star
67

ios_guidelines

Inaka's iOS Coding Guidelines
Objective-C
4
star
68

sumo_db_elasticsearch

ElasticSearch adapter for sumo_db
Erlang
4
star
69

tele_sign

Node.js library to send messages through http://www.telesign.com/
JavaScript
4
star
70

inaka.github.io

Inaka's Open Source Projects
HTML
3
star
71

sumo_db_riak

Riak adapter for sumo_db
Erlang
3
star
72

android-excercises

Quick test for Android candidates
3
star
73

sumo_db_mongo

MongoDB adapter for sumo_db
Erlang
2
star
74

Otec

A swift app to showcase our best open-source libraries
Swift
2
star
75

gold_fever-solver

A solver for the http://github.com/inaka/gold_fever game
Erlang
2
star
76

inaka.mk

erlang.mk extras that we generally use in all of our projects
Makefile
2
star
77

g2x

Graffle to XCode
Objective-C
2
star
78

beam_olympics-extended

Internal repo to keep secret beam_olympics tasks from the public view
Erlang
2
star
79

beam_olympics-solver

Solutions for beam_olympics
Elixir
2
star
80

emarkdown

Based on https://github.com/devinus/markdown - but for Erlang :)
C
2
star
81

sumo_db_mysql

MySQL adapter for sumo_db
Erlang
2
star
82

ruby_guidelines

Our own guidelines when it comes to ruby development
1
star
83

pokedex

Dumb repo to prove what we can do with sumo{_db|rest_}
Erlang
1
star
84

homebrew-formulas

Homebrew formulas for some of our tools
Ruby
1
star
85

updike

Run, rabbit, run
1
star
86

ios-scripts

Helper scripts that you can use in your iOS apps
Shell
1
star
87

INSocketListener

SSE Socket Listener for Objective-C
Objective-C
1
star