Permalink
Browse files

Extract dependency tracking from Digestor

  • Loading branch information...
1 parent 3a0b6c8 commit 889bf198577fd914e2814b9e402b49f972cf9551 @dasch dasch committed Dec 16, 2012
Showing with 73 additions and 44 deletions.
  1. +66 −0 actionpack/lib/action_view/dependency_tracker.rb
  2. +7 −44 actionpack/lib/action_view/digestor.rb
@@ -0,0 +1,66 @@
+module ActionView
+ class DependencyTracker
+ def self.find_dependencies(name, template)
+ ErbTracker.call(name, template)
+ end
+
+ class ErbTracker
+ EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/
+
+ # Matches:
+ # render partial: "comments/comment", collection: commentable.comments
+ # render "comments/comments"
+ # render 'comments/comments'
+ # render('comments/comments')
+ #
+ # render(@topic) => render("topics/topic")
+ # render(topics) => render("topics/topic")
+ # render(message.topics) => render("topics/topic")
+ RENDER_DEPENDENCY = /
+ render\s* # render, followed by optional whitespace
+ \(? # start an optional parenthesis for the render call
+ (partial:|:partial\s+=>)?\s* # naming the partial, used with collection -- 1st capture
+ ([@a-z"'][@a-z_\/\."']+) # the template name itself -- 2nd capture
+ /x
+
+ def self.call(name, template)
+ new(name, template).call
+ end
+
+ def initialize(name, template)
+ @name, @template = name, template
+ end
+
+ def call
+ render_dependencies + explicit_dependencies
+ end
+
+ private
+ attr_reader :name, :template
+
+ def directory
+ name.split("/")[0..-2].join("/")
+ end
+
+ def render_dependencies
+ template.source.scan(RENDER_DEPENDENCY).
+ collect(&:second).uniq.
+
+ # render(@topic) => render("topics/topic")
+ # render(topics) => render("topics/topic")
+ # render(message.topics) => render("topics/topic")
+ collect { |name| name.sub(/\A@?([a-z]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }.
+
+ # render("headline") => render("message/headline")
+ collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }.
+
+ # replace quotes from string renders
+ collect { |name| name.gsub(/["']/, "") }
+ end
+
+ def explicit_dependencies
+ template.source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
+ end
+ end
+ end
+end
@@ -1,25 +1,8 @@
require 'thread_safe'
+require 'action_view/dependency_tracker'
module ActionView
class Digestor
- EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/
-
- # Matches:
- # render partial: "comments/comment", collection: commentable.comments
- # render "comments/comments"
- # render 'comments/comments'
- # render('comments/comments')
- #
- # render(@topic) => render("topics/topic")
- # render(topics) => render("topics/topic")
- # render(message.topics) => render("topics/topic")
- RENDER_DEPENDENCY = /
- render\s* # render, followed by optional whitespace
- \(? # start an optional parenthesis for the render call
- (partial:|:partial\s+=>)?\s* # naming the partial, used with collection -- 1st capture
- ([@a-z"'][@a-z_\/\."']+) # the template name itself -- 2nd capture
- /x
-
cattr_reader(:cache)
@@cache = ThreadSafe::Cache.new
@@ -47,7 +30,7 @@ def digest
end
def dependencies
- render_dependencies + explicit_dependencies
+ DependencyTracker.find_dependencies(name, template)
rescue ActionView::MissingTemplate
[] # File doesn't exist, so no dependencies
end
@@ -69,16 +52,16 @@ def logical_name
name.gsub(%r|/_|, "/")
end
- def directory
- name.split("/")[0..-2].join("/")
- end
-
def partial?
false
end
+ def template
+ @template ||= finder.find(logical_name, [], partial?, formats: [ format ])
+ end
+
def source
- @source ||= finder.find(logical_name, [], partial?, formats: [ format ]).source
+ template.source
end
def dependency_digest
@@ -89,26 +72,6 @@ def dependency_digest
(template_digests + injected_dependencies).join("-")
end
- def render_dependencies
- source.scan(RENDER_DEPENDENCY).
- collect(&:second).uniq.
-
- # render(@topic) => render("topics/topic")
- # render(topics) => render("topics/topic")
- # render(message.topics) => render("topics/topic")
- collect { |name| name.sub(/\A@?([a-z]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }.
-
- # render("headline") => render("message/headline")
- collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }.
-
- # replace quotes from string renders
- collect { |name| name.gsub(/["']/, "") }
- end
-
- def explicit_dependencies
- source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
- end
-
def injected_dependencies
Array.wrap(options[:dependencies])
end

0 comments on commit 889bf19

Please sign in to comment.