Object
`Base` class for `Environment` and `Index`.
The `Environment#version` is a custom value used for manually expiring all asset caches.
Sprockets is able to track most file and directory changes and will take care of expiring the cache for you. However, its impossible to know when any custom helpers change that you mix into the `Context`.
It would be wise to increment this value anytime you make a configuration change to the `Environment` object.
Preferred `find_asset` shorthand.
environment['application.js']
# File lib/sprockets/base.rb, line 176 176: def [](*args) 177: find_asset(*args) 178: end
Internal. Return a `AssetAttributes` for `path`.
# File lib/sprockets/base.rb, line 144 144: def attributes_for(path) 145: AssetAttributes.new(self, path) 146: end
Set persistent cache store
The cache store must implement a pair of getters and setters. Either `get(key)`/`set(key, value)`, `[key]`/`[key]=value`, `read(key)`/`write(key, value)`.
# File lib/sprockets/base.rb, line 96 96: def cache=(cache) 97: expire_index! 98: @cache = cache 99: end
Internal. Return content type of `path`.
# File lib/sprockets/base.rb, line 149 149: def content_type_of(path) 150: attributes_for(path).content_type 151: end
Returns a `Digest` instance for the `Environment`.
This value serves two purposes. If two `Environment`s have the same digest value they can be treated as equal. This is more useful for comparing environment states between processes rather than in the same. Two equal `Environment`s can share the same cached assets.
The value also provides a seed digest for all `Asset` digests. Any change in the environment digest will affect all of its assets.
# File lib/sprockets/base.rb, line 64 64: def digest 65: # Compute the initial digest using the implementation class. The 66: # Sprockets release version and custom environment version are 67: # mixed in. So any new releases will affect all your assets. 68: @digest ||= digest_class.new.update(VERSION).update(version.to_s) 69: 70: # Returned a dupped copy so the caller can safely mutate it with `.update` 71: @digest.dup 72: end
Assign a `Digest` implementation class. This maybe any Ruby `Digest::` implementation such as `Digest::MD5` or `Digest::SHA1`.
environment.digest_class = Digest::SHA1
# File lib/sprockets/base.rb, line 27 27: def digest_class=(klass) 28: expire_index! 29: @digest_class = klass 30: end
# File lib/sprockets/base.rb, line 180 180: def each_entry(root, &block) 181: return to_enum(__method__, root) unless block_given? 182: root = Pathname.new(root) unless root.is_a?(Pathname) 183: 184: paths = [] 185: entries(root).sort.each do |filename| 186: path = root.join(filename) 187: paths << path 188: 189: if stat(path).directory? 190: each_entry(path) do |subpath| 191: paths << subpath 192: end 193: end 194: end 195: 196: paths.sort_by(&:to_s).each(&block) 197: 198: nil 199: end
# File lib/sprockets/base.rb, line 201 201: def each_file 202: return to_enum(__method__) unless block_given? 203: paths.each do |root| 204: each_entry(root) do |path| 205: if !stat(path).directory? 206: yield path 207: end 208: end 209: end 210: nil 211: end
# File lib/sprockets/base.rb, line 213 213: def each_logical_path(*args) 214: return to_enum(__method__, *args) unless block_given? 215: filters = args.flatten 216: files = {} 217: each_file do |filename| 218: if logical_path = logical_path_for_filename(filename, filters) 219: yield logical_path unless files[logical_path] 220: files[logical_path] = true 221: end 222: end 223: nil 224: end
Works like `Dir.entries`.
Subclasses may cache this method.
# File lib/sprockets/base.rb, line 115 115: def entries(pathname) 116: trail.entries(pathname) 117: end
Read and compute digest of filename.
Subclasses may cache this method.
# File lib/sprockets/base.rb, line 129 129: def file_digest(path) 130: if stat = self.stat(path) 131: # If its a file, digest the contents 132: if stat.file? 133: digest.file(path.to_s) 134: 135: # If its a directive, digest the list of filenames 136: elsif stat.directory? 137: contents = self.entries(path).join(',') 138: digest.update(contents) 139: end 140: end 141: end
Find asset by logical path or expanded path.
# File lib/sprockets/base.rb, line 154 154: def find_asset(path, options = {}) 155: logical_path = path 156: pathname = Pathname.new(path) 157: 158: if pathname.absolute? 159: return unless stat(pathname) 160: logical_path = attributes_for(pathname).logical_path 161: else 162: begin 163: pathname = resolve(logical_path) 164: rescue FileNotFound 165: return nil 166: end 167: end 168: 169: build_asset(logical_path, pathname, options) 170: end
Return an `Index`. Must be implemented by the subclass.
# File lib/sprockets/base.rb, line 102 102: def index 103: raise NotImplementedError 104: end
Pretty inspect
# File lib/sprockets/base.rb, line 227 227: def inspect 228: "#<#{self.class}:0x#{object_id.to_s(16)} " + 229: "root=#{root.to_s.inspect}, " + 230: "paths=#{paths.inspect}, " + 231: "digest=#{digest.to_s.inspect}" + 232: ">" 233: end
# File lib/sprockets/base.rb, line 241 241: def build_asset(logical_path, pathname, options) 242: pathname = Pathname.new(pathname) 243: 244: # If there are any processors to run on the pathname, use 245: # `BundledAsset`. Otherwise use `StaticAsset` and treat is as binary. 246: if attributes_for(pathname).processors.any? 247: if options[:bundle] == false 248: circular_call_protection(pathname.to_s) do 249: ProcessedAsset.new(index, logical_path, pathname) 250: end 251: else 252: BundledAsset.new(index, logical_path, pathname) 253: end 254: else 255: StaticAsset.new(index, logical_path, pathname) 256: end 257: end
# File lib/sprockets/base.rb, line 259 259: def cache_key_for(path, options) 260: "#{path}:#{options[:bundle] ? '1' : '0'}" 261: end
# File lib/sprockets/base.rb, line 263 263: def circular_call_protection(path) 264: reset = Thread.current[:sprockets_circular_calls].nil? 265: calls = Thread.current[:sprockets_circular_calls] ||= Set.new 266: if calls.include?(path) 267: raise CircularDependencyError, "#{path} has already been required" 268: end 269: calls << path 270: yield 271: ensure 272: Thread.current[:sprockets_circular_calls] = nil if reset 273: end
Clear index after mutating state. Must be implemented by the subclass.
# File lib/sprockets/base.rb, line 237 237: def expire_index! 238: raise NotImplementedError 239: end
# File lib/sprockets/base.rb, line 275 275: def logical_path_for_filename(filename, filters) 276: logical_path = attributes_for(filename).logical_path.to_s 277: 278: if matches_filter(filters, logical_path) 279: return logical_path 280: end 281: 282: # If filename is an index file, retest with alias 283: if File.basename(logical_path)[/[^\.]+/, 0] == 'index' 284: path = logical_path.sub(/\/index\./, '.') 285: if matches_filter(filters, path) 286: return path 287: end 288: end 289: 290: nil 291: end
# File lib/sprockets/base.rb, line 293 293: def matches_filter(filters, filename) 294: return true if filters.empty? 295: 296: filters.any? do |filter| 297: if filter.is_a?(Regexp) 298: filter.match(filename) 299: elsif filter.respond_to?(:call) 300: filter.call(filename) 301: else 302: File.fnmatch(filter.to_s, filename) 303: end 304: end 305: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.