Ragex.Analysis.Impact
(Ragex v0.13.0)
View Source
Change impact analysis using graph traversal and metrics.
Predicts the impact of code changes by analyzing:
- Call graph (who calls this function?)
- Betweenness centrality (how critical is this node?)
- PageRank (how important is this node?)
- Complexity metrics (how complex is the code?)
Usage
alias Ragex.Analysis.Impact
# Analyze impact of changing a function
{:ok, analysis} = Impact.analyze_change({:function, MyModule, :process, 2})
# Find tests affected by a change
{:ok, tests} = Impact.find_affected_tests({:function, MyModule, :process, 2})
# Estimate refactoring effort
{:ok, estimate} = Impact.estimate_effort(:rename_function, {:function, MyModule, :old, 2})
# Calculate risk score
{:ok, risk} = Impact.risk_score({:function, MyModule, :critical, 1})
Summary
Functions
Analyzes the impact of changing a function or module.
Estimates the effort required for a refactoring operation.
Finds tests that would be affected by changing a function.
Calculates a risk score for changing a function or module.
Types
@type impact_analysis() :: %{ target: node_ref(), direct_callers: [node_ref()], all_affected: [node_ref()], affected_count: non_neg_integer(), depth: non_neg_integer(), risk_score: float(), importance: float(), recommendations: [String.t()] }
@type node_ref() :: {:module, module()} | {:function, module(), atom(), non_neg_integer()}
@type test_ref() :: {:function, module(), atom(), non_neg_integer()}
Functions
@spec analyze_change( node_ref(), keyword() ) :: {:ok, impact_analysis()} | {:error, term()}
Analyzes the impact of changing a function or module.
Uses graph traversal to find all code that would be affected by changing the target node. Calculates risk scores and provides recommendations.
Parameters
target- Node reference (function or module tuple)opts- Keyword list of options:depth- Maximum traversal depth (default: 5):include_tests- Include test files in analysis (default: true):exclude_modules- List of modules to exclude
Returns
{:ok, impact_analysis}- Impact analysis result{:error, reason}- Error if analysis fails
Examples
{:ok, analysis} = Impact.analyze_change({:function, MyModule, :process, 2})
IO.puts("Functions affected: " <> Integer.to_string(analysis.affected_count))
IO.puts("Risk score: " <> Float.to_string(analysis.risk_score))
@spec estimate_effort(atom(), node_ref(), keyword()) :: {:ok, effort_estimate()} | {:error, term()}
Estimates the effort required for a refactoring operation.
Parameters
operation- Refactoring operation atom:rename_function- Rename a function:rename_module- Rename a module:extract_function- Extract code into new function:inline_function- Inline a function:move_function- Move function to another module:change_signature- Change function signature
target- Target node referenceopts- Additional options for specific operations
Returns
{:ok, effort_estimate}- Effort estimation{:error, reason}- Error if estimation fails
Examples
{:ok, estimate} = Impact.estimate_effort(:rename_function, {:function, MyModule, :old, 2})
IO.puts("Estimated changes: " <> Integer.to_string(estimate.estimated_changes))
IO.puts("Complexity: " <> Atom.to_string(estimate.complexity))
IO.puts("Time: " <> estimate.estimated_time)
Finds tests that would be affected by changing a function.
Traverses the call graph to find test functions that directly or indirectly call the target function.
Parameters
target- Function reference tupleopts- Keyword list of options:depth- Maximum traversal depth (default: 10):test_patterns- Patterns to identify test modules (default: ["Test", "_test"])
Returns
{:ok, [test_ref]}- List of affected test functions{:error, reason}- Error if analysis fails
Examples
{:ok, tests} = Impact.find_affected_tests({:function, MyModule, :process, 2})
IO.puts("Tests affected: " <> Integer.to_string(length(tests)))
@spec risk_score( node_ref(), keyword() ) :: {:ok, risk_analysis()} | {:error, term()}
Calculates a risk score for changing a function or module.
Combines multiple factors:
- Importance (PageRank score)
- Coupling (number of dependencies)
- Complexity (if available from quality metrics)
Parameters
target- Node referenceopts- Keyword list of options:weights- Custom weights for factors (default: equal)
Returns
{:ok, risk_analysis}- Risk analysis with score 0.0-1.0{:error, reason}- Error if scoring fails
Examples
{:ok, risk} = Impact.risk_score({:function, MyModule, :critical, 1})
IO.puts("Overall risk: " <> Float.to_string(risk.overall) <> " (" <> Atom.to_string(risk.level) <> ")")