Skip to content

Instantly share code, notes, and snippets.

@criess
Created May 5, 2021 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save criess/2775bf269d5105d8fa6f0f94b9b9b96f to your computer and use it in GitHub Desktop.
Save criess/2775bf269d5105d8fa6f0f94b9b9b96f to your computer and use it in GitHub Desktop.
analyzes includes between two folders on a rails application
#!/usr/bin/env ruby
#
# script can be run from rails runner like so:
# rails r this_file.rb -- <including_directory_path> <included_directory_path>
#
# for example on a rails concerns setup: rails r thisfile.rb -- app/models app/models/concerns
#
# rubocop is required to parse the code
#
stderr = Logger.new($stderr, :info)
included = Dir.glob(
File.join(Rails.root, ARGV[1], '**', '*.rb')
).map do |x|
replace = Rails.application.config.eager_load_paths.select { |eager| x.match?(/^#{Regexp.escape(eager)}/) }.max
[x, x[replace.size + 1, x.size].split('.').tap(&:pop).join('.').camelize]
end.to_h
require 'rubocop'
tree = Dir.glob(File.join(Rails.root, ARGV[0], '**', '*.rb')).map do |o|
if included[o]
stderr.warn("overlapping sources: #{o}")
next
end
consume = false
includes = []
replace = Rails.application.config.eager_load_paths.select { |eager| o.match?(/^#{Regexp.escape(eager)}/) }.max
path_prefixes = o[replace.size + 1, o.size].split('.').tap(&:pop).join('.').camelize.split('::')
local_module = path_prefixes.pop
RuboCop::ProcessedSource.new(File.read(o), BigDecimal(RbConfig::CONFIG['RUBY_API_VERSION'])).each_token do |t|
consume = false if t.type == :tNL
includes[-1] += t.text if consume
consume = true && includes.push('') if t.type == :tIDENTIFIER && t.text == 'include'
end
data = includes.map do |incl|
found = nil
path_prefixes.inject("#{incl}") do |m, prefix|
lookup = "#{prefix}::#{m}"
found = included.find { |k, l| l == lookup }
break if found
lookup
end
[incl, Hash[*found || included.find { |k, l| l == incl }]]
end.select {|e| e[1].any? }.to_h
[o, data]
end.compact.to_h
puts(tree.to_yaml)
puts(
tree.values.map(&:keys).flatten.inject({}) do |cl, e|
cl[e] ||= 0
cl[e] += 1
cl
end.sort { |p1, p2| p2[1] <=> p1[1] }.to_h.to_yaml
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment