Class: Jammit::Packager
- Inherits:
- Object
- Defined in:
- lib/jammit/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.
Constant Summary
- PATH_TO_URL = In Rails, the difference between a path and an asset URL is “public”.
/\A#{ASSET_ROOT}(\/public)?/
Attribute Summary
- - (Object) force 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.
Method Summary
- - (Object) cache(package, extension, contents, output_dir, suffix = nil, mtime = Time.now) Caches a single prebuilt asset package and gzips it at the highest compression level.
- - (Object) individual_urls(package, extension) Get the list of individual assets for a package.
- - (Packager) initialize Creating a new Packager will rebuild the list of assets from the Jammit.configuration.
- - (Object) pack_javascripts(package) Return the compressed contents of a javascript package.
- - (Object) pack_stylesheets(package, variant = nil, asset_url = nil) Return the compressed contents of a stylesheet package.
- - (Object) pack_templates(package) Return the compiled contents of a JST package.
- - (Object) precache_all(output_dir = nil, base_url = nil) Ask the packager to precache all defined assets, along with their gzip’d versions.
- - (Object) cacheable(extension, output_dir) private Return a list of all of the packages that should be cached.
- - (Object) create_packages(config) private Compiles the list of assets that goes into each package.
- - (Object) glob_files(glob) private Absolute globs are absolute — relative globs are relative to ASSET_ROOT.
- - (Object) not_found(package, extension) private Raise a PackageNotFound exception for missing packages…
- - (Object) package_for(package, extension) private Look up a package asset list by name, raising an exception if the package has gone missing.
Constructor Details
- (Packager) initialize
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.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/jammit/packager.rb', line 19 def initialize @compressor = Compressor.new @force = false @config = { :css => (Jammit.configuration[:stylesheets] || {}).symbolize_keys, :js => (Jammit.configuration[:javascripts] || {}).symbolize_keys, :jst => (Jammit.configuration[:templates] || {}).symbolize_keys } @packages = { :css => create_packages(@config[:css]), :js => create_packages(@config[:js]), :jst => create_packages(@config[:jst]) } end |
Attribute Details
- (Object) force
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.
14 15 16 |
# File 'lib/jammit/packager.rb', line 14 def force @force end |
Method Details
- (Object) cache(package, extension, contents, output_dir, suffix = nil, mtime = Time.now)
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.
59 60 61 62 63 64 65 66 |
# File 'lib/jammit/packager.rb', line 59 def cache(package, extension, contents, output_dir, suffix=nil, mtime=Time.now) FileUtils.mkdir_p(output_dir) unless File.exists?(output_dir) filename = File.join(output_dir, Jammit.filename(package, extension, suffix)) zip_name = "#{filename}.gz" File.open(filename, 'wb+') {|f| f.write(contents) } Zlib::GzipWriter.open(zip_name, Zlib::BEST_COMPRESSION) {|f| f.write(contents) } File.utime(mtime, mtime, filename, zip_name) end |
- (Object) individual_urls(package, extension)
Get the list of individual assets for a package.
69 70 71 |
# File 'lib/jammit/packager.rb', line 69 def individual_urls(package, extension) package_for(package, extension)[:urls] end |
- (Object) pack_javascripts(package)
Return the compressed contents of a javascript package.
79 80 81 |
# File 'lib/jammit/packager.rb', line 79 def pack_javascripts(package) @compressor.compress_js(package_for(package, :js)[:paths]) end |
- (Object) pack_stylesheets(package, variant = nil, asset_url = nil)
Return the compressed contents of a stylesheet package.
74 75 76 |
# File 'lib/jammit/packager.rb', line 74 def pack_stylesheets(package, variant=nil, asset_url=nil) @compressor.compress_css(package_for(package, :css)[:paths], variant, asset_url) end |
- (Object) pack_templates(package)
Return the compiled contents of a JST package.
84 85 86 |
# File 'lib/jammit/packager.rb', line 84 def pack_templates(package) @compressor.compile_jst(package_for(package, :jst)[:paths]) end |
- (Object) precache_all(output_dir = nil, base_url = nil)
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.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/jammit/packager.rb', line 39 def precache_all(output_dir=nil, base_url=nil) output_dir ||= File.join(PUBLIC_ROOT, Jammit.package_path) cacheable(:js, output_dir).each {|p| cache(p, 'js', pack_javascripts(p), output_dir) } 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. cache(p, 'css', pack_stylesheets(p, :datauri), output_dir, :datauri) if Jammit.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 |
- (Object) cacheable(extension, output_dir) (private)
Return a list of all of the packages that should be cached. If “force” is true, this is all of them — otherwise only the packages whose source files have changed since the last package build.
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/jammit/packager.rb', line 107 def cacheable(extension, output_dir) names = @packages[extension].keys return names if @force return names.select do |name| pack = package_for(name, extension) cached = File.join(output_dir, Jammit.filename(name, extension)) since = File.exists?(cached) && File.mtime(cached) !since || pack[:paths].any? {|src| File.mtime(src) > since } end end |
- (Object) create_packages(config) (private)
Compiles the list of assets that goes into each package. Runs an ordered list of Dir.globs, taking the merged unique result.
120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/jammit/packager.rb', line 120 def create_packages(config) packages = {} return packages if !config config.each do |name, globs| globs ||= [] packages[name] = {} paths = globs.map {|glob| glob_files(glob) }.flatten.uniq packages[name][:paths] = paths packages[name][:urls] = paths.map {|path| path.sub(PATH_TO_URL, '') } end packages end |
- (Object) glob_files(glob) (private)
Absolute globs are absolute — relative globs are relative to ASSET_ROOT.
99 100 101 102 |
# File 'lib/jammit/packager.rb', line 99 def glob_files(glob) absolute = Pathname.new(glob).absolute? Dir[absolute ? glob : File.join(ASSET_ROOT, glob)] end |
- (Object) not_found(package, extension) (private)
Raise a PackageNotFound exception for missing packages…
134 135 136 |
# File 'lib/jammit/packager.rb', line 134 def not_found(package, extension) raise PackageNotFound, "assets.yml does not contain a \"#{package}\" #{extension.to_s.upcase} package" end |
- (Object) package_for(package, extension) (private)
Look up a package asset list by name, raising an exception if the package has gone missing.
93 94 95 96 |
# File 'lib/jammit/packager.rb', line 93 def package_for(package, extension) pack = @packages[extension] && @packages[extension][package] pack || not_found(package, extension) end |