diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..410e858a --- /dev/null +++ b/Gemfile @@ -0,0 +1,15 @@ +source 'http://rubygems.org' + +gemspec + +group :development, :test do + gem "rake", "0.9.2" + gem "rails", "2.3.11" + gem "yui-compressor", "0.9.3" + gem "closure-compiler", "1.1.5" + gem "uglifier", "0.4.0" +end + +group :development do + gem "RedCloth", "4.2.9" +end diff --git a/LICENSE b/LICENSE index 9644b34c..21987a88 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 Jeremy Ashkenas, DocumentCloud +Copyright (c) 2009-2011 Jeremy Ashkenas, DocumentCloud Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/index.html b/index.html index 5819b511..f386ecb3 100644 --- a/index.html +++ b/index.html @@ -93,7 +93,7 @@
- Current Version: 0.6.3 + Current Version: 0.6.5
@@ -699,6 +699,12 @@
+ 0.6.5 — Nov 30, 2011
+ Added the ability to pass HTML tag options to include_javascripts.
+ Fixed a bug that would always cause JS to be recompiled, regardless of mtimes.
+
0.6.3 — May 26, 2011
Quick bugfix release for Rails 3.1 compatibility, which changes the method
diff --git a/jammit.gemspec b/jammit.gemspec
index 47fd8d9a..23fd32f6 100644
--- a/jammit.gemspec
+++ b/jammit.gemspec
@@ -1,7 +1,7 @@
Gem::Specification.new do |s|
s.name = 'jammit'
- s.version = '0.6.3' # Keep version in sync with jammit.rb
- s.date = Time.now.strftime('%Y-%m-%d')
+ s.version = '0.6.5' # Keep version in sync with jammit.rb
+ s.date = '2011-11-30'
s.homepage = "http://documentcloud.github.com/jammit/"
s.summary = "Industrial Strength Asset Packaging for Rails"
diff --git a/lib/jammit.rb b/lib/jammit.rb
index 7939add2..a0df171b 100644
--- a/lib/jammit.rb
+++ b/lib/jammit.rb
@@ -4,13 +4,13 @@
# to all of the configuration options.
module Jammit
- VERSION = "0.6.3"
+ VERSION = "0.6.5"
ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
ASSET_ROOT = File.expand_path((defined?(Rails) && Rails.root.to_s.length > 0) ? Rails.root : ENV['RAILS_ROOT'] || ".") unless defined?(ASSET_ROOT)
- PUBLIC_ROOT = (defined?(Rails) && Rails.public_path.to_s.length > 0) ? Rails.public_path : File.join(ASSET_ROOT, 'public') unless defined?(PUBLIC_ROOT)
+ DEFAULT_PUBLIC_ROOT = (defined?(Rails) && Rails.public_path.to_s.length > 0) ? Rails.public_path : File.join(ASSET_ROOT, 'public') unless defined?(PUBLIC_ROOT)
DEFAULT_CONFIG_PATH = File.join(ASSET_ROOT, 'config', 'assets.yml')
@@ -26,8 +26,6 @@ module Jammit
DEFAULT_COMPRESSOR = :yui
- RAILS_ENV = (defined?(Rails) ? Rails.env : ENV['RAILS_ENV'] || "development")
-
# Extension matchers for JavaScript and JST, which need to be disambiguated.
JS_EXTENSION = /\.js\Z/
DEFAULT_JST_EXTENSION = "jst"
@@ -37,7 +35,7 @@ module Jammit
class PackageNotFound < NameError; end
# Jammit raises a MissingConfiguration exception when you try to load the
- # configuration of an assets.yml file that doesn't exist, or are missing
+ # configuration of an assets.yml file that doesn't exist, or are missing
# a piece of required configuration.
class MissingConfiguration < NameError; end
@@ -54,12 +52,13 @@ class << self
:package_path, :mhtml_enabled, :include_jst_script, :config_path,
:javascript_compressor, :compressor_options, :css_compressor_options,
:template_extension, :template_extension_matcher, :allow_debugging,
- :rewrite_relative_paths
+ :rewrite_relative_paths, :public_root
attr_accessor :compressors
end
# The minimal required configuration.
@configuration = {}
+ @public_root = DEFAULT_PUBLIC_ROOT
@package_path = DEFAULT_PACKAGE_PATH
@compressors = COMPRESSORS
@@ -72,7 +71,8 @@ def self.load_configuration(config_path, soft=false)
conf = YAML.load(ERB.new(File.read(config_path)).result)
# Optionally overwrite configuration based on the environment.
- conf.merge! conf.delete RAILS_ENV if conf.has_key? RAILS_ENV
+ rails_env = (defined?(Rails) ? ::Rails.env : ENV['RAILS_ENV'] || "development")
+ conf.merge! conf.delete rails_env if conf.has_key? rails_env
@config_path = config_path
@configuration = symbolize_keys(conf)
@@ -90,6 +90,7 @@ def self.load_configuration(config_path, soft=false)
set_template_function(conf[:template_function])
set_template_namespace(conf[:template_namespace])
set_template_extension(conf[:template_extension])
+ set_public_root(conf[:public_root]) if conf[:public_root]
symbolize_keys(conf[:stylesheets]) if conf[:stylesheets]
symbolize_keys(conf[:javascripts]) if conf[:javascripts]
check_for_deprecations
@@ -127,9 +128,11 @@ def self.package!(options={})
:config_path => Jammit::DEFAULT_CONFIG_PATH,
:output_folder => nil,
:base_url => nil,
+ :public_root => nil,
:force => false
}.merge(options)
load_configuration(options[:config_path])
+ set_public_root(options[:public_root]) if options[:public_root]
packager.force = options[:force]
packager.package_names = options[:package_names]
packager.precache_all(options[:output_folder], options[:base_url])
@@ -137,6 +140,12 @@ def self.package!(options={})
private
+ # Allows command-line definition of `PUBLIC_ROOT`, for those using Jammit
+ # outside of Rails.
+ def self.set_public_root(public_root=nil)
+ @public_root = public_root if public_root
+ end
+
# Ensure that the JavaScript compressor is a valid choice.
def self.set_javascript_compressor(value)
value = value && value.to_sym
diff --git a/lib/jammit/command_line.rb b/lib/jammit/command_line.rb
index 36daec6d..07e3ef19 100644
--- a/lib/jammit/command_line.rb
+++ b/lib/jammit/command_line.rb
@@ -66,6 +66,10 @@ def parse_options
opts.on('-p', '--packages LIST', 'list of packages to build (ex: "core,ui", default: all)') do |package_names|
@options[:package_names] = package_names.split(/,\s*/).map {|n| n.to_sym }
end
+ opts.on('-P', '--public-root PATH', 'path to public assets (default: "public")') do |public_root|
+ puts "Option for PUBLIC_ROOT"
+ @options[:public_root] = public_root
+ end
opts.on_tail('-v', '--version', 'display Jammit version') do
puts "Jammit version #{Jammit::VERSION}"
exit
diff --git a/lib/jammit/compressor.rb b/lib/jammit/compressor.rb
index 01348d4b..0854f977 100644
--- a/lib/jammit/compressor.rb
+++ b/lib/jammit/compressor.rb
@@ -187,14 +187,14 @@ def construct_asset_path(asset_path, css_path, variant)
# not be relative, given the path of the stylesheet that contains it.
def absolute_path(asset_pathname, css_pathname)
(asset_pathname.absolute? ?
- Pathname.new(File.join(PUBLIC_ROOT, asset_pathname)) :
+ Pathname.new(File.join(Jammit.public_root, asset_pathname)) :
css_pathname.dirname + asset_pathname).cleanpath
end
# CSS assets that are referenced by relative paths, and are *not* being
# embedded, must be rewritten relative to the newly-merged stylesheet path.
def relative_path(absolute_path)
- File.join('../', absolute_path.sub(PUBLIC_ROOT, ''))
+ File.join('../', absolute_path.sub(Jammit.public_root, ''))
end
# Similar to the AssetTagHelper's method of the same name, this will
@@ -246,7 +246,7 @@ def concatenate(paths)
# `File.read`, but in "binary" mode.
def read_binary_file(path)
- File.open(path, 'rb') {|f| f.read }
+ File.open(path, 'rb:UTF-8') {|f| f.read }
end
end
diff --git a/lib/jammit/controller.rb b/lib/jammit/controller.rb
index 53f65bb2..0ebbd71c 100644
--- a/lib/jammit/controller.rb
+++ b/lib/jammit/controller.rb
@@ -11,7 +11,7 @@ class Controller < ActionController::Base
SUFFIX_STRIPPER = /-(datauri|mhtml)\Z/
- NOT_FOUND_PATH = "#{PUBLIC_ROOT}/404.html"
+ NOT_FOUND_PATH = "#{Jammit.public_root}/404.html"
# The "package" action receives all requests for asset packages that haven't
# yet been cached. The package will be built, cached, and gzipped.
diff --git a/lib/jammit/helper.rb b/lib/jammit/helper.rb
index 727e5a19..530bc1bf 100644
--- a/lib/jammit/helper.rb
+++ b/lib/jammit/helper.rb
@@ -25,10 +25,11 @@ def include_stylesheets(*packages)
# Writes out the URL to the bundled and compressed javascript package,
# except in development, where it references the individual scripts.
def include_javascripts(*packages)
+ options = packages.extract_options!
html_safe packages.map {|pack|
should_package? ? Jammit.asset_url(pack, :js) : Jammit.packager.individual_urls(pack.to_sym, :js)
}.flatten.map {|pack|
- javascript_include_tag pack
+ javascript_include_tag pack, options
}.join("\n")
end
@@ -72,8 +73,8 @@ def embedded_image_stylesheets(packages, options)
# Generate the stylesheet tags for a batch of packages, with options, by
# yielding each package to a block.
def tags_with_options(packages, options)
- packages.dup.map {|package|
- yield package
+ packages.dup.map {|package|
+ yield package
}.flatten.map {|package|
stylesheet_link_tag package, options
}.join("\n")
diff --git a/lib/jammit/packager.rb b/lib/jammit/packager.rb
index acce7a72..4b06f185 100644
--- a/lib/jammit/packager.rb
+++ b/lib/jammit/packager.rb
@@ -6,10 +6,6 @@ module Jammit
# with the correct timestamps.
class Packager
- # In Rails, the difference between a path and an asset URL is "public".
- PATH_DIFF = PUBLIC_ROOT.sub(ASSET_ROOT, '')
- PATH_TO_URL = /\A#{Regexp.escape(ASSET_ROOT)}(\/?#{Regexp.escape(PATH_DIFF)})?/
-
# Set force to false to allow packages to only be rebuilt when their source
# files have changed since the last time their package was built.
attr_accessor :force, :package_names
@@ -37,7 +33,7 @@ def initialize
# Unless forced, will only rebuild assets whose source files have been
# changed since their last package build.
def precache_all(output_dir=nil, base_url=nil)
- output_dir ||= File.join(PUBLIC_ROOT, Jammit.package_path)
+ output_dir ||= File.join(Jammit.public_root, Jammit.package_path)
cacheable(:js, output_dir).each {|p| cache(p, 'js', pack_javascripts(p), output_dir) }
cacheable(:css, output_dir).each do |p|
cache(p, 'css', pack_stylesheets(p), output_dir)
@@ -89,6 +85,7 @@ def pack_javascripts(package)
def pack_templates(package)
@compressor.compile_jst(package_for(package, :js)[:paths])
end
+
private
@@ -107,6 +104,11 @@ def glob_files(glob)
Jammit.warn("No assets match '#{glob}'") if paths.empty?
paths
end
+
+ # In Rails, the difference between a path and an asset URL is "public".
+ def path_to_url
+ @path_to_url ||= /\A#{Regexp.escape(ASSET_ROOT)}(\/?#{Regexp.escape(Jammit.public_root.sub(ASSET_ROOT, ''))})?/
+ end
# Get the latest mtime of a list of files (plus the config path).
def latest_mtime(paths)
@@ -125,8 +127,10 @@ def cacheable(extension, output_dir)
return names.select do |name|
pack = package_for(name, extension)
cached = [Jammit.filename(name, extension)]
- cached.push Jammit.filename(name, extension, :datauri) if Jammit.embed_assets
- cached.push Jammit.filename(name, extension, :mhtml) if Jammit.mhtml_enabled
+ if extension == :css
+ cached.push Jammit.filename(name, extension, :datauri) if Jammit.embed_assets
+ cached.push Jammit.filename(name, extension, :mhtml) if Jammit.mhtml_enabled
+ end
cached.map! {|file| File.join(output_dir, file) }
if cached.any? {|file| !File.exists?(file) }
true
@@ -153,10 +157,10 @@ def create_packages(config)
paths = globs.flatten.uniq.map {|glob| glob_files(glob) }.flatten.uniq
packages[name][:paths] = paths
if !paths.grep(Jammit.template_extension_matcher).empty?
- packages[name][:urls] = paths.grep(JS_EXTENSION).map {|path| path.sub(PATH_TO_URL, '') }
+ packages[name][:urls] = paths.grep(JS_EXTENSION).map {|path| path.sub(path_to_url, '') }
packages[name][:urls] += [Jammit.asset_url(name, Jammit.template_extension)]
else
- packages[name][:urls] = paths.map {|path| path.sub(PATH_TO_URL, '') }
+ packages[name][:urls] = paths.map {|path| path.sub(path_to_url, '') }
end
end
packages
diff --git a/test/config/assets-erb.yml b/test/config/assets-erb.yml
index 2610e6c5..33b5ca08 100644
--- a/test/config/assets-erb.yml
+++ b/test/config/assets-erb.yml
@@ -1,4 +1,4 @@
-embed_assets: <%= RAILS_ENV == 'test' %>
+embed_assets: <%= ENV['RAILS_ENV'] == 'test' %>
javascripts:
js_test:
diff --git a/test/test_helper.rb b/test/test_helper.rb
index be81ae82..b1fe3497 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -5,9 +5,7 @@
ASSET_ROOT = File.expand_path(File.dirname(__FILE__))
devnull = RUBY_PLATFORM =~ /mswin|mingw|bccwin|wince|emx/ ? 'nul' : '/dev/null'
-RAILS_DEFAULT_LOGGER = Logger.new(devnull)
-RAILS_ENV = "test"
-RAILS_ROOT = File.expand_path(File.dirname(__FILE__))
+ENV['RAILS_ENV'] ||= "test"
ENV["RAILS_ASSET_ID"] = "101"
require './lib/jammit'
diff --git a/test/unit/test_configuration.rb b/test/unit/test_configuration.rb
index 088ba0bf..974a1006 100644
--- a/test/unit/test_configuration.rb
+++ b/test/unit/test_configuration.rb
@@ -24,42 +24,42 @@ def test_disabled_compression
@compressor = Compressor.new
# Should not compress js.
packed = @compressor.compress_js(glob('test/fixtures/src/*.js'))
- assert packed == File.read('test/fixtures/jammed/js_test-uncompressed.js')
+ assert_equal packed, File.read('test/fixtures/jammed/js_test-uncompressed.js')
# Nothing should change with jst.
packed = @compressor.compile_jst(glob('test/fixtures/src/*.jst'))
- assert packed == File.read('test/fixtures/jammed/jst_test.js')
+ assert_equal packed, File.read('test/fixtures/jammed/jst_test.js')
packed = @compressor.compress_css(glob('test/fixtures/src/*.css'))
- assert packed == File.open('test/fixtures/jammed/css_test-uncompressed.css', 'rb') {|f| f.read }
+ assert_equal packed, File.open('test/fixtures/jammed/css_test-uncompressed.css', 'rb') {|f| f.read }
end
def test_css_compression
assert Jammit.compress_assets
assert Jammit.gzip_assets
packed = @compressor.compress_css(glob('test/fixtures/src/*.css'))
- assert packed == File.read('test/fixtures/jammed/css_test.css')
+ assert_equal packed, File.read('test/fixtures/jammed/css_test.css')
end
def test_erb_configuration
Jammit.load_configuration('test/config/assets-erb.yml')
assert Jammit.compress_assets
packed = @compressor.compress_css(glob('test/fixtures/src/*.css'))
- assert packed == File.read('test/fixtures/jammed/css_test.css')
+ assert_equal packed, File.read('test/fixtures/jammed/css_test.css')
end
def test_css_configuration
Jammit.load_configuration('test/config/assets-css.yml')
packed = Compressor.new.compress_css(glob('test/fixtures/src/*.css'))
- assert packed == File.read('test/fixtures/jammed/css_test-line-break.css')
+ assert_equal packed, File.read('test/fixtures/jammed/css_test-line-break.css')
end
def test_javascript_compression
packed = @compressor.compress_js(glob('test/fixtures/src/*.js'))
- assert packed == File.read('test/fixtures/jammed/js_test.js')
+ assert_equal packed, File.read('test/fixtures/jammed/js_test.js')
end
def test_jst_compilation
packed = @compressor.compile_jst(glob('test/fixtures/src/*.jst'))
- assert packed == File.read('test/fixtures/jammed/jst_test.js')
+ assert_equal packed, File.read('test/fixtures/jammed/jst_test.js')
end
def test_environment_specific_configuration
diff --git a/test/unit/test_uglifier.rb b/test/unit/test_uglifier.rb
index f19a9b81..61ee4124 100644
--- a/test/unit/test_uglifier.rb
+++ b/test/unit/test_uglifier.rb
@@ -13,7 +13,7 @@ def teardown
def test_javascript_compression
packed = @compressor.compress_js(glob('test/fixtures/src/*.js'))
- assert packed == File.read('test/fixtures/jammed/js_test-uglifier.js')
+ assert_equal packed, File.read('test/fixtures/jammed/js_test-uglifier.js')
end
def test_jst_compilation