Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wildcard template dependencies. #20904

Merged
merged 1 commit into from Jul 27, 2015

Conversation

@kaspth
Copy link
Member

@kaspth kaspth commented Jul 16, 2015

Fixes #20878.

@kaspth kaspth added the actionview label Jul 16, 2015
@kaspth kaspth self-assigned this Jul 16, 2015
@kaspth kaspth added this to the 5.0.0 milestone Jul 16, 2015
@@ -142,8 +142,20 @@ def add_static_dependency(dependencies, dependency)
end
end

def resolve_directories(wildcard_dependencies)
wildcard_dependencies.map do |dependency|
Dir[ "digestor/#{dependency}" ].map do |file|

This comment has been minimized.

@kaspth

kaspth Jul 16, 2015
Author Member

So this is where the hack is. I can't figure out how to reliably find a way to prefix the dependency path with the correct directory nesting.

Some ideas I've been throwing around:

  • Extend Action View's resolvers to support wildcard lookups (they have the most info about paths and templates and such).
  • Inject a shared prefix path (perhaps as a threaded mattr_accessor)

Either way, the problem is that the prefix is fixed here:

FixtureTemplate.new("digestor/#{partial_name}.#{format}.erb")

Which probably doesn't work the same way as it does outside of tests either.

This comment has been minimized.

@kaspth

kaspth Jul 19, 2015
Author Member

After having looked at this some more, we probably need to give the dependency tracker access to either a view_paths or a lookup_context.
I still don't know enough about either view paths or lookup contexts, to say if this can work out yet. I'll keep investigating.

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch from c479e28 Jul 22, 2015
@kaspth
kaspth reviewed Jul 22, 2015
View changes
railties/test/application/wildcard_dependencies_test.rb Outdated
teardown :teardown_app

test "dependency tracker view_paths are set in initializer" do
assert_equal ActionController::Base.view_paths, ActionView::DependencyTracker.view_paths

This comment has been minimized.

@kaspth

kaspth Jul 22, 2015
Author Member

Best way I could find to test initializer behavior.

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 23, 2015
Member

It is the best way.

This comment has been minimized.

@kaspth

kaspth Jul 23, 2015
Author Member

Rails way is best way™️

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch 2 times, most recently from 0a089c6 to 78a1dae Jul 22, 2015
@kaspth
Copy link
Member Author

@kaspth kaspth commented Jul 22, 2015

@dhh I got something that's working here too, but I still need to add documentation.

I don't know how necessary it is to add a cache to the wildcard lookup. I'll try doing some benchmarking.

@jeremy @rafaelfranca the implementation I've done feels, eh, not so nice to me. Can you review? 😁

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch from 78a1dae to 38358bb Jul 22, 2015
@dhh
Copy link
Member

@dhh dhh commented Jul 23, 2015

Awesome. I do think we'll need a cache, though. Otherwise every time that
template is eval'ed, you have to touch the filesystem. That won't fly.

On Wed, Jul 22, 2015 at 10:35 PM, Kasper Timm Hansen <
notifications@github.com> wrote:

@dhh https://github.com/dhh I got something that's working here too,
but I still need to add documentation.

I don't know how necessary it is to add a cache to the wildcard lookup.
I'll try doing some benchmarking.

@jeremy https://github.com/jeremy @rafaelfranca
https://github.com/rafaelfranca the implementation I've done feels, eh,
not so nice to me. Can you review? [image: 😁]


Reply to this email directly or view it on GitHub
#20904 (comment).

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch 2 times, most recently to f8563c9 Jul 23, 2015
@kaspth
Copy link
Member Author

@kaspth kaspth commented Jul 23, 2015

@dhh I've added a changelog entry, documentation and, most importantly, caching 😁


module ActionView
class DependencyTracker # :nodoc:
@trackers = ThreadSafe::Cache.new

mattr_accessor(:view_paths) { ActionView::PathSet.new }

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 23, 2015
Member

Why does it need its own view paths?

This comment has been minimized.

@kaspth

kaspth Jul 23, 2015
Author Member

The only place I found that I could steal them from was ActionController::Base's, which I can't depend on here. So this is a fallback.

Do you know of another place I could steal paths from? 😄

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 23, 2015
Member

Yeah, I can see that. You are trying to avoid coupling with Action Pack. But is views_paths shared across all controllers or can I override it just for a controller? If that is the case this will not work.

This comment has been minimized.

@kaspth

kaspth Jul 23, 2015
Author Member

Right, I think you can override view_paths. Hm, not sure, how to catch those usages. Can we get a reference to the controller in those cases? If you happen to know that is.

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 23, 2015
Member

I think the view context has a controller reference, but I think the tracker run before the context is created. But worth to investigate.

This comment has been minimized.

@kaspth

kaspth Jul 23, 2015
Author Member

Thanks, I’ll take a look.

Den 23/07/2015 kl. 21.57 skrev Rafael Mendonça França notifications@github.com:

In actionview/lib/action_view/dependency_tracker.rb #20904 (comment):

module ActionView
class DependencyTracker # :nodoc:
@trackers = ThreadSafe::Cache.new

  • mattr_accessor(:view_paths) { ActionView::PathSet.new }
    I think the view context has a controller reference, but I think the tracker run before the context is created. But worth to investigate.


Reply to this email directly or view it on GitHub https://github.com/rails/rails/pull/20904/files#r35364247.

Kasper

This comment has been minimized.

@kaspth

kaspth Jul 24, 2015
Author Member

Good call here, @rafaelfranca. The digestor gets the lookup_context injected through the finder argument, so we can get the view_paths from there.

The only problem, is that we have to add a third argument to the tracker's call method, which other trackers definitely don't support yet. Since I don't know of a reliable way to check how many args a method takes, I've added an option trackers should specify when registering.


wildcards, explicits = dependencies.partition { |dependency| dependency[-1] == '*' }

explicits + resolve_directories(wildcards).flatten.uniq

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 23, 2015
Member

What are you trying to call uniq? The merge of explicits with resolve_directories(wildcards) or just the resolve_directories(wildcards)? Because I think you are calling on the latter.

This comment has been minimized.

@kaspth

kaspth Jul 23, 2015
Author Member

Just on the resolving. You're right there could be overlap between the explicits and wildcard resolved templates. I'll change to uniq the merge 👍

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 23, 2015
Member

you can also moved the flatten to inside the method.

This comment has been minimized.

@kaspth

kaspth Jul 23, 2015
Author Member

Will do 👍

Den 23/07/2015 kl. 21.51 skrev Rafael Mendonça França notifications@github.com:

In actionview/lib/action_view/dependency_tracker.rb #20904 (comment):

     def explicit_dependencies
  •      source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
    
  •      dependencies = source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
    
  •      wildcards, explicits = dependencies.partition { |dependency| dependency[-1] == '*' }
    
  •      explicits + resolve_directories(wildcards).flatten.uniq
    
    you can also moved the flatten to inside the method.


Reply to this email directly or view it on GitHub https://github.com/rails/rails/pull/20904/files#r35363595.

Kasper

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch from f8563c9 to ae703ec Jul 24, 2015
@kaspth
Copy link
Member Author

@kaspth kaspth commented Jul 24, 2015

I'm not sure where we document that custom trackers must support the view_paths argument to be able to use these wildcard dependencies.

@kaspth
Copy link
Member Author

@kaspth kaspth commented Jul 24, 2015

🏃 Travis 🏃

@kaspth kaspth closed this Jul 24, 2015
@kaspth kaspth reopened this Jul 24, 2015
@kaspth
Copy link
Member Author

@kaspth kaspth commented Jul 25, 2015

I've looked at how Haml and Slim register themselves and they both use the ERB tracker. Perhaps the trackers should implement supports_view_paths instead of having it as a configured that's used when registering, then it'll just work for Haml and Slim and possibly others.

I've talked myself into doing that. I'll change it now 👍

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch from ae703ec to 591834d Jul 25, 2015
@kaspth kaspth closed this Jul 25, 2015
@kaspth kaspth reopened this Jul 25, 2015
@dhh
Copy link
Member

@dhh dhh commented Jul 26, 2015

Excellent! @rafaelfranca do you have any comments on the view handler implementation?

@@ -30,7 +32,7 @@ def details_key
end

def find(name, prefixes = [], partial = false, keys = [], options = {})
partial_name = partial ? name.gsub(%r|/([^/]+)$|, '/_\1') : name
partial_name = partial ? name.gsub(%r|/([^/]+)$|, '/_\1') : name # '

This comment has been minimized.

@repinel

repinel Jul 26, 2015
Member

We need this comment?

This comment has been minimized.

@kaspth

kaspth Jul 26, 2015
Author Member

Wups! you're right.

@kaspth kaspth force-pushed the kaspth:wildcard-template-dependencies branch from 591834d to a6509d3 Jul 26, 2015
@rafaelfranca
Copy link
Member

@rafaelfranca rafaelfranca commented Jul 27, 2015

:shipit:

kaspth added a commit that referenced this pull request Jul 27, 2015
Add wildcard template dependencies.
@kaspth kaspth merged commit c5583cd into rails:master Jul 27, 2015
@kaspth kaspth deleted the kaspth:wildcard-template-dependencies branch Jul 27, 2015
@kaspth
Copy link
Member Author

@kaspth kaspth commented Jul 27, 2015

Boom! Thanks everyone 🎉

@dhh
Copy link
Member

@dhh dhh commented Jul 27, 2015

Awesome work, Kasper!

On Mon, Jul 27, 2015 at 8:29 PM, Kasper Timm Hansen <
notifications@github.com> wrote:

Boom! Thanks everyone [image: 🎉]


Reply to this email directly or view it on GitHub
#20904 (comment).

@rafaelfranca rafaelfranca modified the milestones: 5.0.0 [temp], 5.0.0 Dec 30, 2015
@dhh
Copy link
Member

@dhh dhh commented Feb 10, 2016

Found an issue with this in deployment. The dependency tree generated by the wildcards is not deterministic. I think the directory scan returns results in an unordered fashion. This means each server generates a unique digest for the same wildcard dependency declaration. Which means that the caching doesn't work. I remember we used to have this problem with Sprockets as well. @kaspth can you investigate?

@kaspth
Copy link
Member Author

@kaspth kaspth commented Feb 10, 2016

@dhh yup, will do 👍


if tracker.present?
tracker.call(name, template)
if tracker.respond_to?(:supports_view_paths?) && tracker.supports_view_paths?

This comment has been minimized.

@eduardoschneiders

eduardoschneiders Feb 10, 2016

Isn't it better to do something like this here?

if tracker.try(:supports_view_paths?)

This comment has been minimized.

@kaspth

kaspth Feb 10, 2016
Author Member

We don't use try internally :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants
You can’t perform that action at this time.