Parent

Sprockets::Manifest

The Manifest logs the contents of assets compiled to a single directory. It records basic attributes about the asset for fast lookup without having to compile. A pointer from each logical path indicates with fingerprinted asset is the current one.

The JSON is part of the public API and should be considered stable. This should make it easy to read from other programming languages and processes that don’t have sprockets loaded. See `#` and `#` for more infomation about the structure.

Attributes

environment[R]
path[R]
dir[R]

Public Class Methods

new(environment, path) click to toggle source

Create new Manifest associated with an `environment`. `path` is a full path to the manifest json file. The file may or may not already exist. The dirname of the `path` will be used to write compiled assets to. Otherwise, if the path is a directory, the filename will default to “manifest.json“ in that directory.

  Manifest.new(environment, "./public/assets/manifest.json")
    # File lib/sprockets/manifest.rb, line 25
25:     def initialize(environment, path)
26:       @environment = environment
27: 
28:       if File.extname(path) == ""
29:         @dir  = File.expand_path(path)
30:         @path = File.join(@dir, 'manifest.json')
31:       else
32:         @path = File.expand_path(path)
33:         @dir  = File.dirname(path)
34:       end
35: 
36:       data = nil
37: 
38:       begin
39:         if File.exist?(@path)
40:           data = MultiJson.decode(File.read(@path))
41:         end
42:       rescue MultiJson::DecodeError => e
43:         logger.error "#{@path} is invalid: #{e.class} #{e.message}"
44:       end
45: 
46:       @data = data.is_a?(Hash) ? data : {}
47:     end

Public Instance Methods

assets() click to toggle source

Returns internal assets mapping. Keys are logical paths which map to the latest fingerprinted filename.

  Logical path (String): Fingerprint path (String)

  { "application.js" => "application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js",
    "jquery.js"      => "jquery-ae0908555a245f8266f77df5a8edca2e.js" }
    # File lib/sprockets/manifest.rb, line 57
57:     def assets
58:       @data['assets'] ||= {}
59:     end
clean(keep = 2) click to toggle source

Cleanup old assets in the compile directory. By default it will keep the latest version plus 2 backups.

     # File lib/sprockets/manifest.rb, line 138
138:     def clean(keep = 2)
139:       self.assets.keys.each do |logical_path|
140:         # Get assets sorted by ctime, newest first
141:         assets = backups_for(logical_path)
142: 
143:         # Keep the last N backups
144:         assets = assets[keep..1] || []
145: 
146:         # Remove old assets
147:         assets.each { |path, _| remove(path) }
148:       end
149:     end
clobber() click to toggle source

Wipe directive

     # File lib/sprockets/manifest.rb, line 152
152:     def clobber
153:       FileUtils.rm_r(@dir) if File.exist?(@dir)
154:       logger.warn "Removed #{@dir}"
155:       nil
156:     end
compile(*args) click to toggle source

Compile and write asset to directory. The asset is written to a fingerprinted filename like `application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js`. An entry is also inserted into the manifest file.

  compile("application.js")
     # File lib/sprockets/manifest.rb, line 85
 85:     def compile(*args)
 86:       paths = environment.each_logical_path(*args).to_a +
 87:         args.flatten.select { |fn| Pathname.new(fn).absolute? }
 88: 
 89:       paths.each do |path|
 90:         if asset = find_asset(path)
 91:           files[asset.digest_path] = {
 92:             'logical_path' => asset.logical_path,
 93:             'mtime'        => asset.mtime.iso8601,
 94:             'digest'       => asset.digest
 95:           }
 96:           assets[asset.logical_path] = asset.digest_path
 97: 
 98:           target = File.join(dir, asset.digest_path)
 99: 
100:           if File.exist?(target)
101:             logger.debug "Skipping #{target}, already exists"
102:           else
103:             logger.info "Writing #{target}"
104:             asset.write_to target
105:           end
106: 
107:           save
108:           asset
109:         end
110:       end
111:     end
files() click to toggle source

Returns internal file directory listing. Keys are filenames which map to an attributes array.

  Fingerprint path (String):
    logical_path: Logical path (String)
    mtime: ISO8601 mtime (String)
    digest: Base64 hex digest (String)

 { "application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js" =>
     { 'logical_path' => "application.js",
       'mtime' => "2011-12-13T21:47:08-06:00",
       'digest' => "2e8e9a7c6b0aafa0c9bdeec90ea30213" } }
    # File lib/sprockets/manifest.rb, line 74
74:     def files
75:       @data['files'] ||= {}
76:     end
remove(filename) click to toggle source

Removes file from directory and from manifest. `filename` must be the name with any directory path.

  manifest.remove("application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js")
     # File lib/sprockets/manifest.rb, line 118
118:     def remove(filename)
119:       path = File.join(dir, filename)
120:       logical_path = files[filename]['logical_path']
121: 
122:       if assets[logical_path] == filename
123:         assets.delete(logical_path)
124:       end
125: 
126:       files.delete(filename)
127:       FileUtils.rm(path) if File.exist?(path)
128: 
129:       save
130: 
131:       logger.warn "Removed #{filename}"
132: 
133:       nil
134:     end

Protected Instance Methods

backups_for(logical_path) click to toggle source

Finds all the backup assets for a logical path. The latest version is always excluded. The return array is sorted by the assets mtime in descending order (Newest to oldest).

     # File lib/sprockets/manifest.rb, line 162
162:       def backups_for(logical_path)
163:         files.select { |filename, attrs|
164:           # Matching logical paths
165:           attrs['logical_path'] == logical_path &&
166:             # Excluding whatever asset is the current
167:             assets[logical_path] != filename
168:         }.sort_by { |filename, attrs|
169:           # Sort by timestamp
170:           Time.parse(attrs['mtime'])
171:         }.reverse
172:       end
find_asset(logical_path) click to toggle source

Basic wrapper around Environment#find_asset. Logs compile time.

     # File lib/sprockets/manifest.rb, line 175
175:       def find_asset(logical_path)
176:         asset = nil
177:         ms = benchmark do
178:           asset = environment.find_asset(logical_path)
179:         end
180:         logger.warn "Compiled #{logical_path}  (#{ms}ms)"
181:         asset
182:       end
save() click to toggle source

Persist manfiest back to FS

     # File lib/sprockets/manifest.rb, line 185
185:       def save
186:         FileUtils.mkdir_p dir
187:         File.open(path, 'w') do |f|
188:           f.write MultiJson.encode(@data)
189:         end
190:       end

Private Instance Methods

benchmark() click to toggle source
     # File lib/sprockets/manifest.rb, line 197
197:       def benchmark
198:         start_time = Time.now.to_f
199:         yield
200:         ((Time.now.to_f - start_time) * 1000).to_i
201:       end
logger() click to toggle source
     # File lib/sprockets/manifest.rb, line 193
193:       def logger
194:         environment.logger
195:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.