Class: Guardrails::StimulusAudit

Inherits:
Object
  • Object
show all
Defined in:
lib/guardrails/stimulus_audit.rb

Defined Under Namespace

Classes: Result

Constant Summary collapse

CONTROLLER_BASES =

Stimulus controller files can live under different layouts depending on bundler / app structure:

app/javascript/controllers/*_controller.{js,ts}        (importmap default)
app/javascript/js/controllers/*_controller.{js,ts}     (Avo)
app/javascript/packs/controllers/*_controller.{js,ts}  (older Webpacker)
app/frontend/controllers/*_controller.{js,ts}          (Vite Rails)

Glob from each accepted base; controller-name derivation hinges on the deepest ‘controllers/` segment in the path.

%w[app/javascript app/frontend].freeze
CONTROLLER_GLOB =
"**/*_controller.{js,ts}"
VIEW_PATTERNS =
[
  "app/views/**/*.html.erb",
  "app/components/**/*.html.erb"
].freeze
DATA_CONTROLLER_PATTERN =
/data-controller\s*=\s*["']([^"']+)["']/
RUBY_DATA_CONTROLLER_PATTERN =

Ruby helper syntax: ‘tag.div(data: { controller: “foo” })` or `link_to “x”, url, data: { controller: “foo bar” }`. Allow `=>` rocket syntax too. Capture the string passed as the `controller:` value.

/data:?\s*(?:=>)?\s*\{[^}]*?controller:?\s*(?:=>)?\s*["']([^"']+)["']/m

Instance Method Summary collapse

Constructor Details

#initialize(root:, output: $stdout) ⇒ StimulusAudit

Returns a new instance of StimulusAudit.



39
40
41
42
# File 'lib/guardrails/stimulus_audit.rb', line 39

def initialize(root:, output: $stdout)
  @root = Pathname(root)
  @output = output
end

Instance Method Details

#runObject



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/guardrails/stimulus_audit.rb', line 44

def run
  defined = collect_defined_controllers
  referenced = collect_referenced_controllers

  result = Result.new(
    orphaned: (referenced - defined).sort,
    dead: (defined - referenced).sort
  )

  print_report(result)
  result
end