why can jruby find require 'susy'
in my compass config.rb, but @import 'susy'
within *.scss files produces the issue:
[java] error Web Content/common/sass/base/foundation_de_DE.scss (Line 9: File to import not found or unreadable: susy.
[java] Load paths:
[java] <removed>/Web Content/common/sass
My existing application wants to start using a responsive design on the front end. However, installing ruby / compass on all the developer's machines, integration environments, performance environments and production would kill the initiative.
per this question, and this simplified tutorial I used our current Ant build.xml to make some targets using jRuby.
gems in a jar trick to so that I don't need to install ruby everywhere: downloaded jruby-complete-1.6.8.jar per latest jruby has relative path issue as of 2013.03.20
java -jar jruby-complete-1.6.8.jar -S gem install -i ./susy susy
jar uf jruby-complete-1.6.8.jar -C susy .
java -jar jruby-complete-1.6.8.jar -S gem list
ant target used during the build process:
<target name="compass.compile">
<java classname="org.jruby.Main" fork="true" failonerror="true" classpathref="jruby.classpath">
<arg line="${basedir}/compile.rb ${basedir} compile ${basedir}"/>
</java>
</target>
ant target used by Eclipse based IDE to 'auto-compile' when a user saves a scss file. Instructions to have Eclipse 'auto-build' scss files (start at step #5)
<target name="compass.dev">
<path id="jruby.classpath">
<fileset dir="../../../release/lib/arch/jruby">
<include name="jruby-complete.jar"/>
</fileset>
</path>
<java classname="org.jruby.Main" fork="true" failonerror="true" classpathref="jruby.classpath">
<arg line="${basedir}/compile.rb ${basedir} compile ${basedir}"/>
</java>
</target>
Finally, here is the 'compile.rb' used by the ant target:
Dir.entries(ARGV[0]).each do |lib|
$LOAD_PATH.unshift "#{ARGV[0]}/#{lib}/lib"
end
require 'rubygems'
require 'compass'
require 'susy'
require 'compass/exec'
exit Compass::Exec::SubCommandUI.new([ARGV[1], ARGV[2], "-q"]).run!
and the config.rb used by compass:
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
require 'susy'
http_path = "./Web Content/"
css_dir = "./Web Content/common/sass-output-css/"
sass_dir = "./Web Content/common/sass/"
add_import_path "./Web Content/sass"
images_dir = "./Web Content/common/images/"
javascripts_dir = "./Web Content/common/js/widgets"
# To enable relative paths to assets via compass helper functions. Uncomment:
#relative_assets = true
and finally, trying to use susy in an scss file:
@import 'reset';
@import 'utilities';
@import 'baseColorVariables';
@import 'font';
@import 'susy';
$total-columns: 12;
$column-width: 4em;
$gutter-width: 1em;
$grid-padding: 1em;
.magic-container { @include container; }
update as of 2013.03.20, this works. but it may not be the cleanest way to get Susy / compass on 'rubyless' machines. does anyone have anything cleaner?
found it. compass is not in the sass load path, nor is susy actually while running under a 'gems in a jar' jruby solution. Thank you Henning Petersen, and your post
specifically:
JRuby has quite a brilliant abstraction from the file-based way of all things Ruby, so most things keep working when packaged into a JAR. A file inside a JAR has a path roughly like this: /path/to/jar/gems.jar!file/in/jar/script.rb. JRuby keeps relative files and everything working when using JARs, with one great BUT: There is no way to do such a thing as a directory listing inside a JAR file. That's right, everything that reads directory listings is now broken.
I altered compass's frameworks.rb (not a fan) so it's directory listing call failure does not stop compass from loading itself into the sass load path:
Compass::Frameworks.discover(:defaults)
Compass::Frameworks.register_directory(File.join(Compass.base_directory, 'frameworks/compass'))
Compass::Frameworks.register_directory(File.join(Compass.base_directory, 'frameworks/blueprint'))
which changes a *.scss auto-compile request to:
Syntax error: File to import not found or unreadable: susy.
Load paths:
<removed>/Web Content/common/sass
file:<removed>/release/lib/arch/jruby/jruby-complete.jar!/gems/compass-0.12.2/frameworks/compass/stylesheets
file:<removed>/release/lib/arch/jruby/jruby-complete.jar!/gems/compass-0.12.2/frameworks/blueprint/stylesheets
ok, now we need to get susy into the load path. adding this line to compass's config.rb
does not work, though I wish it did: add_import_path "../../../release/lib/arch/jruby/jruby-complete.jar!gems/susy-1.0.7/sass"
Henning Petersen also caught this, and it was again because of directory listing calls withing the jruby jar altered compass's configuration/adapters.rb
and Sass's importers/filesystem.rb
. Altering all those files is dirtier to maintain than I am comfortable with, and already the posting is out of date regarding compass && sass.
So I pulled the sass directory out of the jar, which let the compass's add_import_path
work as intended. The cleanest solution I have so far is manually appending to the gem/compass-0.12.2/lib/frameworks.rb
:
Compass::Frameworks.register_directory(File.join(Compass.base_directory, 'frameworks/compass'))
Compass::Frameworks.register_directory(File.join(Compass.base_directory, 'frameworks/blueprint'))
and then adding this line to the compass project's config.rb (whole file provided):
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
require 'susy'
http_path = "./Web Content/"
css_dir = "./Web Content/common/sass-output-css/"
sass_dir = "./Web Content/common/sass/"
add_import_path "./Web Content/susy-1.0.7-read-only"
images_dir = "./Web Content/common/images/"
javascripts_dir = "./Web Content/common/js/widgets"
# To enable relative paths to assets via compass helper functions. Uncomment:
#relative_assets = true
which led to the RAD / eclipse builder scss auto-compile ant target to spit out:
compass.dev:
BUILD SUCCESSFUL
Total time: 16 seconds