diff --git a/lib/jbuilder/dependency_tracker.rb b/lib/jbuilder/dependency_tracker.rb deleted file mode 100644 index 83c8dbbb..00000000 --- a/lib/jbuilder/dependency_tracker.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'jbuilder/jbuilder' - -dependency_tracker = false - -begin - require 'action_view' - require 'action_view/dependency_tracker' - dependency_tracker = ::ActionView::DependencyTracker -rescue LoadError - begin - require 'cache_digests' - dependency_tracker = ::CacheDigests::DependencyTracker - rescue LoadError - end -end - -if dependency_tracker - class Jbuilder - module DependencyTrackerMethods - # Matches: - # json.partial! "messages/message" - # json.partial!('messages/message') - # - DIRECT_RENDERS = / - \w+\.partial! # json.partial! - \(?\s* # optional parenthesis - (['"])([^'"]+)\1 # quoted value - /x - - # Matches: - # json.partial! partial: "comments/comment" - # json.comments @post.comments, partial: "comments/comment", as: :comment - # json.array! @posts, partial: "posts/post", as: :post - # = render partial: "account" - # - INDIRECT_RENDERS = / - (?::partial\s*=>|partial:) # partial: or :partial => - \s* # optional whitespace - (['"])([^'"]+)\1 # quoted value - /x - - def dependencies - direct_dependencies + indirect_dependencies + explicit_dependencies - end - - private - - def direct_dependencies - source.scan(DIRECT_RENDERS).map(&:second) - end - - def indirect_dependencies - source.scan(INDIRECT_RENDERS).map(&:second) - end - end - end - - ::Jbuilder::DependencyTracker = Class.new(dependency_tracker::ERBTracker) - ::Jbuilder::DependencyTracker.send :include, ::Jbuilder::DependencyTrackerMethods - dependency_tracker.register_tracker :jbuilder, ::Jbuilder::DependencyTracker -end diff --git a/lib/jbuilder/jbuilder_dependency_tracker.rb b/lib/jbuilder/jbuilder_dependency_tracker.rb new file mode 100644 index 00000000..62b6dbf2 --- /dev/null +++ b/lib/jbuilder/jbuilder_dependency_tracker.rb @@ -0,0 +1,73 @@ +class Jbuilder::DependencyTracker + EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/ + + # Matches: + # json.partial! "messages/message" + # json.partial!('messages/message') + # + DIRECT_RENDERS = / + \w+\.partial! # json.partial! + \(?\s* # optional parenthesis + (['"])([^'"]+)\1 # quoted value + /x + + # Matches: + # json.partial! partial: "comments/comment" + # json.comments @post.comments, partial: "comments/comment", as: :comment + # json.array! @posts, partial: "posts/post", as: :post + # = render partial: "account" + # + INDIRECT_RENDERS = / + (?::partial\s*=>|partial:) # partial: or :partial => + \s* # optional whitespace + (['"])([^'"]+)\1 # quoted value + /x + + def self.call(name, template, view_paths = nil) + new(name, template, view_paths).dependencies + end + + def initialize(name, template, view_paths = nil) + @name, @template, @view_paths = name, template, view_paths + end + + def dependencies + direct_dependencies + indirect_dependencies + explicit_dependencies + end + + private + + attr_reader :name, :template + + def direct_dependencies + source.scan(DIRECT_RENDERS).map(&:second) + end + + def indirect_dependencies + source.scan(INDIRECT_RENDERS).map(&:second) + end + + def explicit_dependencies + dependencies = source.scan(EXPLICIT_DEPENDENCY).flatten.uniq + + wildcards, explicits = dependencies.partition { |dependency| dependency.end_with?("/*") } + + (explicits + resolve_directories(wildcards)).uniq + end + + def resolve_directories(wildcard_dependencies) + return [] unless @view_paths + return [] if wildcard_dependencies.empty? + + # Remove trailing "/*" + prefixes = wildcard_dependencies.map { |query| query[0..-3] } + + @view_paths.flat_map(&:all_template_paths).uniq.filter_map { |path| + path.to_s if prefixes.include?(path.prefix) + }.sort + end + + def source + template.source + end +end diff --git a/test/jbuilder_dependency_tracker_test.rb b/test/jbuilder_dependency_tracker_test.rb index d89be37a..df30ea29 100644 --- a/test/jbuilder_dependency_tracker_test.rb +++ b/test/jbuilder_dependency_tracker_test.rb @@ -1,6 +1,5 @@ require 'test_helper' -require 'jbuilder/dependency_tracker' - +require 'jbuilder/jbuilder_dependency_tracker' class FakeTemplate attr_reader :source, :handler