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

#initialize(environment, logical_path, pathname) ⇒ Asset

Returns a new instance of Asset.



35
36
37
38
39
40
41
42
43
# File 'lib/sprockets/asset.rb', line 35

def initialize(environment, logical_path, pathname)
  @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

#content_typeObject (readonly)

Returns the value of attribute content_type.



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

def content_type
  @content_type
end

#digestObject (readonly)

Returns the value of attribute digest.



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

def digest
  @digest
end

#lengthObject (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

#logical_pathObject (readonly)

Returns the value of attribute logical_path.



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

def logical_path
  @logical_path
end

#mtimeObject (readonly)

Returns the value of attribute mtime.



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

def mtime
  @mtime
end

#pathnameObject (readonly)

Returns the value of attribute pathname.



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

def pathname
  @pathname
end

Class Method Details

.from_hash(environment, hash) ⇒ Object

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

#bodyObject

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



105
106
107
# File 'lib/sprockets/asset.rb', line 105

def body
  source
end

#dependenciesObject

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



89
90
91
# File 'lib/sprockets/asset.rb', line 89

def dependencies
  []
end

#digest_pathObject

Return logical path with digest spliced in.

"foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"


84
85
86
# File 'lib/sprockets/asset.rb', line 84

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

#each {|to_s| ... } ⇒ Object

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

Yields:



116
117
118
# File 'lib/sprockets/asset.rb', line 116

def each
  yield to_s
end

#encode_with(coder) ⇒ Object

Copy serialized attributes to the coder object



70
71
72
73
74
75
76
77
78
# File 'lib/sprockets/asset.rb', line 70

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

#eql?(other) ⇒ Boolean Also known as: ==

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

Returns:

  • (Boolean)


183
184
185
186
187
188
# File 'lib/sprockets/asset.rb', line 183

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

#fresh?(environment) ⇒ Boolean

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)


124
125
126
127
# File 'lib/sprockets/asset.rb', line 124

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

#hashObject



178
179
180
# File 'lib/sprockets/asset.rb', line 178

def hash
  digest.hash
end

#init_with(environment, coder) ⇒ Object

Initialize ‘Asset` from serialized `Hash`.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/sprockets/asset.rb', line 46

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

#inspectObject

Pretty inspect



170
171
172
173
174
175
176
# File 'lib/sprockets/asset.rb', line 170

def inspect
  "#<#{self.class}:0x#{object_id.to_s(16)} " +
    "pathname=#{pathname.to_s.inspect}, " +
    "mtime=#{mtime.inspect}, " +
    "digest=#{digest.inspect}" +
    ">"
end

#stale?(environment) ⇒ Boolean

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

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

Returns:

  • (Boolean)


133
134
135
# File 'lib/sprockets/asset.rb', line 133

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

#to_aObject

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.



100
101
102
# File 'lib/sprockets/asset.rb', line 100

def to_a
  [self]
end

#to_sObject

Return ‘String` of concatenated source.



110
111
112
# File 'lib/sprockets/asset.rb', line 110

def to_s
  source
end

#write_to(filename, options = {}) ⇒ Object

Save asset to disk.



138
139
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
# File 'lib/sprockets/asset.rb', line 138

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.write to_s
      gz.close
    else
      # Write out as is
      f.write to_s
      f.close
    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