Lesson 23 / 25

Code Quality: Formatter, Credo, Dialyzer and Types

Keep Elixir code consistent and catch bugs early with static analysis.

Tools for maintainable Elixir

mix format formats code according to the community standard, configured in .formatter.exs, and mix format --check-formatted enforces it in CI. Credo is a static analysis tool that flags consistency issues, refactoring opportunities and likely bugs (mix credo --strict). Dialyzer, usually run through dialyxir (mix dialyzer), uses @spec typespecs and success typing to find type inconsistencies and unreachable code; it reports only what it can prove wrong, so it has no false positives in theory but can miss errors and its messages take practice to read. Elixir is also gaining a built-in gradual, set-theoretic type system: since version 1.17 the compiler performs type inference on patterns and guards and warns about type violations, such as calling a function with a value that can never match, without requiring annotations, with more capabilities arriving release by release. Other useful tools: mix xref for dependency graphs between modules, Sobelow for security scanning of Phoenix apps, ex_doc for documentation and mix_audit for vulnerable dependencies. A typical CI pipeline runs format check, compile with --warnings-as-errors, Credo, tests and Dialyzer.

A CI quality pipeline

Formatting, warnings as errors, static analysis, tests and security checks.

# .github/workflows/ci.yml (steps excerpt, expressed as shell commands)
mix deps.get
mix format --check-formatted
mix compile --warnings-as-errors
mix credo --strict
mix test --warnings-as-errors
mix sobelow --config                 # Phoenix security checks
mix deps.audit                       # from the mix_audit package
mix dialyzer                         # cache the PLT files between CI runs

# typespecs help both Dialyzer and readers:
# @spec place_order(Customer.t(), map()) :: {:ok, Order.t()} | {:error, Ecto.Changeset.t() | atom()}

Spellcheck, grammar check and a proofreader

The formatter is spellcheck for layout, Credo is a grammar checker with style advice, and Dialyzer plus the compiler's type checks are a careful proofreader who points out sentences that cannot possibly make sense.

Quick check: What does Dialyzer use to find bugs?

  • Runtime logs
  • Typespecs and success typing to detect provable type inconsistencies
  • Unit tests
  • Code formatting rules
Answer

Typespecs and success typing to detect provable type inconsistencies — Dialyzer analyses types statically and reports definite contradictions.