Class: Sprockets::Manifest

### Home Classes Methods

### In Files

- lib/sprockets/legacy.rb
- lib/sprockets/manifest.rb

### Parent

Object

### Methods

- ::compile_match_filter
- ::compute_alias_logical_path
- ::new
- ::simple_logical_path?
- #assets
- #clean
- #clobber
- #compile
- #files
- #filter_logical_paths
- #find
- #find_logical_paths
- #remove
- #save

### Included Modules

- Sprockets::ManifestUtils

### Class/Module Index

Quicksearch

- Sprockets
- Sprockets::ArgumentError
- Sprockets::Asset
- Sprockets::Autoload
- Sprockets::Base
- Sprockets::Bower
- Sprockets::Bundle
- Sprockets::Cache
- Sprockets::Cache::FileStore
- Sprockets::Cache::GetWrapper
- Sprockets::Cache::HashWrapper
- Sprockets::Cache::MemoryStore
- Sprockets::Cache::NullStore
- Sprockets::Cache::ReadWriteWrapper
- Sprockets::Cache::Wrapper
- Sprockets::CachedEnvironment
- Sprockets::ClosureCompressor
- Sprockets::CoffeeScriptProcessor
- Sprockets::CoffeeScriptTemplate
- Sprockets::Compressing
- Sprockets::Configuration
- Sprockets::ContentTypeMismatch
- Sprockets::Context
- Sprockets::ConversionError
- Sprockets::Dependencies
- Sprockets::DigestUtils
- Sprockets::DirectiveProcessor
- Sprockets::ERBProcessor
- Sprockets::ERBTemplate
- Sprockets::EcoProcessor
- Sprockets::EcoTemplate
- Sprockets::EjsProcessor
- Sprockets::EjsTemplate
- Sprockets::EncodingUtils
- Sprockets::Engines
- Sprockets::Environment
- Sprockets::Error
- Sprockets::FileNotFound
- Sprockets::FileOutsidePaths
- Sprockets::FileReader
- Sprockets::HTTPUtils
- Sprockets::Index
- Sprockets::JstProcessor
- Sprockets::LegacyProcProcessor
- Sprockets::LegacyTiltProcessor
- Sprockets::Loader
- Sprockets::Manifest
- Sprockets::ManifestUtils
- Sprockets::Mime
- Sprockets::NotFound
- Sprockets::NotImplementedError
- Sprockets::PathDependencyUtils
- Sprockets::PathDigestUtils
- Sprockets::PathUtils
- Sprockets::Paths
- Sprockets::Processing
- Sprockets::ProcessorUtils
- Sprockets::Resolve
- Sprockets::SassCompressor
- Sprockets::SassProcessor
- Sprockets::SassProcessor::CacheStore
- Sprockets::SassProcessor::Functions
- Sprockets::SassTemplate
- Sprockets::ScssProcessor
- Sprockets::ScssTemplate
- Sprockets::Server
- Sprockets::Transformers
- Sprockets::URITar
- Sprockets::URIUtils
- Sprockets::UglifierCompressor
- Sprockets::UnloadedAsset
- Sprockets::Utils
- Sprockets::YUICompressor
- Rake
- Rake::SprocketsTask

No matching classes.

# 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 which 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 `assets` and `files` for more infomation about the structure.

### Attributes

dir[R]
directory[R]
environment[R]
filename[R]

Returns String path to manifest.json file.

path[R]

Returns String path to manifest.json file.

### Public Class Methods

compile_match_filter(filter) click to toggle source

Deprecated: Compile logical path matching filter into a proc that can be passed to logical_paths.select(&proc).

    compile_match_filter(proc { |logical_path|
      File.extname(logical_path) == '.js'
    })

    compile_match_filter(/application.js/)

    compile_match_filter("foo/*.js")

Returns a Proc or raise a TypeError.

    # File lib/sprockets/legacy.rb, line 279
    def self.compile_match_filter(filter)
      # If the filter is already a proc, great nothing to do.
      if filter.respond_to?(:call)
        filter
      # If the filter is a regexp, wrap it in a proc that tests it against the
      # logical path.
      elsif filter.is_a?(Regexp)
        proc { |logical_path| filter.match(logical_path) }
      elsif filter.is_a?(String)
        # If its an absolute path, detect the matching full filename
        if PathUtils.absolute_path?(filter)
          proc { |logical_path, filename| filename == filter.to_s }
        else
          # Otherwise do an fnmatch against the logical path.
          proc { |logical_path| File.fnmatch(filter.to_s, logical_path) }
        end
      else
        raise TypeError, "unknown filter type: #{filter.inspect}"
      end
    end

compute_alias_logical_path(path) click to toggle source

    # File lib/sprockets/legacy.rb, line 306
    def self.compute_alias_logical_path(path)
      dirname, basename = File.split(path)
      extname = File.extname(basename)
      if File.basename(basename, extname) == 'index'
        "#{dirname}#{extname}"
      else
        nil
      end
    end

new(*args) click to toggle source

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

    Manifest.new(environment, "./public/assets/manifest.json")

    # File lib/sprockets/manifest.rb, line 28
    def initialize(*args)
      if args.first.is_a?(Base) || args.first.nil?
        @environment = args.shift
      end

      @directory, @filename = args[0], args[1]

      # Whether the manifest file is using the old manifest-*.json naming convention
      @legacy_manifest = false

      # Expand paths
      @directory = File.expand_path(@directory) if @directory
      @filename  = File.expand_path(@filename) if @filename

      # If filename is given as the second arg
      if @directory && File.extname(@directory) != ""
        @directory, @filename = nil, @directory
      end

      # Default dir to the directory of the filename
      @directory ||= File.dirname(@filename) if @filename

      # If directory is given w/o filename, pick a random manifest location
      @rename_filename = nil
      if @directory && @filename.nil?
        @filename = find_directory_manifest(@directory)

        # If legacy manifest name autodetected, mark to rename on save
        if File.basename(@filename).start_with?("manifest")
          @rename_filename = File.join(@directory, generate_manifest_path)
        end
      end

      unless @directory && @filename
        raise ArgumentError, "manifest requires output filename"
      end

      data = {}

      begin
        if File.exist?(@filename)
          data = json_decode(File.read(@filename))
        end
      rescue JSON::ParserError => e
        logger.error "#{@filename} is invalid: #{e.class} #{e.message}"
      end

      @data = data
    end

simple_logical_path?(str) click to toggle source

    # File lib/sprockets/legacy.rb, line 300
    def self.simple_logical_path?(str)
      str.is_a?(String) &&
        !PathUtils.absolute_path?(str) &&
        str !~ /\*|\*\*|\?|\[|\]|\{|\}/
    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 93
    def assets
      @data['assets'] ||= {}
    end

clean(count = 2, age = 3600) click to toggle source

Cleanup old assets in the compile directory. By default it will keep the latest version, 2 backups and any created within the past hour.

Examples

    To force only 1 backup to be kept, set count=1 and age=0.

    To only keep files created within the last 10 minutes, set count=0 and
    age=600.

    # File lib/sprockets/manifest.rb, line 229
    def clean(count = 2, age = 3600)
      asset_versions = files.group_by { |_, attrs| attrs['logical_path'] }

      asset_versions.each do |logical_path, versions|
        current = assets[logical_path]

        versions.reject { |path, _|
          path == current
        }.sort_by { |_, attrs|
          # Sort by timestamp
          Time.parse(attrs['mtime'])
        }.reverse.each_with_index.drop_while { |(_, attrs), index|
          _age = [0, Time.now - Time.parse(attrs['mtime'])].max
          # Keep if under age or within the count limit
          _age < age || index < count
        }.each { |(path, _), _|
           # Remove old assets
          remove(path)
        }
      end
    end

clobber() click to toggle source

Wipe directive

    # File lib/sprockets/manifest.rb, line 252
    def clobber
      FileUtils.rm_r(directory) if File.exist?(directory)
      logger.info "Removed #{directory}"
      nil
    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 155
    def compile(*args)
      unless environment
        raise Error, "manifest requires environment for compilation"
      end

      filenames = []

      find(*args) do |asset|
        files[asset.digest_path] = {
          'logical_path' => asset.logical_path,
          'mtime'        => asset.mtime.iso8601,
          'size'         => asset.bytesize,
          'digest'       => asset.hexdigest,

          # Deprecated: Remove beta integrity attribute in next release.
          # Callers should DigestUtils.hexdigest_integrity_uri to compute the
          # digest themselves.
          'integrity'    => DigestUtils.hexdigest_integrity_uri(asset.hexdigest)
        }
        assets[asset.logical_path] = asset.digest_path

        if alias_logical_path = self.class.compute_alias_logical_path(asset.logical_path)
          assets[alias_logical_path] = asset.digest_path
        end

        target = File.join(dir, asset.digest_path)

        if File.exist?(target)
          logger.debug "Skipping #{target}, already exists"
        else
          logger.info "Writing #{target}"
          asset.write_to target
        end

        filenames << asset.filename
      end
      save

      filenames
    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 110
    def files
      @data['files'] ||= {}
    end

filter_logical_paths(*args) click to toggle source

Deprecated: Filter logical paths in environment. Useful for selecting what files you want to compile.

Returns an Enumerator.

    # File lib/sprockets/legacy.rb, line 320
    def filter_logical_paths(*args)
      filters = args.flatten.map { |arg| self.class.compile_match_filter(arg) }
      environment.cached.logical_paths.select do |a, b|
        filters.any? { |f| f.call(a, b) }
      end
    end

Also aliased as: find_logical_paths
find(*args) click to toggle source

Public: Find all assets matching pattern set in environment.

Returns Enumerator of Assets.

    # File lib/sprockets/manifest.rb, line 117
    def find(*args)
      unless environment
        raise Error, "manifest requires environment for compilation"
      end

      return to_enum(__method__, *args) unless block_given?

      paths, filters = args.flatten.partition { |arg| self.class.simple_logical_path?(arg) }
      filters = filters.map { |arg| self.class.compile_match_filter(arg) }

      environment = self.environment.cached

      paths.each do |path|
        environment.find_all_linked_assets(path) do |asset|
          yield asset
        end
      end

      if filters.any?
        environment.logical_paths do |logical_path, filename|
          if filters.any? { |f| f.call(logical_path, filename) }
            environment.find_all_linked_assets(filename) do |asset|
              yield asset
            end
          end
        end
      end

      nil
    end

find_logical_paths(*args) click to toggle source

Deprecated alias.

Alias for: filter_logical_paths
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 201
    def remove(filename)
      path = File.join(dir, filename)
      logical_path = files[filename]['logical_path']

      if assets[logical_path] == filename
        assets.delete(logical_path)
      end

      files.delete(filename)
      FileUtils.rm(path) if File.exist?(path)

      save

      logger.info "Removed #{filename}"

      nil
    end

save() click to toggle source

Persist manfiest back to FS

    # File lib/sprockets/manifest.rb, line 259
    def save
      if @rename_filename
        logger.info "Renaming #{@filename} to #{@rename_filename}"
        FileUtils.mv(@filename, @rename_filename)
        @filename = @rename_filename
        @rename_filename = nil
      end

      data = json_encode(@data)
      FileUtils.mkdir_p File.dirname(@filename)
      PathUtils.atomic_write(@filename) do |f|
        f.write(data)
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.