Emilio is a fairly opinionated style check for Erlang which looks to promote consistency, readability, and portability between developers.
While Emilio attempts to check a large number of common cases of styles it is by no means exhaustive. Just because Emilio does not report any errors does not mean a particular source file has no style issues. Although hopefully the number of checks that do exist will lead developers to making similar decisions in the uncovered situations. And obivously there can always be more checks added in the future.
$ git clone https://github.com/cloudant-labs/emilio
$ cd emilio/
$ make
This produces a self contained emilio
executable which you can then
place anywhere on your path as desired.
Usage: ./emilio [-h <help>] [-l <list>] [-e <explain>] [-c <config>]
[-i <ignore>] [-j <jobs>] [-f <report_formatter>]
[-C <context>] [-w <whitelist>]
[--debug-stats <debug_stats>] path [path ...]
-h, --help Show this help message
-l, --list List all error codes with a short description
-e, --explain Show explanation for the given error code
-c, --config The config file to use
-i, --ignore Ignore any file path matching the specified glob
-j, --jobs Number of files to process in parallel [default: 4]
-f, --format Set the output format [default: text]
-C, --context Number of contextual lines to display with the text
formatter [default: 0]
-w, --whitelist A CSV file of filename,line,column,code reports to
ignore
--debug-stats Display timing information with the text formatter
path Paths to process, directories are searched recursively
- 1xx - Indentation
- 2xx - Whitespace
- 3xx - Blank Lines
- 4xx - Exports and Imports
- 5xx - Line Length
- 6xx - Anti-Patterns
Code | Good | Bad | Description |
---|---|---|---|
111 | good | bad | Indentation should be a multiple of the configured indentation_count |
112 | good | bad | Indentation should not increase by more than two levels |
120 | good | bad | Indentation should match for corresponding tokens |
121 | good | bad | Indentation should increase one level for clauses |
122 | good | bad | Indentation for when clauses should increase two levels |
123 | good | bad | Indentation for line breaks at operators should increase by two levels |
124 | good | bad | Indentation for line breaks at operators should increase by two levels |
125 | good | bad | Indentation for clause bodies should increase by at least one level |
126 | good | bad | Indentation for expression spans should increase by at least two levels |
127 | good | bad | Clause bodies should be all inline or multiline |
130 | good | bad | Exports should be indented one level |
141 | good | bad | Inline funs as arguments should start on the same line as the call |
142 | good | bad | Inline funs as arguments should end on the last line of the call |
201 | good | bad | Whitespace should not contain tabs |
202 | good | bad | Whitespace should not contain carriage returns |
203 | good | bad | Line endings should not include carriage returns |
204 | good | bad | Whitespace should not contain other non-printable characters |
210 | good | bad | Source files should end with a single newline. |
221 | good | bad | No spaces before commas |
222 | good | bad | Commas should have a trailing space |
223 | good | bad | No spaces before semicolons |
224 | good | bad | No whitespace before dot |
225 | good | bad | Attribute declarations should start in the first column of the line |
230 | good | bad | No spaces after left parenthesis |
231 | good | bad | No spaces before right parenthesis |
240 | good | bad | No spaces after left square brace |
241 | good | bad | No space before right square brace |
242 | good | bad | Pipe operators should have preceding whitespace |
243 | good | bad | Pipe operators should have trailing whitespace |
250 | good | bad | No space after left curly brace |
251 | good | bad | No space before right curly brace |
301 | good | bad | No more than two consecutive blank lines at module level |
302 | good | bad | Functions should be separated by two blank lines |
310 | good | bad | Use zero or one blank lines between function clauses |
311 | good | bad | Use a consistent number of blank lines between function clauses |
401 | good | bad | Only put module and behavior attributes before exports |
402 | good | bad | Do not use imports |
410 | good | bad | Exports should be grouped correctly |
411 | good | bad | Do not use arbitrary groups of exports |
412 | good | bad | Export groups should follow the order of declared behaviors |
413 | good | bad | Order known behavior callbacks consistently |
420 | good | bad | Function definitions should follow the same order as exports |
421 | good | bad | Do not mix private functions with exported functions |
501 | good | bad | Limit source lines to 80 columns |
601 | good | bad | Do not re-use underscore prefixed variable names |
602 | good | bad | Cases should have more than one clause |
To add a new check to emilio you'll need to first implement your check
as a module. The existing emilio_check_*
modules should provide
decent guidance on the implementation. To include the check you should
add the module name to the list in emilio.hrl
so that its executed.
Once your check is implemented you'll then want to add entries in
priv/documentation/
for each error code it generates. Make sure
to follow the existing style for description.md so that the
README.md generation works correctly.
You can exercise Emilio on a number of open source projects easily by runninng:
make check-projects
The list of projects can be found here.