6

For Konacha, a Rails engine for testing Rails apps, we need a way to find all files that Sprockets can compile to JavaScript.

Right now we use something like

Dir['spec/javascripts/**/*_spec.*']

but this picks up .bak, .orig, and other backup files.

Can Sprockets tell us somehow whether it knows how to compile a file, so that backup files would be automatically excluded?

content_type_of doesn't help:

Rails.application.assets.content_type_of('test/javascripts/foo.js.bak')
=> "application/javascript"
dax
  • 10,779
  • 8
  • 51
  • 86
Jo Liss
  • 30,333
  • 19
  • 121
  • 170

1 Answers1

17

You can iterate through all the files in a Sprockets::Environment's load path using the each_file method:

Rails.application.assets.each_file { |pathname| ... }

The block will be invoked with a Pathname instance for the fully expanded path of each file in the load path.

each_file returns an Enumerator, so you can skip the block and get an array with to_a, or call include? on it. For example, to check whether a file is in the load path:

assets = Rails.application.assets
pathname1 = Pathname.new("test/javascripts/foo.js").expand_path
pathname2 = Pathname.new("test/javascripts/foo.js.bak").expand_path
assets.each_file.include?(pathname1) # => true
assets.each_file.include?(pathname2) # => false
Sam Stephenson
  • 4,392
  • 2
  • 17
  • 7
  • Thanks, Sam! So this will list `.../app/assets/javascripts/foo.js.bak` though, even though `/assets/foo.js` yields 404 (as it should). (And `Rails.application.assets.content_type_of '.../app/assets/javascripts/foo.js.bak'` yields `'application/javascript'`.) That's pretty strange. Is there some other filter I could apply? – Jo Liss Jun 14 '12 at 00:03
  • 1
    I found a solution that seems to work well enough: `(pathname.extname == '.js' || Tilt[pathname])` -- this will pick up all files that either are already JavaScript (hence do not need to be compiled), or can be compiled by Tilt. This notably excludes `.js.bak` files. – Jo Liss Jul 06 '12 at 17:49