Skip to content

Instantly share code, notes, and snippets.

@jaynetics
Created October 5, 2022 14:40
Show Gist options
  • Select an option

  • Save jaynetics/532a9c697e591b9ee25cd34e47774189 to your computer and use it in GitHub Desktop.

Select an option

Save jaynetics/532a9c697e591b9ee25cd34e47774189 to your computer and use it in GitHub Desktop.
desc 'Finds unused views (i.e. view files not starting with "_"). '\
'May find false positives (programmatically chosen views).'
task find_unused_views: :environment do
UnusedViewFinder.run
end
module UnusedViewFinder
module_function
ALLOWLISTED_PATHS_REGEX = %r{
/debug/
|
/layouts/
}x
def run
result = unused_views
puts '-' * 30, result, '=' * 30, "#{result.size} potentially unused views"
end
def unused_views
view_files.grep_v(ALLOWLISTED_PATHS_REGEX).select(&method(:unused?))
end
def unused?(full_path)
(%r{/app/views/(?<path>.+)/(?<name>[^_.][^/.]*)\.[^/]+\z}x =~ full_path) &&
!view_implicitly_used_in_own_controller?(path, name) &&
!view_explicitly_used_in_any_controller?(path, name)
end
def view_implicitly_used_in_own_controller?(path, name)
name.to_sym.in?(controller_class(path)&.public_instance_methods || [])
end
def view_explicitly_used_in_any_controller?(path, name)
view_explicitly_used_in_own_controller?(path, name) ||
view_explicitly_used_in_other_controller?(path, name)
end
def view_explicitly_used_in_own_controller?(path, name)
regex = /render[^\n]+#{name}/
controller_files.grep(/#{path}/).any? { |cf| regex.match?(File.read(cf)) }
end
def view_explicitly_used_in_other_controller?(path, name)
regex = /render[^\n]+#{[path, name].join(?/)}/
controller_files.any? { |cf| regex.match?(File.read(cf)) }
end
def controller_class(view_path)
dirs = view_path.split(?/)
controller_name = dirs.last.classify.pluralize.gsub(/(Volunteering)s/, '\1')
controller_name.prepend("#{dirs[0..-2] * ?/}/".classify) if dirs.many?
"#{controller_name}Controller".constantize rescue nil
end
def view_files
@v_files ||= Dir[Rails.root.join('app', 'views', '**', '*.html.*')]
end
def controller_files
@c_files ||= Dir[Rails.root.join('app', 'controllers', '**', '*.rb')]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment