Class: FiberAudit::Static::Rules::Registry

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/fiber_audit/static/rules/registry.rb

Overview

Registry for managing rule classes.

The registry holds rule classes (not instances) and can instantiate them with the appropriate dependencies for a given configuration.

Usage:

registry = Registry.new(workspace: ws, context_resolver: resolver)
registry.register(BlockingSubprocess)
registry.register(ThreadJoin)

# Find a rule class by ID
rule_class = registry['FA1001']

# Get all enabled rule instances for a configuration
instances = registry.enabled_for(configuration)
instances.each do |rule|
findings = rule.analyze(call_sites: call_sites)
end

Instance Method Summary collapse

Constructor Details

#initialize(workspace: nil, context_resolver: nil) ⇒ Registry

Returns a new instance of Registry.

Parameters:

  • workspace (Object, nil) (defaults to: nil)

    the analysis workspace

  • context_resolver (Object, nil) (defaults to: nil)

    resolves execution contexts



32
33
34
35
36
# File 'lib/fiber_audit/static/rules/registry.rb', line 32

def initialize(workspace: nil, context_resolver: nil)
  @workspace = workspace
  @context_resolver = context_resolver
  @rules = []
end

Instance Method Details

#[](id) ⇒ Class? Also known as: find

Find a rule class by ID (string or symbol).

Parameters:

  • id (String, Symbol)

    the rule identifier

Returns:

  • (Class, nil)

    the rule class, or nil if not found



60
61
62
63
# File 'lib/fiber_audit/static/rules/registry.rb', line 60

def [](id)
  id_str = id.to_s
  @rules.find { |r| r.id == id_str }
end

#each {|rule_class| ... } ⇒ Enumerator

Iterate over registered rule classes.

Yield Parameters:

  • rule_class (Class)

    each registered rule class

Returns:

  • (Enumerator)

    if no block given



79
80
81
# File 'lib/fiber_audit/static/rules/registry.rb', line 79

def each(&)
  @rules.each(&)
end

#enabled_for(configuration) ⇒ Array<Base>

Instantiate all enabled rules for the given configuration.

Filters rules by configuration.rule_enabled?(id) and returns instances initialized with the registry's workspace, context_resolver, and the provided configuration.

Parameters:

Returns:

  • (Array<Base>)

    array of instantiated rule objects



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/fiber_audit/static/rules/registry.rb', line 91

def enabled_for(configuration)
  @rules.filter_map do |rule_class|
    next unless configuration.rule_enabled?(rule_class.id)

    rule_class.new(
      workspace: @workspace,
      context_resolver: @context_resolver,
      configuration: configuration
    )
  end
end

#listArray<Class>

Return all registered rule classes in insertion order.

Returns:

  • (Array<Class>)

    array of rule classes



71
72
73
# File 'lib/fiber_audit/static/rules/registry.rb', line 71

def list
  @rules.dup
end

#register(rule_class) ⇒ self

Register a rule class.

Parameters:

  • rule_class (Class)

    must be a subclass of Base with an id set

Returns:

  • (self)

    for chaining

Raises:

  • (ArgumentError)

    if rule_class is not a Base subclass, has no id, or id is duplicate



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/fiber_audit/static/rules/registry.rb', line 43

def register(rule_class)
  validate_rule_class!(rule_class)

  rule_id = rule_class.id
  if @rules.any? { |r| r.id == rule_id }
    raise ArgumentError,
          "Rule with id '#{rule_id}' is already registered"
  end

  @rules << rule_class
  self
end