Documentation/Buki/Dialyzer/ skills /dialyzer-integration

📖 dialyzer-integration

Use when integrating Dialyzer into development workflows and CI/CD pipelines for Erlang/Elixir projects.



Overview

Integrating Dialyzer into development workflow and CI/CD pipelines.

Local Development

Initial Setup

# Install dialyxir
mix deps.get

# Build initial PLT (takes time first run)
mix dialyzer --plt

# Run analysis
mix dialyzer

Incremental Analysis

# Only analyze changed files
mix dialyzer --incremental

# Force rebuild PLT
mix dialyzer --clean

CI/CD Integration

GitHub Actions

name: Dialyzer

on: [push, pull_request]

jobs:
  dialyzer:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Set up Elixir
        uses: erlef/setup-beam@v1
        with:
          elixir-version: '1.15'
          otp-version: '26'

      - name: Restore dependencies cache
        uses: actions/cache@v3
        with:
          path: deps
          key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}

      - name: Restore PLT cache
        uses: actions/cache@v3
        id: plt-cache
        with:
          path: priv/plts
          key: ${{ runner.os }}-plt-${{ hashFiles('**/mix.lock') }}

      - name: Install dependencies
        run: mix deps.get

      - name: Create PLTs
        if: steps.plt-cache.outputs.cache-hit != 'true'
        run: mix dialyzer --plt

      - name: Run Dialyzer
        run: mix dialyzer --format github

GitLab CI

dialyzer:
  stage: test
  script:
    - mix local.hex --force
    - mix local.rebar --force
    - mix deps.get
    - mix dialyzer
  cache:
    paths:
      - _build/
      - deps/
      - priv/plts/

IDE Integration

VS Code (ElixirLS)

{
  "elixirLS.dialyzerEnabled": true,
  "elixirLS.dialyzerFormat": "dialyxir_long",
  "elixirLS.dialyzerWarnOpts": [
    "error_handling",
    "underspecs",
    "unmatched_returns"
  ]
}

Vim/Neovim (coc-elixir)

{
  "elixir.dialyzer.enabled": true
}

Pre-commit Hooks

Using Husky/Lefthook

# lefthook.yml
pre-commit:
  commands:
    dialyzer:
      glob: "*.ex"
      run: mix dialyzer --incremental

Git Hook Script

#!/bin/sh
# .git/hooks/pre-commit

echo "Running Dialyzer..."
mix dialyzer --incremental --quiet

if [ $? -ne 0 ]; then
  echo "Dialyzer found issues. Commit aborted."
  exit 1
fi

Team Workflow

Shared PLT Strategy

# mix.exs
def project do
  [
    dialyzer: [
      plt_core_path: "priv/plts",
      plt_local_path: "priv/plts",
      plt_add_apps: [:mix, :ex_unit],
      # Shared across team via git
      plt_file: {:no_warn, "priv/plts/project.plt"}
    ]
  ]
end

Baseline Approach

# Generate baseline
mix dialyzer > dialyzer_baseline.txt

# Check for new warnings
mix dialyzer | diff - dialyzer_baseline.txt

Performance Optimization

Parallel Analysis

def project do
  [
    dialyzer: [
      flags: [:error_handling],
      # Use multiple cores
      plt_add_deps: :app_tree
    ]
  ]
end

Selective Analysis

# Only check specific paths
mix dialyzer lib/critical/ test/important_test.exs

Incremental Mode

# Much faster after initial run
mix dialyzer --incremental

Monitoring and Reporting

Custom Formatter

# lib/custom_dialyzer_formatter.ex
defmodule CustomDialyzerFormatter do
  def format(warnings) do
    warnings
    |> Enum.map(&format_warning/1)
    |> Enum.join("\n")
  end

  defp format_warning(warning) do
    # Custom formatting logic
  end
end

Metrics Collection

# Count warnings over time
mix dialyzer | grep -c "warning:" >> dialyzer_metrics.log

Troubleshooting

PLT Issues

# Remove and rebuild
rm -rf _build/dev/*.plt priv/plts/*.plt
mix dialyzer --plt

Memory Issues

# Increase VM memory
elixir --erl "+hms 4096" -S mix dialyzer

Slow Analysis

# Use incremental mode
mix dialyzer --incremental

# Or analyze subset
mix dialyzer lib/core/