Assay.Formatter (assay v0.6.1)

Copy Markdown View Source

Formats Dialyzer warnings into various output formats.

This module converts decorated Dialyzer warning entries into formatted strings suitable for different consumers: humans (text), CI systems (github, sarif), editors (lsp), and LLM/agent tools (json, llm).

Supports multiple formats: :text, :elixir, :github, :json, :sarif, :llm, :markdown, and :marcli. See format/3 for details on each format.

Summary

Functions

Formats decorated Dialyzer warnings into strings for the requested output format.

Functions

format(entries, atom, opts)

@spec format([map()], atom(), keyword()) :: [String.t()]

Formats decorated Dialyzer warnings into strings for the requested output format.

Formats

  • :text - Human-readable text format with code snippets and location information
  • :elixir - Same as :text but with pretty-printed Erlang terms (requires erlex dependency)
  • :github - GitHub Actions workflow annotations (::warning file=...::message) followed by a rich elixir-style text body with code snippets and context
  • :json - JSON objects for machine/RPC consumers (one JSON object per warning)
  • :sarif - SARIF 2.1.0 log (entire log emitted as a single JSON string)
  • :llm - JSON format optimized for LLM consumption (single-line messages, structured data)
  • :markdown - CommonMark Markdown with code snippets and copy-pasteable dialyzer_ignore.exs entries
  • :marcli - Same as :markdown but rendered as ANSI-styled terminal output via Marcli (requires the optional marcli dependency)

Options

  • :project_root (required) - The root directory of the project for resolving relative paths

Examples

iex> entry = %{
...>   text: "Function will never return",
...>   match_text: "Function will never return",
...>   path: "lib/bar.ex",
...>   relative_path: "lib/bar.ex",
...>   line: 5,
...>   column: nil,
...>   code: :warn_not_called
...> }
 iex> [result] = Assay.Formatter.format([entry], :github, project_root: "/project")
 iex> result |> String.split("\n") |> hd() |> String.starts_with?("::warning file=lib/bar.ex,line=5::")
 true

iex> entry = %{
...>   text: "Type mismatch",
...>   match_text: "Type mismatch",
...>   path: "lib/baz.ex",
...>   relative_path: "lib/baz.ex",
...>   line: 10,
...>   column: 5,
...>   code: :warn_matching
...> }
iex> [result] = Assay.Formatter.format([entry], :llm, project_root: "/project")
iex> {:ok, json} = JSON.decode(result)
iex> json["code"]
"warn_matching"
iex> json["line"]
10
iex> json["severity"]
"warning"