3
votes

Does anyone know how to use JRuby and Compass modules to compile SASS (*.scss) files within build.xml?

I'm able to use the Sass::Exec module within sass standalone installation to compile from *.scss to *.css in the following manner:

<!-- Compile SCSS files copied to target folder  -->
<property name="stylesheetFolder" location="myproject/stylesheet"/>
<property name="inputFiles" value="${stylesheetFolder}/[^_]*.scss" />
<echo message="Compiling SCSS files from ${stylesheetFolder}..." />
<script language="ruby" classpath="${env.EP_LIB}/jruby/complete/${jruby-complete.build.jar}">
  <![CDATA[
           require $project.getProperty('env.EP_LIB') + '/sass/sass-3.2.9/lib/sass'
           require 'sass/exec'

           files = Dir.glob($project.getProperty('inputFiles'))
           files.each do |file|
             opts = Sass::Exec::Sass.new(["--style", "compressed", "--load-path", File.dirname(file), file, File.join(File.dirname(file), File.basename(file, ".*") + ".css")])
             opts.parse
           end
  ]]>
</script>
<echo message="Done compiling SCSS source files." />

However, that doesn't give me the power of the Compass framework. I downloaded compass gem as a standalone and I'd like to use one of the Compass Ruby modules to replace the above code in Ant build.xml with something like:

<script language="ruby" classpath="${env.EP_LIB}/jruby/complete/${jruby-complete.build.jar}">
  <![CDATA[
           require $project.getProperty('env.EP_LIB') + '/compass/compass-0.12.2/lib/compass' 
           require 'compass/exec'

           files = Dir.glob($project.getProperty('inputFiles'))
           files.each do |file| 
             opts = Compass::Exec::Compass.new(["--style", "compressed", "--load-path", File.dirname(file), file, File.join(File.dirname(file), File.basename(file, ".*") + ".css")])
             opts.parse
           end
  ]]>
</script>

Has anyone done this successfully?

2
Would it be possible to shell out to the compass command instead of running the Compass library?Shepmaster
It has to run from the Compass library so it's portablen (self-contained) and doesn't require gem installation on each server that the code is deployedpartizan

2 Answers

5
votes

Ok, I got it finally working with a lot of effort and working with out of date documentation. Here is what worked or us:

Bundling gems into an executable jar

  1. Download jruby-complete-1.7.4.jar (working version for me) (from http://jruby.org/files/downloads/1.7.4/)
  2. C:\jruby\complete>java -jar jruby-complete-1.7.4.jar -S gem install -i ./compass compass
  3. C:\jruby\complete>jar uf jruby-complete-1.7.4.jar -C compass .
  4. C:\jruby\complete>java -jar jruby-complete-1.7.4.jar -S gem list
  5. After successfully running the cmd above, your jruby-complete-1.7.4.jar will be modified. Now it should contain the bundled gems (including Compass). This works with other gems that you want to bundle and use in your Compass project as well.

compile.rb

Dir.entries(ARGV[0]).each do |lib|     
    $LOAD_PATH.unshift "#{ARGV[0]}/#{lib}/lib" 
end 

require 'rubygems' 
require 'compass' 
require 'compass/exec' 

command_line_class = Compass::Exec::SubCommandUI.new([ARGV[1], ARGV[2], "-q"]).run!

config.rb

http_path = "/"
css_dir = "."
sass_dir = "."
images_dir = "../images"
javascripts_dir = "../js"

output_style = :compressed
line_comments = false

build.xml

    <path id="jruby.classpath">
        <fileset dir="${env.LIB}/jruby/complete">
            <include name="${jruby-complete.build.jar}"></include>  
        </fileset>
    </path>

    <java fork="true" failonerror="true" classpathref="jruby.classpath" classname="org.jruby.Main">
        <arg line="${stylesheetFolder}/compass/compile.rb ${rubyCompleteFolder}/compass/gems compile ${stylesheetFolder}"></arg>
    </java>  

Here is the supporting documentation that helped me with Compass and Ant integration:

I hope this helps and saves you lots of time :)

0
votes

Here is my solution that supports batch compile of multiple different SASS projects in one single java fork, by searching for multiple config.rb files in your java project (based on this answer: https://stackoverflow.com/a/21051968/6440953):

For each argument representing a different sass project path (containing a config.rb file), run the compile command:

compile.rb

require 'rubygems'
require 'compass'
require 'compass/exec'

ARGV.each do |arg|
  Compass::Exec::SubCommandUI.new(["compile", arg, "--force"]).run!
end

Create a similar config.rb file in all SASS project paths:

config.rb

http_path = "/"
css_dir = "."
sass_dir = "."
images_dir = "../images"
javascripts_dir = "../js"

output_style = :compressed
line_comments = false

Set up path of your ruby-complete jar with compass gem bundled inside (see https://stackoverflow.com/a/21051968/6440953).

Search for all config.rb files in your Java project and concatenate their paths to a property. Send this property as argument line to the java fork performing the SASS compilation.

build.xml

<path id="jruby.classpath">
    <fileset dir="${ext.path}/lib/jruby/complete">
        <include name="jruby-complete*.jar"></include>
    </fileset>
</path>

<macrodef name="sassToCss">
    <sequential>
        <dirset id="configRubyDirSet" dir="${ext.path}\web\webroot\_ui\">
            <present targetdir="${ext.path}\web\webroot\_ui\">
                <mapper type="glob" from="*" to="*/config.rb" />
            </present>
        </dirset>

        <pathconvert property="config.rb.dirs.str" pathsep=" " refid="configRubyDirSet"/>

        <java fork="true" failonerror="true" classpathref="jruby.classpath" classname="org.jruby.Main">
            <arg path="${ext.path}\compile.rb"></arg>
            <arg line="${config.rb.dirs.str}"></arg>
        </java>
    </sequential>
</macrodef>