ExDNA (ExDNA v1.5.0)

Copy Markdown View Source

Code duplication detector for Elixir, powered by native AST analysis.

ExDNA understands code structure, not just text. It normalizes variable names, abstracts literals, and compares AST subtrees — so renamed copies and near-miss clones are caught too. Each clone comes with a concrete refactoring suggestion.

Quick start

report = ExDNA.analyze("lib/")
report.clones   #=> [%ExDNA.Detection.Clone{}, ...]
report.stats    #=> %{files_analyzed: 42, total_clones: 3, ...}

Clone types

  • Type I — exact copies (modulo whitespace/comments)
  • Type II — renamed variables and/or changed literals
  • Type III — near-miss clones (similar structure ± edits)

Configuration

Pass options to analyze/1 or configure in .ex_dna.exs:

%{
  min_mass: 30,
  min_occurrences: 3,
  min_similarity: 0.85,
  paths: ["lib/"],
  ignore: ["lib/my_app_web/templates/**"]
}

See the README for the full option reference.

Summary

Functions

Analyze files for code duplication.

Types

path_or_paths()

@type path_or_paths() :: String.t() | [String.t()]

Functions

analyze(path_or_opts \\ [])

@spec analyze(path_or_paths() | keyword()) :: ExDNA.Report.t()

Analyze files for code duplication.

Accepts a path string, a list of path strings, or a keyword list of options.

Options

  • :paths — list of file/directory paths to scan (default: ["lib/"])
  • :min_mass — minimum AST node count for a fragment to be considered (default: 30)
  • :min_occurrences - minimum number of code occurrences to label a clone (default: 2)
  • :min_similarity — similarity threshold 0.0–1.0 (default: 1.0)
  • :ignore — list of glob patterns to exclude
  • :reporters — list of reporter modules (default: [ExDNA.Reporter.Console])

Examples

ExDNA.analyze("lib/")
ExDNA.analyze(["lib/", "test/"])
ExDNA.analyze(paths: ["lib/", "test/"], min_mass: 20)