Class: Sprockets::BundledAsset

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

Overview

‘BundledAsset`s are used for files that need to be processed and concatenated with other assets. Use for `.js` and `.css` files.

Instance Attribute Summary

Attributes inherited from Asset

#environment, #id, #logical_path, #pathname

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Asset

#content_type, #digest_path, #each, #eql?, from_hash, #inspect, #stale?

Constructor Details

#initialize(environment, logical_path, pathname, options) ⇒ BundledAsset

Returns a new instance of BundledAsset.



16
17
18
19
# File 'lib/sprockets/bundled_asset.rb', line 16

def initialize(environment, logical_path, pathname, options)
  super(environment, logical_path, pathname)
  @options = options || {}
end

Class Method Details

.serialized_attributesObject

Define extra attributes to be serialized.



12
13
14
# File 'lib/sprockets/bundled_asset.rb', line 12

def self.serialized_attributes
  super + %w( content_type mtime )
end

Instance Method Details

#bodyObject

Get asset’s own processed contents. Excludes any of its required dependencies but does run any processors or engines on the original file.



55
56
57
# File 'lib/sprockets/bundled_asset.rb', line 55

def body
  @body ||= build_dependency_context_and_body[1]
end

#dependenciesObject

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



75
76
77
# File 'lib/sprockets/bundled_asset.rb', line 75

def dependencies
  to_a - [self]
end

#digestObject

Compute digest of concatenated source.



70
71
72
# File 'lib/sprockets/bundled_asset.rb', line 70

def digest
  @digest ||= build_source['digest']
end

#encode_with(coder) ⇒ Object

Serialize custom attributes in ‘BundledAsset`.



42
43
44
45
46
47
48
49
50
# File 'lib/sprockets/bundled_asset.rb', line 42

def encode_with(coder)
  super

  coder['body']        = body
  coder['asset_paths'] = to_a.map { |a| relativize_root_path(a.pathname) }
  coder['dependency_paths'] = dependency_paths.map { |h|
    h.merge('path' => relativize_root_path(h['path']))
  }
end

#fresh?Boolean

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

Returns:

  • (Boolean)


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

def fresh?
  # Check freshness of all declared dependencies
  dependency_paths.all? { |h| dependency_fresh?(h) }
end

#init_with(environment, coder) ⇒ Object

Initialize ‘BundledAsset` from serialized `Hash`.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/sprockets/bundled_asset.rb', line 22

def init_with(environment, coder)
  @options = {}

  super

  @body   = coder['body']
  @assets = coder['asset_paths'].map { |p|
    p = expand_root_path(p)
    p == pathname.to_s ? self : environment[p, @options]
  }

  @dependency_paths = coder['dependency_paths'].map { |h|
    h.merge('path' => expand_root_path(h['path']))
  }
  @dependency_paths.each do |dep|
    dep['mtime'] = Time.parse(dep['mtime']) if dep['mtime'].is_a?(String)
  end
end

#lengthObject

Get size of concatenated source.



65
66
67
# File 'lib/sprockets/bundled_asset.rb', line 65

def length
  @length ||= build_source['length']
end

#mtimeObject

Get latest mtime of all its dependencies.



60
61
62
# File 'lib/sprockets/bundled_asset.rb', line 60

def mtime
  @mtime ||= dependency_paths.map { |h| h['mtime'] }.max
end

#to_aObject

Expand asset into an ‘Array` of parts.



80
81
82
# File 'lib/sprockets/bundled_asset.rb', line 80

def to_a
  @assets ||= build_dependencies_paths_and_assets[1]
end

#to_sObject

Return ‘String` of concatenated source.



92
93
94
# File 'lib/sprockets/bundled_asset.rb', line 92

def to_s
  @source ||= build_source['source']
end

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

Save asset to disk.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/sprockets/bundled_asset.rb', line 97

def write_to(filename, options = {})
  # Gzip contents if filename has '.gz'
  options[:compress] ||= File.extname(filename) == '.gz'

  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