Class: Jammit::Packager

Inherits:
Object
  • Object
show all
Defined in:
lib/jammit-core/packager.rb

Overview

The Jammit::Packager resolves the configuration file into lists of real assets that get merged into individual asset packages. Given the compiled contents of an asset package, the Packager knows how to cache that package with the correct timestamps.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePackager

Creating a new Packager will rebuild the list of assets from the Jammit.configuration. When assets.yml is being changed on the fly, create a new Packager.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/jammit-core/packager.rb', line 16

def initialize
  @path_to_url = /\A#{Regexp.escape(Jammit.asset_root)}(\/?public)?/
  @compressor = Compressor.new
  @force = false
  @config = {
    :css => (Jammit.config[:stylesheets] || {}),
    :js  => (Jammit.config[:javascripts] || {}),
    :jst => (Jammit.config[:templates]   || {})
  }
  @packages = {
    :css => create_packages(@config[:css]),
    :js  => create_packages(@config[:js]),
    :jst => create_packages(@config[:jst])
  }  
end

Instance Attribute Details

#forceObject

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.



11
12
13
# File 'lib/jammit-core/packager.rb', line 11

def force
  @force
end

Instance Method Details

#cache(package, extension, contents, output_dir, suffix = nil, mtime = Time.now) ⇒ Object

Caches a single prebuilt asset package and gzips it at the highest compression level. Ensures that the modification time of both both variants is identical, for web server caching modules, as well as MHTML.

Raises:



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/jammit-core/packager.rb', line 65

def cache(package, extension, contents, output_dir, suffix=nil, mtime=Time.now)
  FileUtils.mkdir_p(output_dir) unless File.exists?(output_dir)
  
  raise OutputNotWritable, "Jammit doesn't have permission to write to \"#{output_dir}\"" unless File.writable?(output_dir)
  files = []
  files << file_name = File.join(output_dir, Jammit.filename(package, extension, suffix))
  File.open(file_name, 'wb+') {|f| f.write(contents) }
  if Jammit.config[:gzip_assets]
    files << zip_name = "#{file_name}.gz"
    Zlib::GzipWriter.open(zip_name, Zlib::BEST_COMPRESSION) {|f| f.write(contents) }
  end
  File.utime(mtime, mtime, *files)
end

#individual_urls(package, extension) ⇒ Object

Get the list of individual assets for a package.



80
81
82
# File 'lib/jammit-core/packager.rb', line 80

def individual_urls(package, extension)
  package_for(package, extension)[:urls]
end

#pack_javascripts(package) ⇒ Object

Return the compressed contents of a javascript package.



90
91
92
# File 'lib/jammit-core/packager.rb', line 90

def pack_javascripts(package)
  @compressor.compress_js(package_for(package, :js)[:paths])
end

#pack_stylesheets(package, variant = nil, asset_url = nil) ⇒ Object

Return the compressed contents of a stylesheet package.



85
86
87
# File 'lib/jammit-core/packager.rb', line 85

def pack_stylesheets(package, variant=nil, asset_url=nil)
  @compressor.compress_css(package_for(package, :css)[:paths], variant, asset_url)
end

#pack_templates(package) ⇒ Object

Return the compiled contents of a JST package.



95
96
97
# File 'lib/jammit-core/packager.rb', line 95

def pack_templates(package)
  @compressor.compile_jst(package_for(package, :jst)[:paths])
end

#precache(package, output_dir = nil, base_url = nil) ⇒ Object



58
59
60
# File 'lib/jammit-core/packager.rb', line 58

def precache(package, output_dir=nil, base_url=nil)
  cache(package, 'js', pack_javascripts(package), File.join(output_dir, package), suffix)
end

#precache_all(output_dir = nil, base_url = nil) ⇒ Object

Ask the packager to precache all defined assets, along with their gzip’d versions. In order to prebuild the MHTML stylesheets, we need to know the base_url, because IE only supports MHTML with absolute references. Unless forced, will only rebuild assets whose source files have been changed since their last package build.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/jammit-core/packager.rb', line 37

def precache_all(output_dir=nil, base_url=nil)
  
  output_dir ||= File.join(Jammit.public_root, Jammit.package_path)
  
  cacheable(:js, output_dir).each  {|p|
    cache(p, 'js',  pack_javascripts(p), File.join(output_dir, p), suffix) 
  }
  cacheable(:jst, output_dir).each {|p| cache(p, 'jst', pack_templates(p),  output_dir) }
  cacheable(:css, output_dir).each do |p|
    cache(p, 'css', pack_stylesheets(p), output_dir)
    if Jammit.config[:embed_assets]
      cache(p, 'css', pack_stylesheets(p, :datauri), output_dir, :datauri)
      if Jammit.config[:mhtml_enabled] && base_url
        mtime = Time.now
        asset_url = "#{base_url}#{Jammit.asset_url(p, :css, :mhtml, mtime)}"
        cache(p, 'css', pack_stylesheets(p, :mhtml, asset_url), output_dir, :mhtml, mtime)
      end
    end
  end
end