0

Previously I was trying to give the Java engine for JavaScript - rhino - a pseudo file system and I have had success (jszip maven plugin)

I now am turning my attention to the SASS compiler

I have integrated JRuby into my Maven plugin and I can call through to the SASS compiler just fine, so now the final step (before the great refactoring from hack-land to maintainable code) is to fake out the paths that JRuby sees,

My feeling is that I will not be able to reuse my Rhino trick (where I remap the java.io.File class adapter in the Rhino scope) as Ruby in general does not have adapter layers to correct for the differences between different Ruby VMs

So my next thought was monkey patch... But I am unsure how big a job that would be...

With JavaScript I just had to fake java.io.File, java.io.FileReader, java.io.FileWriter, java.io.FileInputStream, java.io.FileOutputStream

How much would I need to monkey patch in the Ruby runtime... Or am I better using an ASM based rewriting classloader to pull the rug from under JRuby itself (where I risk breaking legitimate File use to load eg Gems)

Community
  • 1
  • 1
Stephen Connolly
  • 13,872
  • 6
  • 41
  • 63
  • Tcl has had a virtual file system for years, so a little research into how they pulled it off may help; just google: 'tcl vfs' – Dexygen Jan 30 '13 at 18:41
  • I have a virtual file system already (for JavaScript) but here I am trying to integrate *code I didn't write* with that file system. If the code was in java I would use `aspectc` to intercept all the calls to Java's file handling in the 3rd party code jar. Here the code is in ruby, so needs a different method of shimming – Stephen Connolly Jan 30 '13 at 18:45
  • Understood, just trying to give you another angle from which to attack the problem. And I missed the JRuby aspect of your question. – Dexygen Jan 30 '13 at 19:09

1 Answers1

1

An answer to my specific problem with regards to the SASS compiler, but not an answer to the general question of what to do to monkey-patch JRuby to give it a fake file system.

It turns out that Sass has a concept of an Sass::Importer::Base which is the base class for resolving .scss and .sass files. So all I needed to do is create my own implementation which delegates to my virtual file system and configure the options passed to Sass::Engine.new such that the default file-system based importer is replaced with my Importer implementation.

Seems to be working though I have had some issues trying to get it to compile Foundation 3 perhaps due to it relying on Compass which contrasts with the testing experience I had for LESS support, where Bootstrap is stand-alone.

Update

With regard to the ASM based rewriting classloader. Perhaps the trick in that approach is to use AspectC to modify only those classes in the JRuby runtime. In other words, only apply the aspect if the class extends RubyObject. That should retain the legitimate needs of JRuby to load the ruby source code, while giving the embedded VM the fake file system.

With regard to Monkey-patching, it seems there would be a lot of work filling in all the equivalent methods that Ruby's File APIs provide in order to ensure that the monkey patch holds, and especially given that we don't know the exact footprint of what APIs the SASS compiler will use.

So, I guess the full answer is: "You don't want to do either monkey-patching or ASM rewriting as the library you want to use provides a nice abstraction to allow feeding it the virtual filesystem anyway"

Stephen Connolly
  • 13,872
  • 6
  • 41
  • 63