Class: Sprockets::Asset

Inherits:
Object
  • Object
show all
Defined in:
lib/sprockets/asset.rb

Overview

`Asset` is the base class for `BundledAsset` and `StaticAsset`.

Direct Known Subclasses

BundledAsset, ProcessedAsset, StaticAsset

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Asset) initialize(environment, logical_path, pathname)

Returns a new instance of Asset

Raises:



35
36
37
38
39
40
41
42
43
44
45
# 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

Instance Attribute Details

- (Object) content_type (readonly)

Returns the value of attribute content_type



32
33
34
# File 'lib/sprockets/asset.rb', line 32

def content_type
  @content_type
end

- (Object) digest (readonly)

Returns the value of attribute digest



32
33
34
# File 'lib/sprockets/asset.rb', line 32

def digest
  @digest
end

- (Object) length (readonly) Also known as: bytesize

Returns the value of attribute length



32
33
34
# File 'lib/sprockets/asset.rb', line 32

def length
  @length
end

- (Object) logical_path (readonly)

Returns the value of attribute logical_path



31
32
33
# File 'lib/sprockets/asset.rb', line 31

def logical_path
  @logical_path
end

- (Object) mtime (readonly)

Returns the value of attribute mtime



32
33
34
# File 'lib/sprockets/asset.rb', line 32

def mtime
  @mtime
end

- (Object) pathname (readonly)

Returns the value of attribute pathname



31
32
33
# File 'lib/sprockets/asset.rb', line 31

def pathname
  @pathname
end

Class Method Details

+ (Object) from_hash(environment, hash)

Internal initializer to load `Asset` from serialized `Hash`.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 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

Instance Method Details

- (Object) body

`body` is aliased to source by default if it can't have any dependencies.



107
108
109
# File 'lib/sprockets/asset.rb', line 107

def body
  source
end

- (Object) dependencies

Return an `Array` of `Asset` files that are declared dependencies.



91
92
93
# File 'lib/sprockets/asset.rb', line 91

def dependencies
  []
end

- (Object) digest_path

Return logical path with digest spliced in.

"foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"


86
87
88
# File 'lib/sprockets/asset.rb', line 86

def digest_path
  logical_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" }
end

- (Object) each {|to_s| ... }

Add enumerator to allow `Asset` instances to be used as Rack compatible body objects.

Yields:

  • (to_s)


118
119
120
# File 'lib/sprockets/asset.rb', line 118

def each
  yield to_s
end

- (Object) encode_with(coder)

Copy serialized attributes to the coder object



72
73
74
75
76
77
78
79
80
# 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

- (Boolean) eql?(other) Also known as: ==

Assets are equal if they share the same path, mtime and digest.

Returns:

  • (Boolean)


185
186
187
188
189
190
# 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

- (Boolean) fresh?(environment)

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.

Returns:

  • (Boolean)


126
127
128
129
# File 'lib/sprockets/asset.rb', line 126

def fresh?(environment)
  # Check current mtime and digest
  dependency_fresh?(environment, self)
end

- (Object) hash



180
181
182
# File 'lib/sprockets/asset.rb', line 180

def hash
  digest.hash
end

- (Object) init_with(environment, coder)

Initialize `Asset` from serialized `Hash`.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 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

- (Object) inspect

Pretty inspect



172
173
174
175
176
177
178
# 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

- (Boolean) stale?(environment)

Checks if Asset is stale by comparing the actual mtime and digest to the inmemory model.

Subclass must override `fresh?` or `stale?`.

Returns:

  • (Boolean)


135
136
137
# File 'lib/sprockets/asset.rb', line 135

def stale?(environment)
  !fresh?(environment)
end

- (Object) to_a

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.



102
103
104
# File 'lib/sprockets/asset.rb', line 102

def to_a
  [self]
end

- (Object) to_s

Return `String` of concatenated source.



112
113
114
# File 'lib/sprockets/asset.rb', line 112

def to_s
  source
end

- (Object) write_to(filename, options = {})

Save asset to disk.



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# 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