Code Monkey home page Code Monkey logo

elvis's Introduction

elvis CI

Elvis Presley dancing

elvis, the Erlang style reviewer, is the command-line interface for elvis_core.

What is elvis?

elvis is an Erlang generic style reviewer that focuses on code and configuration consistency, as well as readability, across your whole code base. By the very nature of the rules applied from elvis_core it can also be considered a learning tool, by trying to generalize good practices and allowing teams to adapt it to their own specific needs, while fostering discussions around code conventions.

Advantages of using it

Some of the advantages of using elvis are:

  • enabling consistency in style across all your code base
  • encouraging the development team to sit down and talk about code conventions
  • allowing continuous monitoring of code quality
  • helping developers avoid repeated mistakes that can be automatically detected
  • providing homogenisation among different projects in a company, therefore facilitating project switching for developers, as well as allowing easier code sharing between projects
  • learning, since some of the conventions it proposes are themselves the distilled result of working in very large code bases

Installation

To use elvis as a standalone tool, you need to:

git clone https://github.com/inaka/elvis
cd elvis
rebar3 escriptize
export PATH=${PWD}/_build/default/bin:${PATH}

(to make the env. variable export more permanent add it to your shell's configuration file, i.e. .bashrc, .zshrc, ...)

Now run it by calling elvis (or elvis help), and you should get to the Usage: elvis instructions.

Usage

The most common use case is to cd into a folder containing an elvis.config file and executing elvis rock.

If you just execute elvis with no arguments or options you'll get to the usage instructions outlined in this README.

Options

While you can get a more complete list of options by executing elvis help, we try to keep them documented below.

--code-path <dir> (-p <dir>)

Adds <dir> to the analysis' code path.

--commands

Outputs the list of commands under stood by elvis.

git-branch <branch | commit>

Executes elvis on source files that have changed since <branch> or <commit>.

git-hook

Executes elvis (with the specific configuration file) on the pre-commit hook Git-staged files.

install git-hook

Installs elvis in your current Git repository, as a pre-commit hook.

rock [file...]

Executes elvis analysis on identified files. It will, by default, consider all the files in the configuration (i.e. either elvis.config or the path set by option --config).

--config <file> (-c <file>)

Allows providing the path to the config. file (by default elvis.config is assumed).

--help (-h)

Shows help information.

--keep-rocking (-k)

Doesn't stop analysis when erroring out on a file, if given a list of files to analyse.

--output-format <plain | colors | parsable>

Allows controlling the output format of the analysis' results.

The default value is colors.

plain will output results without colors. parsable will allow for consumption by systems (it's less readable for humans).

--parallel <n | auto> (-P <n | auto>)

Allows analyzing files concurrently.

Use n to set the desired number of parallel workers, or auto to have the application choose an appropriate value (based on the number of schedulers).

--quiet (-q)

Allows suppressing all output. The exit code will still be non-0 if there are failing rules.

--verbose (-V)

Allows verbose output.

--version (-v)

Outputs the application's version.

Configuration

elvis is configured via elvis_core's elvis.config as detailed under elvis_core / Configuration.

Rules

A reference of all rules implemented in elvis can be found in elvis_core's RULES.md.

User-defined rules

If you have implemented elvis rule that are in your local repository or in one of your dependencies, you can add these rule to your elvis.config file and tell elvis where to find the .beam that contains the compiled rule using the --code-path option.

For example, if the rule is in one of your dependencies, you can run elvis rock -p deps/elvis_rules/ebin -c elvis.config.

As a Git hook

elvis can be used as a git pre-commit hook using the git-hook command (installable via install git-hook) as:

#!/bin/sh
elvis git-hook

This will have elvis execute on staged files, as per its configuration.

If any rule fails, elvis exits with a non-zero code, which signals to git that the commit shouldn't be made.

Note: your pre-commit hook script should be executable (i.e. by running chmod +x .git/hooks/pre-commit), otherwise git won't be able to execute it.

As a webhook

elvis can be used as a GitHub webhook for pull request (PR) events, by calling the elvis_webhook:event/1 function. This will add a comment in each file and rule that is broken, analyzing only the files associated with the PR.

Since GitHub's API needs a valid username and password to allow the creation of reviews on PRs, parameters github_user and github_password need to be added to elvis's configuration file (mind you that the credentials used must be from an admin. of the repo or someone with permissions for requesting changes to PRs).

The elvis_webhook:event/1 function takes a map containing the keys headers and body, whose values should be the map of headers and the body from the GitHub's event request.

Headers = #{<<"X-GitHub-Event">>, <<"pull_request">>},
Body = <<"{}">>, %% JSON data from GitHub's event.
Request = #{headers => Headers, body => Body},
elvis:webhook(Request).

The extension to the configuration is as follows:

[
  {elvis, [
    {config, [...]},
    %% webhook configuration parameters
    {github_user, "user"},
    {github_password, "password"}
  ]}
].

Documentation

You can generate local documentation with rebar3 ex_doc and then access it with open doc/index.html.

Contributing

elvis is a FOSS application, and as such contributions are welcome. Be sure to read the contributing guide for more detailed information.

License

elvis is licensed under the Apache License, Version 2.0.

Inspiration

elvis got some of its inspiration from HoundCI.

elvis's People

Contributors

amilkr avatar bullno1 avatar define-null avatar elbrujohalcon avatar elfantasma avatar euen avatar f3c0 avatar fenek avatar ferigis avatar guilleiguaran avatar harenson avatar hernanrivasacosta avatar igaray avatar jfacorro avatar johanvikman avatar licenser avatar mzaini30 avatar nomorecoffee avatar onno-vos-dev avatar onnovos avatar paulo-ferraz-oliveira avatar sargun avatar srenatus avatar sztheory avatar technion avatar tjarvstrand avatar tyler-eon avatar waffle-iron avatar waisbrot avatar walrusvision avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elvis's Issues

Indentation Format

Rule

Indent using {N spaces|tabs}

Options
  • Indentation character
  • (if using spaces) number of spaces
Implementation

Check in each line, how much more indented it is against the previous one.

God Modules

Rule

Don't design your system using god modules

Options
  • Max number of exported functions
  • Max number of expressions in the generated code
  • Max number of lines of code
Implementation

The number of exported functions and expressions in generated code can be obtained using beam_lib-related functions
The number of lines of code, maybe too

Elvis can't find header files

With the following repo layout:

.
├── Makefile
├── README.md
├── include
│   └── dcsp.hrl
├── src
│   ├── dcsp.app.src
│   ├── dcsp.erl
│   ├── dcsp_agent.erl
│   ├── dcsp_problem.erl
│   ├── dcsp_problem_logic.erl
│   ├── dcsp_solver.erl
│   ├── dcsp_sup.erl
│   ├── ex1.erl
│   └── nqueens.erl
└── test
    └── dcsp_SUITE.erl

and dcsp.erl (and others) including dcsp.hrl like this (note no leading include/):

-include("dcsp.hrl").

Elvis (commit 647fd5a) can't find dcsp.hrl:

> elvis:rock(#{src_dirs => ["src", "include", "test"], rules => []}).
** exception error: no match of right hand side value {error,{not_found,"dcsp.hrl"}}
     in function  elvis_code:parse_tree/1 (src/elvis_code.erl, line 65)
     in call from elvis_utils:parse_tree/1 (src/elvis_utils.erl, line 56)
     in call from elvis_utils:load_file_data/1 (src/elvis_utils.erl, line 68)
     in call from lists:map/2 (lists.erl, line 1237)
     in call from elvis:rock/1 (src/elvis.erl, line 52)

The repo in question is https://github.com/lavrin/dcsp/.

if

Rule

Don't use if

Missing link in README

There's a link missing in the README.md.

There's also a way to use elvis as a GitHub [webhook][webhooks] for pull request (PR) events by calling the webhook/1 function. This will add a comment for each rule that is broken by a line in the files associated wiith the PR.

Elvis crashes in `erl_parse:abstract/2`

Again with respect to https://github.com/lavrin/dcsp/ after I changed include directives to sidestep #75 Elvis crashes:

> elvis:rock(#{src_dirs => ["src", "include", "test"], rules => []}).
** exception error: no function clause matching erl_parse:abstract(undefined,{5,19}) (erl_parse.yrl, line 935)
     in function  erl_parse:record_fields/1 (erl_parse.yrl, line 792)
     in call from erl_parse:build_typed_attribute/2 (erl_parse.yrl, line 623)
     in call from erl_parse:yeccpars2_483/7 (erl_parse.yrl, line 80)
     in call from erl_parse:yeccpars0/5 (/net/isildur/ldisk/daily_build/17_prebuild_master-opu_o.2014-04-07_20/otp_src_17/bootstrap/lib/parsetools/include/yeccpre.hrl, line 56)
     in call from lists:map/2 (lists.erl, line 1237)
     in call from lists:map/2 (lists.erl, line 1237)
     in call from elvis_code:parse_tree/1 (src/elvis_code.erl, line 68)

Please see this gist for a dbg trace - unfortunately, the trace doesn't tell me much.

Rules wiki page

Create a wiki page listing the rules with their options and samples.

DRY

Rule

don't repeat yourself

Implementation

Find exactly the same code repeated in the same module

Macros in module/function names

Rule

Don't use macros for module or function names

Implementation

check for ?MACROS that translate to an atom and are used in expressions like ?MACRO:something or something:?MACRO

Macro Names

Rule

Macros should be named in ALL_UPPER_CASE

Options

No options

CLI tool

Create an escript that basically runs elvis:rock(…). Use the tool for CLI getopt.

-callback

Rule

use -callback instead of behavior_info/1 for your behavior definitions

Options
  • None

Dynamic Functions

Rule

Don't use dynamic function calling outside of behaviour modules with callbacks

Options
  • Ignore modules

Naming convention

Rule

stick to one convention when naming modules (i.e: prefix_module1 vs module2 vs anotherprefix_module3)

Options
  • Regex with which to validate module names
  • Excluded modules

http://elvis.inakalabs.com doesn't advertise character encoding

My name's Radosław, but the site displays it as RadosÅ‚aw. There's no mention of "encoding" or "charset" in the page source, so the browser-default encoding is used, and that's ISO-8859-2 in my case (I'm from Poland), but the site is in fact in UTF-8. I guess <meta charset='utf-8'> in the head section would suffice.

Code width

Rule

Stick to N chars per line

Options
  • Max line length

master in deps

Rule

in your rebar.config or Erlang.mk, specify a tag or commit, but not master

Exported vs. Non-exported

Rule

Try to always separate NON-EXPORTED and EXPORTED functions in groups, with the exported ones first, unless it helps readability and code discovery.

Elvis crashes when running on processone/ejabberd

Error message:

escript: exception error: no match of right hand side value
                 {error,{{49,36},
                         aleppo_parser,
                         ["syntax error before: ","..."]}}
  in function  elvis_code:parse_tree/2 (src/elvis_code.erl, line 67)
  in call from elvis_utils:parse_tree/2 (src/elvis_utils.erl, line 57)
  in call from elvis_utils:load_file_data/2 (src/elvis_utils.erl, line 69)
  in call from lists:map/2 (lists.erl, line 1237)
  in call from lists:map/2 (lists.erl, line 1237)
  in call from elvis:rock/1 (src/elvis.erl, line 53)
  in call from elvis:process_commands/2 (src/elvis.erl, line 152)
  in call from elvis:process_options/2 (src/elvis.erl, line 131)

Improve feedback when using Elvis on the command line

For big projects (e.g. erlang/otp, ejabberd), the initial processing of files takes too long and the user is left waiting without any feedback. It would be nice to display information related to what file is being processed before showing the actual output.

Executable Path Length

Rule

Write functions with executable paths no longer than N.

Options
  • N: max length of executable paths.
  • Ignored modules

#state records

Rule

name your state records #state and use -type state():: #state{} in all your OTP modules.

Nesting Level

Rule

Nest your code no more than N levels.

Options
  • Max nesting level

Checkstyle compatible output

How about making the output compatible with the CheckStyle file format? This will allow to run the tool from jenkins and publish the results of the build without any translations

Erlang console tool

Make the system run with

elvis:rock(…)

or something similar (i.e. let it be ready to run from an Erlang console), following these rules:

  • The code to be analysed should be src/*.erl or given as a param
  • The list of rules to validate should be configurable by app.config and only one or two very simple rules (e.g. 80 chars a line) should be implemented
  • The results should be in the simplest possible form
  • Add Tests
  • Write Documentation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.