Ragex.Analysis.Smells
(Ragex v0.11.0)
View Source
Code smell detection using Metastatic.Analysis.Smells.
Provides file and directory-level code smell detection with configurable thresholds, parallel processing, and detailed reporting.
Usage
alias Ragex.Analysis.Smells
# Analyze single file
{:ok, result} = Smells.analyze_file("lib/my_module.ex")
# Analyze with custom thresholds
{:ok, result} = Smells.analyze_file("lib/my_module.ex",
thresholds: %{max_statements: 30, max_nesting: 3})
# Analyze directory
{:ok, results} = Smells.analyze_directory("lib/",
recursive: true,
parallel: true)
# Filter by severity
critical = Smells.filter_by_severity(results, :critical)Detected Smells
- Long function - Too many statements (default threshold: 50)
- Deep nesting - Excessive nesting depth (default threshold: 4)
- Magic numbers - Unexplained numeric literals
- Complex conditionals - Deeply nested boolean operations
- Long parameter list - Too many parameters (default threshold: 5)
Summary
Functions
Analyzes all files in a directory for code smells.
Analyzes a single file for code smells.
Gets default thresholds for smell detection.
Detects code smells in a directory.
Filters smell results by minimum severity level.
Filters results by smell type.
Types
@type directory_result() :: %{ total_files: non_neg_integer(), files_with_smells: non_neg_integer(), total_smells: non_neg_integer(), by_severity: %{required(atom()) => non_neg_integer()}, by_type: %{required(atom()) => non_neg_integer()}, results: [smell_result()], summary: String.t() }
@type location() :: %{ optional(:module) => atom(), optional(:function) => atom(), optional(:arity) => non_neg_integer(), optional(:line) => non_neg_integer(), optional(:formatted) => String.t() }
@type smell_result() :: %{ path: String.t(), language: atom(), has_smells?: boolean(), total_smells: non_neg_integer(), smells: [smell_with_location()], by_severity: %{required(atom()) => non_neg_integer()}, by_type: %{required(atom()) => non_neg_integer()}, summary: String.t(), timestamp: DateTime.t() }
Functions
@spec analyze_directory(path :: String.t(), opts :: keyword()) :: {:ok, directory_result()} | {:error, term()}
Analyzes all files in a directory for code smells.
Options
:recursive- Recursively analyze subdirectories (default: true):thresholds- Map of threshold overrides:parallel- Use parallel processing (default: true):max_concurrency- Maximum concurrent analyses (default: System.schedulers_online()):min_severity- Minimum severity to include (:low,:medium,:high,:critical)
Examples
{:ok, results} = Smells.analyze_directory("lib/",
recursive: true,
parallel: true,
min_severity: :medium)
@spec analyze_file(path :: String.t(), opts :: keyword()) :: {:ok, smell_result()} | {:error, term()}
Analyzes a single file for code smells.
Options
:thresholds- Map of threshold overrides:language- Explicit language (default: auto-detect)
Examples
{:ok, result} = Smells.analyze_file("lib/my_module.ex")
result.has_smells? # => true/false
result.total_smells # => 3
@spec default_thresholds() :: map()
Gets default thresholds for smell detection.
Examples
iex> Ragex.Analysis.Smells.default_thresholds()
%{max_statements: 50, max_nesting: 4, max_parameters: 5, max_cognitive: 15}
Detects code smells in a directory.
Alias for analyze_directory/2. Provided for API consistency with mix tasks.
Examples
{:ok, smells} = Smells.detect_smells("lib/")
@spec filter_by_severity([smell_result()], atom()) :: [smell_result()]
Filters smell results by minimum severity level.
Severity Levels
:low- Include all smells:medium- Include medium, high, and critical:high- Include high and critical only:critical- Include critical only
Examples
critical_smells = Smells.filter_by_severity(results, :critical)
@spec filter_by_type([smell_result()], atom()) :: [smell_result()]
Filters results by smell type.
Examples
magic_numbers = Smells.filter_by_type(results, :magic_number)