upgrade to 2.3.2: render started matching vim-patchmode *.orig files

As of 2.3.2 render started loading vim patch mode files
( '*.erb.orig' instead of '*.erb' ):

How to reproduce: create *.erb.orig files in the appropriate view
directory:

rails 2.3.2 loads:

app/views/articles/new.html.erb.orig

instead of:

app/views/articles/new.html.erb

This is probably because of the way
ActiionView::ReloadableTemplate::ReloadablePath is implemented. The
keys it contains come from the relative path without the extension, so
it gets:

@paths[ 'sessions/logout.html.erb' ] => template # from
login.html.erb

and the same hash value gets overwritten:

@paths[ 'sessions/logout.html.erb' ] => template # from
login.html.erb.orig

The quick hack I made just reverses the file listing
(Dir.glob.sort.reverse), so the *.erb files come after the *.erb.orig
files, and replace those created from .orig files (patch below).

NOTE: The problem appeared in RSpec, which may load templates
differently than production/non rspec/unit test/console - that is why
I changed all 3 Dir.glob instances.

--- reloadable_template.rb.orig 2009-03-18 12:27:45.000000000 +0100
+++ reloadable_template.rb 2009-03-19 18:48:31.109227986 +0100
@@ -69,7 +69,7 @@

         # get all the template filenames from the dir
         def template_files_from_dir(dir)
- Dir.glob(File.join(dir, '*'))
+ Dir.glob(File.join(dir, '*')).sort.reverse
         end
     end

--- template.rb.orig 2009-03-18 12:27:45.000000000 +0100
+++ template.rb 2009-03-19 18:51:29.281239443 +0100
@@ -78,7 +78,7 @@

       private
         def templates_in_path
- (Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/
**")).each do |file|
+ (Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/
**")).sort.reverse.each do |file|
             yield create_template(file) unless File.directory?(file)
           end
         end

Update to my own post:

There are two paths depending on whether you have
config.action_view.cache_template_loading or not.

(Either EagerPath.load! or ReloadablePath.register_template)

EXAMPLE: Given the files:
    views/main/index.html.erb
    views/main/index.html.erb.backup

RESULT: get '/main' renders 'views/main/index.html.erb.backup'

PROBLEM:

In both cases (Eager, ReloadablePath) "@path[path]" is assigned twice,
setting "index.html.erb.backup" as the final template.

This is not relevant for production mode, since you don't usually have
backups of editor files there.

Backup files such as: "index.html.erb~" are handled correctly, BTW -
added to the list, but never used because of unique extension ("erb~").

QUESTION: Why does ActionView consider the *.backup files anyway?

ANSWER: They pass the ActionView::Template.split test:

      elsif valid_extension?(m[1]) # format and extension

The thing is, index.html.erb.orig has 3 extensions m = ['html', 'erb',
'orig'] and m[2] is ignored. Idea: join m[1] and m[2] and return as
extension?

QUESTION: shouldn't both implementations(Eager/Reloadable) be identical,
except for handling _when_ to load the templates?

The differences may cause some problems to come up only in one case
(w/wo caching). E.g. my guess is that broken symbolic links will be
handled differently - ReloadablePath uses File.file?, which returns
false for the broken symlinks that the Dir.glob returns. EagerPath
doesn't seem to check that.

SOLUTION; Only assign a template once, don't clobber the previous value.
This works, because Dir.glob returns a sorted list, where
'index.html.erb' is at the top.

PATCH: The patch becomes trivial now:

--- template.rb.orig 2009-03-18 12:27:45.000000000 +0100
+++ template.rb 2009-03-20 12:15:14.698483807 +0100
@@ -64,7 +64,7 @@
          templates_in_path do |template|
            template.load!
            template.accessible_paths.each do |path|
- @paths[path] = template
+ @paths[path] ||= template #don't clobber previous entry
with *.erb.backup files
            end
          end
          @paths.freeze

--- reloadable_template.rb.orig 2009-03-18 12:27:45.000000000 +0100
+++ reloadable_template.rb 2009-03-20 13:13:43.866482672 +0100
@@ -41,7 +41,7 @@

          def register_template(template)
            template.accessible_paths.each do |path|
- @paths[path] = template
+ @paths[path] ||= template #don't clobber previous entry
with *.erb.backup files
            end
          end

Seems to work fine now. But does this solve/create other problems with
templates and caching?

Hope this helps and possibly prevents some headaches in the future.

czarek wrote: