Class: Woods::Extractors::RailsSourceExtractor

Inherits:
Object
  • Object
show all
Defined in:
lib/woods/extractors/rails_source_extractor.rb

Overview

RailsSourceExtractor indexes selected parts of the Rails framework and key gems for version-specific accuracy.

This enables queries like “what options does has_many support” or “how does Rails implement callbacks” to return accurate answers for the exact versions in use.

Only high-value, frequently-referenced code is indexed to avoid bloat.

Examples:

extractor = RailsSourceExtractor.new
units = extractor.extract_all
# Returns units for ActiveRecord associations, callbacks, etc.

Constant Summary collapse

RAILS_PATHS =

High-value Rails paths to index

{
  'activerecord' => [
    'lib/active_record/associations',
    'lib/active_record/callbacks.rb',
    'lib/active_record/validations',
    'lib/active_record/relation',
    'lib/active_record/querying.rb',
    'lib/active_record/scoping',
    'lib/active_record/transactions.rb',
    'lib/active_record/persistence.rb',
    'lib/active_record/attribute_methods',
    'lib/active_record/enum.rb',
    'lib/active_record/store.rb',
    'lib/active_record/nested_attributes.rb'
  ],
  'actionpack' => [
    'lib/action_controller/metal',
    'lib/action_controller/callbacks.rb',
    'lib/abstract_controller/callbacks.rb',
    'lib/action_controller/rendering.rb',
    'lib/action_controller/redirecting.rb',
    'lib/action_controller/params_wrapper.rb'
  ],
  'activesupport' => [
    'lib/active_support/callbacks.rb',
    'lib/active_support/concern.rb',
    'lib/active_support/configurable.rb',
    'lib/active_support/core_ext/module/delegation.rb',
    'lib/active_support/core_ext/object/inclusion.rb'
  ],
  'activejob' => [
    'lib/active_job/callbacks.rb',
    'lib/active_job/enqueuing.rb',
    'lib/active_job/execution.rb',
    'lib/active_job/exceptions.rb'
  ],
  'actionmailer' => [
    'lib/action_mailer/base.rb',
    'lib/action_mailer/delivery_methods.rb',
    'lib/action_mailer/callbacks.rb'
  ]
}.freeze
GEM_CONFIGS =

Common gems worth indexing (configure based on project)

{
  'devise' => {
    paths: ['lib/devise/models', 'lib/devise/controllers', 'lib/devise/strategies'],
    priority: :high
  },
  'pundit' => {
    paths: ['lib/pundit.rb', 'lib/pundit'],
    priority: :high
  },
  'sidekiq' => {
    paths: ['lib/sidekiq/worker.rb', 'lib/sidekiq/job.rb', 'lib/sidekiq/client.rb'],
    priority: :high
  },
  'activeadmin' => {
    paths: ['lib/active_admin/dsl.rb', 'lib/active_admin/resource_dsl.rb'],
    priority: :medium
  },
  'cancancan' => {
    paths: ['lib/cancan/ability.rb', 'lib/cancan/controller_additions.rb'],
    priority: :high
  },
  'friendly_id' => {
    paths: ['lib/friendly_id'],
    priority: :medium
  },
  'paper_trail' => {
    paths: ['lib/paper_trail/has_paper_trail.rb', 'lib/paper_trail/model_config.rb'],
    priority: :medium
  },
  'aasm' => {
    paths: ['lib/aasm'],
    priority: :high
  },
  'phlex' => {
    paths: ['lib/phlex'],
    priority: :high
  },
  'dry-monads' => {
    paths: ['lib/dry/monads'],
    priority: :medium
  }
}.freeze

Instance Method Summary collapse

Constructor Details

#initializeRailsSourceExtractor

Returns a new instance of RailsSourceExtractor.



110
111
112
113
# File 'lib/woods/extractors/rails_source_extractor.rb', line 110

def initialize
  @rails_version = Rails.version
  @gem_versions = {}
end

Instance Method Details

#extract_allArray<ExtractedUnit>

Extract Rails framework and gem source

Returns:



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/woods/extractors/rails_source_extractor.rb', line 118

def extract_all
  units = []

  # Extract Rails framework sources
  units.concat(extract_rails_sources)

  # Extract configured gem sources
  units.concat(extract_gem_sources)

  units.compact
end

#extract_gem_sourcesObject

Extract gem sources



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/woods/extractors/rails_source_extractor.rb', line 165

def extract_gem_sources
  units = []

  GEM_CONFIGS.each do |gem_name, config|
    gem_path = find_gem_path(gem_name)
    next unless gem_path

    @gem_versions[gem_name] = gem_version(gem_name)

    config[:paths].each do |relative_path|
      full_path = gem_path.join(relative_path)

      if full_path.directory?
        Dir[full_path.join('**/*.rb')].each do |file|
          unit = extract_gem_file(gem_name, config[:priority], file)
          units << unit if unit
        end
      elsif full_path.exist?
        unit = extract_gem_file(gem_name, config[:priority], full_path.to_s)
        units << unit if unit
      end
    end
  end

  units
end

#extract_rails_sourcesObject

Extract only Rails framework sources



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/woods/extractors/rails_source_extractor.rb', line 135

def extract_rails_sources
  units = []

  RAILS_PATHS.each do |gem_name, paths|
    gem_path = find_gem_path(gem_name)
    next unless gem_path

    paths.each do |relative_path|
      full_path = gem_path.join(relative_path)

      if full_path.directory?
        Dir[full_path.join('**/*.rb')].each do |file|
          unit = extract_framework_file(gem_name, file)
          units << unit if unit
        end
      elsif full_path.exist?
        unit = extract_framework_file(gem_name, full_path.to_s)
        units << unit if unit
      end
    end
  end

  units
end