jammit 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/jammit.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jammit'
3
- s.version = '0.6.0' # Keep version in sync with jammit.rb
4
- s.date = '2010-11-8'
3
+ s.version = '0.6.1' # Keep version in sync with jammit.rb
4
+ s.date = '2011-05-25'
5
5
 
6
6
  s.homepage = "http://documentcloud.github.com/jammit/"
7
7
  s.summary = "Industrial Strength Asset Packaging for Rails"
@@ -20,15 +20,13 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ['lib']
21
21
  s.executables = ['jammit']
22
22
 
23
- s.has_rdoc = true
24
23
  s.extra_rdoc_files = ['README']
25
24
  s.rdoc_options << '--title' << 'Jammit' <<
26
25
  '--exclude' << 'test' <<
27
26
  '--main' << 'README' <<
28
27
  '--all'
29
28
 
30
- s.add_dependency 'yui-compressor', ['>= 0.9.1']
31
- s.add_dependency 'closure-compiler', ['>= 0.1.0']
29
+ s.add_dependency 'yui-compressor', ['>= 0.9.3']
32
30
 
33
31
  s.files = Dir['lib/**/*', 'bin/*', 'rails/*', 'jammit.gemspec', 'LICENSE', 'README']
34
32
  end
data/lib/jammit.rb CHANGED
@@ -4,11 +4,11 @@ $LOAD_PATH.push File.expand_path(File.dirname(__FILE__))
4
4
  # to all of the configuration options.
5
5
  module Jammit
6
6
 
7
- VERSION = "0.6.0"
7
+ VERSION = "0.6.1"
8
8
 
9
9
  ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
10
10
 
11
- ASSET_ROOT = File.expand_path((defined?(Rails) && Rails.root.to_s.length > 0) ? Rails.root : ".") unless defined?(ASSET_ROOT)
11
+ ASSET_ROOT = File.expand_path((defined?(Rails) && Rails.root.to_s.length > 0) ? Rails.root : ENV['RAILS_ROOT'] || ".") unless defined?(ASSET_ROOT)
12
12
 
13
13
  PUBLIC_ROOT = (defined?(Rails) && Rails.public_path.to_s.length > 0) ? Rails.public_path : File.join(ASSET_ROOT, 'public') unless defined?(PUBLIC_ROOT)
14
14
 
@@ -22,7 +22,7 @@ module Jammit
22
22
 
23
23
  DEFAULT_JST_NAMESPACE = "window.JST"
24
24
 
25
- AVAILABLE_COMPRESSORS = [:yui, :closure]
25
+ COMPRESSORS = [:yui, :closure, :uglifier]
26
26
 
27
27
  DEFAULT_COMPRESSOR = :yui
28
28
 
@@ -34,9 +34,10 @@ module Jammit
34
34
  # requested by a browser -- rendering a 404.
35
35
  class PackageNotFound < NameError; end
36
36
 
37
- # Jammit raises a ConfigurationNotFound exception when you try to load the
38
- # configuration of an assets.yml file that doesn't exist.
39
- class ConfigurationNotFound < NameError; end
37
+ # Jammit raises a MissingConfiguration exception when you try to load the
38
+ # configuration of an assets.yml file that doesn't exist, or are missing
39
+ # a piece of required configuration.
40
+ class MissingConfiguration < NameError; end
40
41
 
41
42
  # Jammit raises an OutputNotWritable exception if the output directory for
42
43
  # cached packages is locked.
@@ -46,24 +47,31 @@ module Jammit
46
47
  class DeprecationError < StandardError; end
47
48
 
48
49
  class << self
49
- attr_reader :configuration, :template_function, :template_namespace,
50
- :embed_assets, :package_assets, :compress_assets, :gzip_assets,
51
- :package_path, :mhtml_enabled, :include_jst_script, :config_path,
52
- :javascript_compressor, :compressor_options, :css_compressor_options,
53
- :template_extension, :template_extension_matcher, :allow_debugging
50
+ attr_reader :configuration, :template_function, :template_namespace,
51
+ :embed_assets, :package_assets, :compress_assets, :gzip_assets,
52
+ :package_path, :mhtml_enabled, :include_jst_script, :config_path,
53
+ :javascript_compressor, :compressor_options, :css_compressor_options,
54
+ :template_extension, :template_extension_matcher, :allow_debugging
55
+ attr_accessor :compressors
54
56
  end
55
57
 
56
58
  # The minimal required configuration.
57
- @configuration = {}
58
- @package_path = DEFAULT_PACKAGE_PATH
59
+ @configuration = {}
60
+ @package_path = DEFAULT_PACKAGE_PATH
61
+ @compressors = COMPRESSORS
59
62
 
60
63
  # Load the complete asset configuration from the specified @config_path@.
61
64
  # If we're loading softly, don't let missing configuration error out.
62
65
  def self.load_configuration(config_path, soft=false)
63
66
  exists = config_path && File.exists?(config_path)
64
67
  return false if soft && !exists
65
- raise ConfigurationNotFound, "could not find the \"#{config_path}\" configuration file" unless exists
68
+ raise MissingConfiguration, "could not find the \"#{config_path}\" configuration file" unless exists
66
69
  conf = YAML.load(ERB.new(File.read(config_path)).result)
70
+
71
+ # Optionally overwrite configuration based on the environment.
72
+ rails_env = defined?(Rails) ? Rails.env : ENV['RAILS_ENV']
73
+ conf.merge! conf.delete rails_env if conf.has_key? rails_env
74
+
67
75
  @config_path = config_path
68
76
  @configuration = symbolize_keys(conf)
69
77
  @package_path = conf[:package_path] || DEFAULT_PACKAGE_PATH
@@ -81,7 +89,6 @@ module Jammit
81
89
  set_template_extension(conf[:template_extension])
82
90
  symbolize_keys(conf[:stylesheets]) if conf[:stylesheets]
83
91
  symbolize_keys(conf[:javascripts]) if conf[:javascripts]
84
- check_java_version
85
92
  check_for_deprecations
86
93
  self
87
94
  end
@@ -120,7 +127,8 @@ module Jammit
120
127
  :force => false
121
128
  }.merge(options)
122
129
  load_configuration(options[:config_path])
123
- packager.force = options[:force]
130
+ packager.force = options[:force]
131
+ packager.package_names = options[:package_names]
124
132
  packager.precache_all(options[:output_folder], options[:base_url])
125
133
  end
126
134
 
@@ -129,7 +137,7 @@ module Jammit
129
137
  # Ensure that the JavaScript compressor is a valid choice.
130
138
  def self.set_javascript_compressor(value)
131
139
  value = value && value.to_sym
132
- @javascript_compressor = AVAILABLE_COMPRESSORS.include?(value) ? value : DEFAULT_COMPRESSOR
140
+ @javascript_compressor = compressors.include?(value) ? value : DEFAULT_COMPRESSOR
133
141
  end
134
142
 
135
143
  # Turn asset packaging on or off, depending on configuration and environment.
@@ -178,7 +186,9 @@ module Jammit
178
186
 
179
187
  # Jammit 0.5+ no longer supports separate template packages.
180
188
  def self.check_for_deprecations
181
- raise DeprecationError, "Jammit 0.5+ no longer supports separate packages for templates.\nPlease fold your templates into the appropriate 'javascripts' package instead." if @configuration[:templates]
189
+ if @configuration[:templates]
190
+ raise DeprecationError, "Jammit 0.5+ no longer supports separate packages for templates.\nPlease fold your templates into the appropriate 'javascripts' package instead."
191
+ end
182
192
  end
183
193
 
184
194
  def self.warn(message)
@@ -63,6 +63,9 @@ Options:
63
63
  opts.on('-f', '--force', 'force a rebuild of all assets') do |force|
64
64
  @options[:force] = force
65
65
  end
66
+ opts.on('-p', '--packages PACKAGE_NAMES', 'comma-separated list of packages (ex: "core,embed", default: all packages)') do |package_names|
67
+ @options[:package_names] = package_names.split(/,\s*/).map {|n| n.to_sym }
68
+ end
66
69
  opts.on_tail('-v', '--version', 'display Jammit version') do
67
70
  puts "Jammit version #{Jammit::VERSION}"
68
71
  exit
@@ -42,19 +42,21 @@ module Jammit
42
42
  JST_END = "})();"
43
43
 
44
44
  COMPRESSORS = {
45
- :yui => YUI::JavaScriptCompressor,
46
- :closure => Closure::Compiler
45
+ :yui => YUI::JavaScriptCompressor,
46
+ :closure => Jammit.compressors.include?(:closure) ? Closure::Compiler : nil,
47
+ :uglifier => Jammit.compressors.include?(:uglifier) ? Jammit::Uglifier : nil
47
48
  }
48
49
 
49
50
  DEFAULT_OPTIONS = {
50
- :yui => {:munge => true},
51
- :closure => {}
51
+ :yui => {:munge => true},
52
+ :closure => {},
53
+ :uglifier => {:copyright => false}
52
54
  }
53
55
 
54
- # Creating a compressor initializes the internal YUI Compressor from
55
- # the "yui-compressor" gem, or the internal Closure Compiler from the
56
- # "closure-compiler" gem.
56
+ # The css compressor is always the YUI Compressor. JS compression can be
57
+ # provided with YUI Compressor, Google Closure Compiler or UglifyJS.
57
58
  def initialize
59
+ Jammit.check_java_version
58
60
  @css_compressor = YUI::CssCompressor.new(Jammit.css_compressor_options || {})
59
61
  flavor = Jammit.javascript_compressor || Jammit::DEFAULT_COMPRESSOR
60
62
  @options = DEFAULT_OPTIONS[flavor].merge(Jammit.compressor_options || {})
@@ -98,7 +100,7 @@ module Jammit
98
100
  base_path = find_base_path(paths)
99
101
  compiled = paths.map do |path|
100
102
  contents = read_binary_file(path)
101
- contents = contents.gsub(/\n/, '').gsub("'", '\\\\\'')
103
+ contents = contents.gsub(/\r?\n/, "\\n").gsub("'", '\\\\\'')
102
104
  name = template_name(path, base_path)
103
105
  "#{namespace}['#{name}'] = #{Jammit.template_function}('#{contents}');"
104
106
  end
@@ -1,3 +1,5 @@
1
+ require 'action_controller'
2
+
1
3
  module Jammit
2
4
 
3
5
  # The JammitController is added to your Rails application when the Gem is
@@ -7,14 +7,28 @@ require 'base64'
7
7
  require 'pathname'
8
8
  require 'fileutils'
9
9
 
10
- # Gem Dependencies:
10
+ # Include YUI as the default
11
11
  require 'yui/compressor'
12
- require 'closure-compiler'
12
+
13
+ # Try Closure.
14
+ begin
15
+ require 'closure-compiler'
16
+ rescue LoadError
17
+ Jammit.compressors.delete :closure
18
+ end
19
+
20
+ # Try Uglifier.
21
+ begin
22
+ require 'uglifier'
23
+ rescue LoadError
24
+ Jammit.compressors.delete :uglifier
25
+ end
13
26
 
14
27
  # Load initial configuration before the rest of Jammit.
15
28
  Jammit.load_configuration(Jammit::DEFAULT_CONFIG_PATH, true) if defined?(Rails)
16
29
 
17
30
  # Jammit Core:
31
+ require 'jammit/uglifier' if Jammit.compressors.include? :uglifier
18
32
  require 'jammit/compressor'
19
33
  require 'jammit/packager'
20
34
 
data/lib/jammit/jst.js CHANGED
@@ -1 +1 @@
1
- var template = function(str){var fn = new Function('obj', 'var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push(\''+str.replace(/[\r\t\n]/g, " ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');"); return fn;};
1
+ var template = function(str){var fn = new Function('obj', 'var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push(\''+str.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/<%=([\s\S]+?)%>/g,function(match,code){return "',"+code.replace(/\\'/g, "'")+",'";}).replace(/<%([\s\S]+?)%>/g,function(match,code){return "');"+code.replace(/\\'/g, "'").replace(/[\r\n\t]/g,' ')+"__p.push('";}).replace(/\r/g,'\\r').replace(/\n/g,'\\n').replace(/\t/g,'\\t')+"');}return __p.join('');");return fn;};
@@ -12,14 +12,15 @@ module Jammit
12
12
 
13
13
  # Set force to false to allow packages to only be rebuilt when their source
14
14
  # files have changed since the last time their package was built.
15
- attr_accessor :force
15
+ attr_accessor :force, :package_names
16
16
 
17
17
  # Creating a new Packager will rebuild the list of assets from the
18
18
  # Jammit.configuration. When assets.yml is being changed on the fly,
19
19
  # create a new Packager.
20
20
  def initialize
21
- @compressor = Compressor.new
22
- @force = false
21
+ @compressor = Compressor.new
22
+ @force = false
23
+ @package_names = nil
23
24
  @config = {
24
25
  :css => (Jammit.configuration[:stylesheets] || {}),
25
26
  :js => (Jammit.configuration[:javascripts] || {})
@@ -42,8 +43,9 @@ module Jammit
42
43
  cache(p, 'css', pack_stylesheets(p), output_dir)
43
44
  if Jammit.embed_assets
44
45
  cache(p, 'css', pack_stylesheets(p, :datauri), output_dir, :datauri)
45
- if Jammit.mhtml_enabled && base_url
46
- mtime = Time.now
46
+ if Jammit.mhtml_enabled
47
+ raise MissingConfiguration, "A --base-url option is required in order to generate MHTML." unless base_url
48
+ mtime = latest_mtime package_for(p, :css)[:paths]
47
49
  asset_url = "#{base_url}#{Jammit.asset_url(p, :css, :mhtml, mtime)}"
48
50
  cache(p, 'css', pack_stylesheets(p, :mhtml, asset_url), output_dir, :mhtml, mtime)
49
51
  end
@@ -54,9 +56,10 @@ module Jammit
54
56
  # Caches a single prebuilt asset package and gzips it at the highest
55
57
  # compression level. Ensures that the modification time of both both
56
58
  # variants is identical, for web server caching modules, as well as MHTML.
57
- def cache(package, extension, contents, output_dir, suffix=nil, mtime=Time.now)
59
+ def cache(package, extension, contents, output_dir, suffix=nil, mtime=nil)
58
60
  FileUtils.mkdir_p(output_dir) unless File.exists?(output_dir)
59
61
  raise OutputNotWritable, "Jammit doesn't have permission to write to \"#{output_dir}\"" unless File.writable?(output_dir)
62
+ mtime ||= latest_mtime package_for(package, extension.to_sym)[:paths]
60
63
  files = []
61
64
  files << file_name = File.join(output_dir, Jammit.filename(package, extension, suffix))
62
65
  File.open(file_name, 'wb+') {|f| f.write(contents) }
@@ -104,14 +107,21 @@ module Jammit
104
107
  Jammit.warn("No assets match '#{glob}'") if paths.empty?
105
108
  paths
106
109
  end
110
+
111
+ # Get the latest mtime of a list of files (plus the config path).
112
+ def latest_mtime(paths)
113
+ paths += [Jammit.config_path]
114
+ paths.map {|p| File.mtime(p) }.max || Time.now
115
+ end
107
116
 
108
117
  # Return a list of all of the packages that should be cached. If "force" is
109
118
  # true, this is all of them -- otherwise only the packages that are missing
110
119
  # or whose source files have changed since the last package build.
111
120
  def cacheable(extension, output_dir)
112
121
  names = @packages[extension].keys
113
- return names if @force
122
+ names = names.select {|n| @package_names.include? n } if @package_names
114
123
  config_mtime = File.mtime(Jammit.config_path)
124
+ return names if @force
115
125
  return names.select do |name|
116
126
  pack = package_for(name, extension)
117
127
  cached = [Jammit.filename(name, extension)]
@@ -0,0 +1,3 @@
1
+ class Jammit::Uglifier < ::Uglifier
2
+ alias :compress :compile
3
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jammit
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 0
10
- version: 0.6.0
9
+ - 1
10
+ version: 0.6.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Ashkenas
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-08 00:00:00 -05:00
19
- default_executable:
18
+ date: 2011-05-25 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: yui-compressor
@@ -26,30 +25,14 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 57
28
+ hash: 61
30
29
  segments:
31
30
  - 0
32
31
  - 9
33
- - 1
34
- version: 0.9.1
32
+ - 3
33
+ version: 0.9.3
35
34
  type: :runtime
36
35
  version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: closure-compiler
39
- prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 27
46
- segments:
47
- - 0
48
- - 1
49
- - 0
50
- version: 0.1.0
51
- type: :runtime
52
- version_requirements: *id002
53
36
  description: " Jammit is an industrial strength asset packaging library for Rails,\n providing both the CSS and JavaScript concatenation and compression that\n you'd expect, as well as YUI Compressor and Closure Compiler compatibility,\n ahead-of-time gzipping, built-in JavaScript template support, and optional\n Data-URI / MHTML image embedding.\n"
54
37
  email: jeremy@documentcloud.org
55
38
  executables:
@@ -68,13 +51,13 @@ files:
68
51
  - lib/jammit/packager.rb
69
52
  - lib/jammit/railtie.rb
70
53
  - lib/jammit/routes.rb
54
+ - lib/jammit/uglifier.rb
71
55
  - lib/jammit.rb
72
56
  - bin/jammit
73
57
  - rails/routes.rb
74
58
  - jammit.gemspec
75
59
  - LICENSE
76
60
  - README
77
- has_rdoc: true
78
61
  homepage: http://documentcloud.github.com/jammit/
79
62
  licenses: []
80
63
 
@@ -110,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
93
  requirements: []
111
94
 
112
95
  rubyforge_project: jammit
113
- rubygems_version: 1.4.2
96
+ rubygems_version: 1.7.2
114
97
  signing_key:
115
98
  specification_version: 3
116
99
  summary: Industrial Strength Asset Packaging for Rails