Class: Jammit::Packager
- Inherits:
-
Object
- Object
- Jammit::Packager
- 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.
Instance Attribute Summary (collapse)
-
- (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.
-
- (Object) package_names
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.
Instance Method Summary (collapse)
-
- (Object) cache(package, extension, contents, output_dir, suffix = nil, mtime = nil)
Caches a single prebuilt asset package and gzips it at the highest compression level.
-
- (Object) cacheable(extension, output_dir)
private
Return a list of all of the packages that should be cached.
- - (Object) compressor
-
- (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) individual_urls(package, extension)
Get the list of individual assets for a package.
-
- (Packager) initialize
constructor
Creating a new Packager will rebuild the list of assets from the Jammit.configuration.
-
- (Object) latest_mtime(paths)
private
Get the latest mtime of a list of files (plus the config path).
-
- (Object) not_found(package, extension)
private
Raise a PackageNotFound exception for missing packages…
-
- (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) package_for(package, extension)
private
Look up a package asset list by name, raising an exception if the package has gone missing.
-
- (Object) path_to_url
private
In Rails, the difference between a path and an asset URL is “public”.
-
- (Object) precache_all(output_dir = nil, base_url = nil)
Ask the packager to precache all defined assets, along with their gzip’d versions.
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.
16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/jammit/packager.rb', line 16 def initialize @force = false @package_names = nil @config = { :css => (Jammit.configuration[:stylesheets] || {}), :js => (Jammit.configuration[:javascripts] || {}) } @packages = { :css => create_packages(@config[:css]), :js => create_packages(@config[:js]) } end |
Instance 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.
11 12 13 |
# File 'lib/jammit/packager.rb', line 11 def force @force end |
- (Object) package_names
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/packager.rb', line 11 def package_names @package_names end |
Instance Method Details
- (Object) cache(package, extension, contents, output_dir, suffix = nil, mtime = nil)
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.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/jammit/packager.rb', line 54 def cache(package, extension, contents, output_dir, suffix=nil, mtime=nil) 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) mtime ||= latest_mtime package_for(package, extension.to_sym)[:paths] files = [] files << file_name = File.join(output_dir, Jammit.filename(package, extension, suffix)) File.open(file_name, 'wb+') {|f| f.write(contents) } if Jammit.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 |
- (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 that are missing or whose source files have changed since the last package build.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/jammit/packager.rb', line 125 def cacheable(extension, output_dir) names = @packages[extension].keys names = names.select {|n| @package_names.include? n } if @package_names config_mtime = File.mtime(Jammit.config_path) return names if @force return names.select do |name| pack = package_for(name, extension) cached = [Jammit.filename(name, extension)] if extension == :css cached.push Jammit.filename(name, extension, :datauri) if Jammit. 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 else since = cached.map {|file| File.mtime(file) }.min config_mtime > since || pack[:paths].any? {|src| File.mtime(src) > since } end end end |
- (Object) compressor
73 74 75 |
# File 'lib/jammit/packager.rb', line 73 def compressor @compressor ||= Compressor.new 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. If there are JST files in this package we need to add an extra path for when package_assets is off (e.g. in a dev environment). This package (e.g. /assets/package-name.jst) will never exist as an actual file but will be dynamically generated by Jammit on every request.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/jammit/packager.rb', line 154 def create_packages(config) packages = {} return packages if !config config.each do |name, globs| globs ||= [] packages[name] = {} 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] += [Jammit.asset_url(name, Jammit.template_extension)] else packages[name][:urls] = paths.map {|path| path.sub(path_to_url, '') } end end packages end |
- (Object) glob_files(glob) (private)
Absolute globs are absolute — relative globs are relative to ASSET_ROOT. Print a warning if no files were found that match the glob.
104 105 106 107 108 109 |
# File 'lib/jammit/packager.rb', line 104 def glob_files(glob) absolute = Pathname.new(glob).absolute? paths = Dir[absolute ? glob : File.join(ASSET_ROOT, glob)].sort Jammit.warn("No assets match '#{glob}'") if paths.empty? paths 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) latest_mtime(paths) (private)
Get the latest mtime of a list of files (plus the config path).
117 118 119 120 |
# File 'lib/jammit/packager.rb', line 117 def latest_mtime(paths) paths += [Jammit.config_path] paths.map {|p| File.mtime(p) }.max || Time.now end |
- (Object) not_found(package, extension) (private)
Raise a PackageNotFound exception for missing packages…
173 174 175 |
# File 'lib/jammit/packager.rb', line 173 def not_found(package, extension) raise PackageNotFound, "assets.yml does not contain a \"#{package}\" #{extension.to_s.upcase} package" end |
- (Object) pack_javascripts(package)
Return the compressed contents of a javascript package.
83 84 85 |
# File 'lib/jammit/packager.rb', line 83 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.
78 79 80 |
# File 'lib/jammit/packager.rb', line 78 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.
88 89 90 |
# File 'lib/jammit/packager.rb', line 88 def pack_templates(package) compressor.compile_jst(package_for(package, :js)[:paths]) end |
- (Object) package_for(package, extension) (private)
Look up a package asset list by name, raising an exception if the package has gone missing.
97 98 99 100 |
# File 'lib/jammit/packager.rb', line 97 def package_for(package, extension) pack = @packages[extension] && @packages[extension][package] pack || not_found(package, extension) end |
- (Object) path_to_url (private)
In Rails, the difference between a path and an asset URL is “public”.
112 113 114 |
# File 'lib/jammit/packager.rb', line 112 def path_to_url @path_to_url ||= /\A#{Regexp.escape(ASSET_ROOT)}(\/?#{Regexp.escape(Jammit.public_root.sub(ASSET_ROOT, ''))})?/ 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.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/jammit/packager.rb', line 34 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), 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 raise MissingConfiguration, "A --base-url option is required in order to generate MHTML." unless base_url mtime = latest_mtime package_for(p, :css)[:paths] 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 |