`Asset` is the base class for `BundledAsset` and `StaticAsset`.
Internal initializer to load `Asset` from serialized `Hash`.
# File lib/sprockets/asset.rb, line 8 def self.from_hash(environment, hash) return unless hash.is_a?(Hash) klass = case hash['class'] when 'BundledAsset' BundledAsset when 'ProcessedAsset' ProcessedAsset when 'StaticAsset' StaticAsset else nil end if klass asset = klass.allocate asset.init_with(environment, hash) asset end rescue UnserializeError nil end
# File lib/sprockets/asset.rb, line 35 def initialize(environment, logical_path, pathname) raise ArgumentError, "Asset logical path has no extension: #{logical_path}" if File.extname(logical_path) == "" @root = environment.root @logical_path = logical_path.to_s @pathname = Pathname.new(pathname) @content_type = environment.content_type_of(pathname) @mtime = environment.stat(pathname).mtime @length = environment.stat(pathname).size @digest = environment.file_digest(pathname).hexdigest end
`body` is aliased to source by default if it can't have any dependencies.
# File lib/sprockets/asset.rb, line 107 def body source end
Return an `Array` of `Asset` files that are declared dependencies.
# File lib/sprockets/asset.rb, line 91 def dependencies [] end
Return logical path with digest spliced in.
"foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"
# File lib/sprockets/asset.rb, line 86 def digest_path logical_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } end
Add enumerator to allow `Asset` instances to be used as Rack compatible body objects.
# File lib/sprockets/asset.rb, line 118 def each yield to_s end
Copy serialized attributes to the coder object
# File lib/sprockets/asset.rb, line 72 def encode_with(coder) coder['class'] = self.class.name.sub(/Sprockets::/, '') coder['logical_path'] = logical_path coder['pathname'] = relativize_root_path(pathname).to_s coder['content_type'] = content_type coder['mtime'] = mtime.iso8601 coder['length'] = length coder['digest'] = digest end
Assets are equal if they share the same path, mtime and digest.
# File lib/sprockets/asset.rb, line 185 def eql?(other) other.class == self.class && other.logical_path == self.logical_path && other.mtime.to_i == self.mtime.to_i && other.digest == self.digest end
Checks if Asset is fresh by comparing the actual mtime and digest to the inmemory model.
Used to test if cached models need to be rebuilt.
# File lib/sprockets/asset.rb, line 126 def fresh?(environment) # Check current mtime and digest dependency_fresh?(environment, self) end
# File lib/sprockets/asset.rb, line 180 def hash digest.hash end
Initialize `Asset` from serialized `Hash`.
# File lib/sprockets/asset.rb, line 48 def init_with(environment, coder) @root = environment.root @logical_path = coder['logical_path'] @content_type = coder['content_type'] @digest = coder['digest'] if pathname = coder['pathname'] # Expand `$root` placeholder and wrapper string in a `Pathname` @pathname = Pathname.new(expand_root_path(pathname)) end if mtime = coder['mtime'] # Parse time string @mtime = Time.parse(mtime) end if length = coder['length'] # Convert length to an `Integer` @length = Integer(length) end end
Pretty inspect
# File lib/sprockets/asset.rb, line 172 def inspect "#<#{self.class}:0x#{object_id.to_s(16)} " + "pathname=#{pathname.to_s.inspect}, " + "mtime=#{mtime.inspect}, " + "digest=#{digest.inspect}" + ">" end
Checks if Asset is stale by comparing the actual mtime and digest to the inmemory model.
Subclass must override `fresh?` or `stale?`.
# File lib/sprockets/asset.rb, line 135 def stale?(environment) !fresh?(environment) end
Expand asset into an `Array` of parts.
Appending all of an assets body parts together should give you the asset's contents as a whole.
This allows you to link to individual files for debugging purposes.
# File lib/sprockets/asset.rb, line 102 def to_a [self] end
Return `String` of concatenated source.
# File lib/sprockets/asset.rb, line 112 def to_s source end
Save asset to disk.
# File lib/sprockets/asset.rb, line 140 def write_to(filename, options = {}) # Gzip contents if filename has '.gz' options[:compress] ||= File.extname(filename) == '.gz' FileUtils.mkdir_p File.dirname(filename) File.open("#{filename}+", 'wb') do |f| if options[:compress] # Run contents through `Zlib` gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION) gz.mtime = mtime.to_i gz.write to_s gz.close else # Write out as is f.write to_s end end # Atomic write FileUtils.mv("#{filename}+", filename) # Set mtime correctly File.utime(mtime, mtime, filename) nil ensure # Ensure tmp file gets cleaned up FileUtils.rm("#{filename}+") if File.exist?("#{filename}+") end
Check if dependency is fresh.
`dep` is a `Hash` with `path`, `mtime` and `hexdigest` keys.
A `Hash` is used rather than other `Asset` object because we want to test non-asset files and directories.
# File lib/sprockets/asset.rb, line 229 def dependency_fresh?(environment, dep) path, mtime, hexdigest = dep.pathname.to_s, dep.mtime, dep.digest stat = environment.stat(path) # If path no longer exists, its definitely stale. if stat.nil? return false end # Compare dependency mtime to the actual mtime. If the # dependency mtime is newer than the actual mtime, the file # hasn't changed since we created this `Asset` instance. # # However, if the mtime is newer it doesn't mean the asset is # stale. Many deployment environments may recopy or recheckout # assets on each deploy. In this case the mtime would be the # time of deploy rather than modified time. if mtime >= stat.mtime return true end digest = environment.file_digest(path) # If the mtime is newer, do a full digest comparsion. Return # fresh if the digests match. if hexdigest == digest.hexdigest return true end # Otherwise, its stale. false end
Internal: String paths that are marked as dependencies after processing.
Default to an empty `Array`.
# File lib/sprockets/asset.rb, line 197 def dependency_paths @dependency_paths ||= [] end
Replace `$root` placeholder with actual environment root.
# File lib/sprockets/asset.rb, line 214 def expand_root_path(path) path.to_s.sub(/^\$root/, @root) end
Get pathname with its root stripped.
# File lib/sprockets/asset.rb, line 209 def relative_pathname @relative_pathname ||= Pathname.new(relativize_root_path(pathname)) end
Replace actual environment root with `$root` placeholder.
# File lib/sprockets/asset.rb, line 219 def relativize_root_path(path) path.to_s.sub(/^#{Regexp.escape(@root)}/, '$root') end
Internal: `ProccessedAsset`s that are required after processing.
Default to an empty `Array`.
# File lib/sprockets/asset.rb, line 204 def required_assets @required_assets ||= [] end