[DRE-commits] [ruby-sprockets] 01/03: New upstream version 3.7.0

Rahulkrishnan R A rahulkrishnanra-guest at moszumanska.debian.org
Sat Aug 27 08:07:57 UTC 2016


This is an automated email from the git hooks/post-receive script.

rahulkrishnanra-guest pushed a commit to branch master
in repository ruby-sprockets.

commit 738a773f70ba66a9d225994e0d20c63b1af2fb5c
Author: Rahulkrishnan R A <rahulkrishnanfs at gmail.com>
Date:   Sat Aug 27 07:55:17 2016 +0000

    New upstream version 3.7.0
---
 CHANGELOG.md                            |  68 ++++++-
 README.md                               |  48 +++++
 lib/sprockets.rb                        |  27 ++-
 lib/sprockets/base.rb                   |   9 +
 lib/sprockets/cache.rb                  |   4 +-
 lib/sprockets/cache/file_store.rb       |  11 +-
 lib/sprockets/coffee_script_template.rb |  13 +-
 lib/sprockets/compressing.rb            |  20 ++
 lib/sprockets/deprecation.rb            |  90 +++++++++
 lib/sprockets/digest_utils.rb           |  84 +++++----
 lib/sprockets/eco_template.rb           |  13 +-
 lib/sprockets/ejs_template.rb           |  13 +-
 lib/sprockets/engines.rb                |  11 ++
 lib/sprockets/erb_template.rb           |   7 +-
 lib/sprockets/legacy_tilt_processor.rb  |   2 +-
 lib/sprockets/loader.rb                 | 278 ++++++++++------------------
 lib/sprockets/manifest.rb               |  48 ++++-
 lib/sprockets/path_utils.rb             |  35 ++--
 lib/sprockets/processing.rb             |  10 +
 lib/sprockets/processor_utils.rb        |  15 +-
 lib/sprockets/resolve.rb                |   2 +
 lib/sprockets/sass_cache_store.rb       |   7 +-
 lib/sprockets/sass_processor.rb         |  18 +-
 lib/sprockets/sass_template.rb          |  16 +-
 lib/sprockets/uglifier_compressor.rb    |   2 +-
 lib/sprockets/unloaded_asset.rb         | 137 ++++++++++++++
 lib/sprockets/uri_tar.rb                |  98 ++++++++++
 lib/sprockets/utils.rb                  |  35 ++--
 lib/sprockets/utils/gzip.rb             |  67 +++++++
 lib/sprockets/version.rb                |   2 +-
 metadata.yml                            | 317 --------------------------------
 sprockets.gemspec                       |  78 ++++++++
 32 files changed, 992 insertions(+), 593 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2304b62..23bc55e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,72 @@
+** 3.7.0** (July 21, 2016)
+
+* Deprecated interfaces now emit deprecation warnings #345
+
+**3.6.3** (July 1, 2016)
+
+* Faster asset lookup in large directories #336
+* Faster PathUtils.match_path_extname https://github.com/rails/sprockets/commit/697269cf81e5261fdd7072e32bd489403027fd7e
+* Fixed uglifier comment stripping #326
+* Error messages now show load path info #313
+
+**3.6.2** (June 21, 2016)
+
+* More performance improvements.
+
+**3.6.1** (June 17, 2016)
+
+* Some performance improvements.
+
+**3.6.0** (April 6, 2016)
+
+* Add `Manifest#find_sources` to return the source of the compiled assets.
+* Fix the list of compressable mime types.
+* Improve performance of the `FileStore` cache.
+
+**3.5.2** (December 8, 2015)
+
+* Fix JRuby bug with concurrent-ruby.
+* Fix disabling gzip generation in cached environments.
+
+**3.5.1** (December 5, 2015)
+
+* Fix gzip asset generation for assets already on disk.
+
+**3.5.0** (December 3, 2015)
+
+* Reintroduce Gzip file generation for non-binary assets.
+
+**3.4.1** (November 25, 2015)
+
+* PathUtils::Entries will no longer error on an empty directory.
+
+**3.4.0** (October 5, 2015)
+
+* Expose method to override the sass cache in the SassProcessor.
+
+**3.3.5** (September 25, 2015)
+
+* Fix bug related to absolute path being reintroduced into history cache #141.
+
+**3.3.4** (September 1, 2015)
+
+* Relative cache contents now work with windows.
+
+**3.3.3** (August 21, 2015)
+
+* Remove more absolute paths from cache contents.
+
+**3.3.2** (August 19, 2015)
+
+* Fix cache contents to use relative paths instead of absolute paths.
+
+**3.3.1** (August 15, 2015)
+
+* Fix legacy Tilt integration when locals is required argument.
+
 **3.3.0** (August 12, 2015)
 
-* Change internal cache lookup to use relative asset paths instead of absolute paths.
+* Change internal cache key to use relative asset paths instead of absolute paths.
 
 **3.2.0** (June 2, 2015)
 
diff --git a/README.md b/README.md
index f7dbb81..e2aa0b0 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,54 @@ Or include it in your project's `Gemfile` with Bundler:
 gem 'sprockets', '~> 3.0'
 ```
 
+## Using sprockets
+
+For most people interested in using sprockets you will want to see [End User Asset Generation](guides/end_user_asset_generation.md) guide. This contains information about sprocket's directive syntax, and default processing behavior.
+
+If you are a framework developer that is using sprockets, see [Building an Asset Processing Framework](guides/building_an_asset_processing_framework.md).
+
+If you are a library developer who is extending the functionality of sprockets, see [Extending Sprockets](guides/extending_sprockets.md).
+
+Below is a disjointed mix of documentation for all three of these roles. Eventually they will be moved to an appropriate guide, for now the recommended way to consume documentation is to view the appropriate guide first and then supplement with docs from the README.
+
+## Behavior
+
+### Index files are proxies for folders
+
+In sprockets index files such as `index.js` or `index.css` files inside of a folder will generate a file with the folder's name. So if you have a `foo/index.js` file it will compile down to `foo.js`. This is similar to NPM's behavior of using [folders as modules](https://nodejs.org/api/modules.html#modules_folders_as_modules). It is also somewhat similar to the way that a file in `public/my_folder/index.html` can be reached by a request to `/my_folder`. This means that you cannot directl [...]
+
+```
+<%= asset_path("foo/index.js") %>
+```
+
+Instead you would need to use:
+
+```
+<%= asset_path("foo.js") %>
+```
+
+Why would you want to use this behavior?  It is common behavior where you might want to include an entire directory of files in a top level javascript. You can do this in sprockets using `require_tree .`
+
+```
+//= require_tree .
+```
+
+This has the problem that files are required alphabetically. If your directory has `jquery-ui.js` and `jquery.min.js` then sprockets will require `jquery-ui.js` before `jquery` is required which won't work (because jquery-ui depends on jquery). Previously the only way to get the correct ordering would be to rename your files, something like `0-jquery-ui.js`. Instead of doing that you can use an index file.
+
+For example, if you have an `application.js` and want all the files in the `foo/` folder you could do this:
+
+```
+//= require foo.js
+```
+
+Then create a file `foo/index.js` that requires all the files in that folder in any order you want:
+
+```
+//= require foo.min.js
+//= require foo-ui.js
+```
+
+Now in your `application.js` will correctly load the `foo.min.js` before `foo-ui.js`. If you used `require_tree` it would not work correctly.
 
 ## Understanding the Sprockets Environment
 
diff --git a/lib/sprockets.rb b/lib/sprockets.rb
index cacb559..5f0b0c7 100644
--- a/lib/sprockets.rb
+++ b/lib/sprockets.rb
@@ -4,6 +4,7 @@ require 'sprockets/cache'
 require 'sprockets/environment'
 require 'sprockets/errors'
 require 'sprockets/manifest'
+require 'sprockets/deprecation'
 
 module Sprockets
   require 'sprockets/processor_utils'
@@ -33,7 +34,8 @@ module Sprockets
     registered_transformers: Hash.new { |h, k| {}.freeze }.freeze,
     root: File.expand_path('..', __FILE__).freeze,
     transformers: Hash.new { |h, k| {}.freeze }.freeze,
-    version: ""
+    version: "",
+    gzip_enabled: true
   }.freeze
   self.computed_config = {}
 
@@ -75,6 +77,7 @@ module Sprockets
 
   # Common font types
   register_mime_type 'application/vnd.ms-fontobject', extensions: ['.eot']
+  register_mime_type 'application/x-font-opentype', extensions: ['.otf']
   register_mime_type 'application/x-font-ttf', extensions: ['.ttf']
   register_mime_type 'application/font-woff', extensions: ['.woff']
 
@@ -120,31 +123,37 @@ module Sprockets
 
   # Mmm, CoffeeScript
   require 'sprockets/coffee_script_processor'
-  register_engine '.coffee', CoffeeScriptProcessor, mime_type: 'application/javascript'
+  Deprecation.silence do
+    register_engine '.coffee', CoffeeScriptProcessor, mime_type: 'application/javascript', silence_deprecation: true
+  end
 
   # JST engines
   require 'sprockets/eco_processor'
   require 'sprockets/ejs_processor'
   require 'sprockets/jst_processor'
-  register_engine '.jst', JstProcessor, mime_type: 'application/javascript'
-  register_engine '.eco', EcoProcessor, mime_type: 'application/javascript'
-  register_engine '.ejs', EjsProcessor, mime_type: 'application/javascript'
+  Deprecation.silence do
+    register_engine '.jst', JstProcessor, mime_type: 'application/javascript', silence_deprecation: true
+    register_engine '.eco', EcoProcessor, mime_type: 'application/javascript', silence_deprecation: true
+    register_engine '.ejs', EjsProcessor, mime_type: 'application/javascript', silence_deprecation: true
+  end
 
   # CSS engines
   require 'sprockets/sass_processor'
-  register_engine '.sass', SassProcessor, mime_type: 'text/css'
-  register_engine '.scss', ScssProcessor, mime_type: 'text/css'
+  Deprecation.silence do
+    register_engine '.sass', SassProcessor, mime_type: 'text/css', silence_deprecation: true
+    register_engine '.scss', ScssProcessor, mime_type: 'text/css', silence_deprecation: true
+  end
   register_bundle_metadata_reducer 'text/css', :sass_dependencies, Set.new, :+
 
   # Other
   require 'sprockets/erb_processor'
-  register_engine '.erb', ERBProcessor, mime_type: 'text/plain'
+  register_engine '.erb', ERBProcessor, mime_type: 'text/plain', silence_deprecation: true
 
   register_dependency_resolver 'environment-version' do |env|
     env.version
   end
   register_dependency_resolver 'environment-paths' do |env|
-    env.paths
+    env.paths.map {|path| env.compress_from_root(path) }
   end
   register_dependency_resolver 'file-digest' do |env, str|
     env.file_digest(env.parse_file_digest_uri(str))
diff --git a/lib/sprockets/base.rb b/lib/sprockets/base.rb
index 930e9ee..e5b61d7 100644
--- a/lib/sprockets/base.rb
+++ b/lib/sprockets/base.rb
@@ -11,6 +11,7 @@ require 'sprockets/path_utils'
 require 'sprockets/resolve'
 require 'sprockets/server'
 require 'sprockets/loader'
+require 'sprockets/uri_tar'
 
 module Sprockets
   # `Base` class for `Environment` and `Cached`.
@@ -97,5 +98,13 @@ module Sprockets
         "root=#{root.to_s.inspect}, " +
         "paths=#{paths.inspect}>"
     end
+
+    def compress_from_root(uri)
+      URITar.new(uri, self).compress
+    end
+
+    def expand_from_root(uri)
+      URITar.new(uri, self).expand
+    end
   end
 end
diff --git a/lib/sprockets/cache.rb b/lib/sprockets/cache.rb
index aebf237..5958f64 100644
--- a/lib/sprockets/cache.rb
+++ b/lib/sprockets/cache.rb
@@ -153,7 +153,9 @@ module Sprockets
       #
       # Returns a String with a length less than 250 characters.
       def expand_key(key)
-        "sprockets/v#{VERSION}/#{DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))}"
+        digest_key = DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))
+        namespace = digest_key[0, 2]
+        "sprockets/v#{VERSION}/#{namespace}/#{digest_key}"
       end
 
       PEEK_SIZE = 100
diff --git a/lib/sprockets/cache/file_store.rb b/lib/sprockets/cache/file_store.rb
index 7b4f6fb..98e777a 100644
--- a/lib/sprockets/cache/file_store.rb
+++ b/lib/sprockets/cache/file_store.rb
@@ -36,7 +36,6 @@ module Sprockets
       #            (default: 1000).
       def initialize(root, max_size = DEFAULT_MAX_SIZE, logger = self.class.default_logger)
         @root     = root
-        @size     = find_caches.inject(0) { |n, (_, stat)| n + stat.size }
         @max_size = max_size
         @gc_size  = max_size * 0.75
         @logger   = logger
@@ -107,11 +106,11 @@ module Sprockets
         # Write data
         PathUtils.atomic_write(path) do |f|
           f.write(raw)
-          @size += f.size unless exists
+          @size = size + f.size unless exists
         end
 
         # GC if necessary
-        gc! if @size > @max_size
+        gc! if size > @max_size
 
         value
       end
@@ -120,7 +119,7 @@ module Sprockets
       #
       # Returns String.
       def inspect
-        "#<#{self.class} size=#{@size}/#{@max_size}>"
+        "#<#{self.class} size=#{size}/#{@max_size}>"
       end
 
       private
@@ -138,6 +137,10 @@ module Sprockets
           }.sort_by { |_, stat| stat.mtime.to_i }
         end
 
+        def size
+          @size ||= compute_size(find_caches)
+        end
+
         def compute_size(caches)
           caches.inject(0) { |sum, (_, stat)| sum + stat.size }
         end
diff --git a/lib/sprockets/coffee_script_template.rb b/lib/sprockets/coffee_script_template.rb
index 5c014ed..c4bd96f 100644
--- a/lib/sprockets/coffee_script_template.rb
+++ b/lib/sprockets/coffee_script_template.rb
@@ -2,5 +2,16 @@ require 'sprockets/coffee_script_processor'
 
 module Sprockets
   # Deprecated
-  CoffeeScriptTemplate = CoffeeScriptProcessor
+  module CoffeeScriptTemplate
+    VERSION = CoffeeScriptProcessor::VERSION
+
+    def self.cache_key
+      CoffeeScriptProcessor.cache_key
+    end
+
+    def self.call(*args)
+      Deprecation.new.warn "CoffeeScriptTemplate is deprecated please use CoffeeScriptProcessor instead"
+      CoffeeScriptProcessor.call(*args)
+    end
+  end
 end
diff --git a/lib/sprockets/compressing.rb b/lib/sprockets/compressing.rb
index f65cb6d..caf8baf 100644
--- a/lib/sprockets/compressing.rb
+++ b/lib/sprockets/compressing.rb
@@ -70,5 +70,25 @@ module Sprockets
 
       register_bundle_processor 'application/javascript', klass
     end
+
+    # Public: Checks if Gzip is enabled.
+    def gzip?
+      config[:gzip_enabled]
+    end
+
+    # Public: Checks if Gzip is disabled.
+    def skip_gzip?
+      !gzip?
+    end
+
+    # Public: Enable or disable the creation of Gzip files.
+    #
+    # Defaults to true.
+    #
+    #     environment.gzip = false
+    #
+    def gzip=(gzip)
+      self.config = config.merge(gzip_enabled: gzip).freeze
+    end
   end
 end
diff --git a/lib/sprockets/deprecation.rb b/lib/sprockets/deprecation.rb
new file mode 100644
index 0000000..69e41e9
--- /dev/null
+++ b/lib/sprockets/deprecation.rb
@@ -0,0 +1,90 @@
+module Sprockets
+  class Deprecation
+    THREAD_LOCAL__SILENCE_KEY = "_sprockets_deprecation_silence".freeze
+    DEFAULT_BEHAVIORS = {
+      raise: ->(message, callstack) {
+        e = DeprecationException.new(message)
+        e.set_backtrace(callstack.map(&:to_s))
+        raise e
+      },
+
+      stderr: ->(message, callstack) {
+        $stderr.puts(message)
+      },
+    }
+
+    attr_reader :callstack
+
+    def self.silence(&block)
+      Thread.current[THREAD_LOCAL__SILENCE_KEY] = true
+      block.call
+    ensure
+      Thread.current[THREAD_LOCAL__SILENCE_KEY] = false
+    end
+
+    def initialize(callstack = nil)
+      @callstack = callstack || caller(2)
+    end
+
+    def warn(message)
+      return if Thread.current[THREAD_LOCAL__SILENCE_KEY]
+      deprecation_message(message).tap do |m|
+        behavior.each { |b| b.call(m, callstack) }
+      end
+    end
+
+    private
+      def behavior
+        @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
+      end
+
+      def behavior=(behavior)
+        @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
+      end
+
+      def deprecation_message(message = nil)
+        message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
+        "DEPRECATION WARNING: #{message} #{ deprecation_caller_message }"
+      end
+
+      def deprecation_caller_message
+        file, line, method = extract_callstack
+        if file
+          if line && method
+            "(called from #{method} at #{file}:#{line})"
+          else
+            "(called from #{file}:#{line})"
+          end
+        end
+      end
+
+      SPROCKETS_GEM_ROOT = File.expand_path("../../../../..", __FILE__) + "/"
+
+      def ignored_callstack(path)
+        path.start_with?(SPROCKETS_GEM_ROOT) || path.start_with?(RbConfig::CONFIG['rubylibdir'])
+      end
+
+      def extract_callstack
+        return _extract_callstack if callstack.first.is_a? String
+
+        offending_line = callstack.find { |frame|
+          frame.absolute_path && !ignored_callstack(frame.absolute_path)
+        } || callstack.first
+
+        [offending_line.path, offending_line.lineno, offending_line.label]
+      end
+
+      def _extract_callstack
+        offending_line = callstack.find { |line| !ignored_callstack(line) } || callstack.first
+
+        if offending_line
+          if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
+            md.captures
+          else
+            offending_line
+          end
+        end
+      end
+  end
+  private_constant :Deprecation
+end
diff --git a/lib/sprockets/digest_utils.rb b/lib/sprockets/digest_utils.rb
index 1195e2a..2551941 100644
--- a/lib/sprockets/digest_utils.rb
+++ b/lib/sprockets/digest_utils.rb
@@ -34,6 +34,50 @@ module Sprockets
       DIGEST_SIZES[bytes.bytesize]
     end
 
+    ADD_VALUE_TO_DIGEST = {
+      String     => ->(val, digest) { digest << val },
+      FalseClass => ->(val, digest) { digest << 'FalseClass'.freeze },
+      TrueClass  => ->(val, digest) { digest << 'TrueClass'.freeze  },
+      NilClass   => ->(val, digest) { digest << 'NilClass'.freeze   },
+
+      Symbol => ->(val, digest) {
+        digest << 'Symbol'.freeze
+        digest << val.to_s
+      },
+      Fixnum => ->(val, digest) {
+        digest << 'Fixnum'.freeze
+        digest << val.to_s
+      },
+      Bignum => ->(val, digest) {
+        digest << 'Bignum'.freeze
+        digest << val.to_s
+      },
+      Array => ->(val, digest) {
+        digest << 'Array'.freeze
+        val.each do |element|
+          ADD_VALUE_TO_DIGEST[element.class].call(element, digest)
+        end
+      },
+      Hash => ->(val, digest) {
+        digest << 'Hash'.freeze
+        val.sort.each do |array|
+          ADD_VALUE_TO_DIGEST[Array].call(array, digest)
+        end
+      },
+      Set => ->(val, digest) {
+        digest << 'Set'.freeze
+        ADD_VALUE_TO_DIGEST[Array].call(val.to_a, digest)
+      },
+      Encoding => ->(val, digest) {
+        digest << 'Encoding'.freeze
+        digest << val.name
+      },
+    }
+    ADD_VALUE_TO_DIGEST.default_proc = ->(_, val) {
+      raise TypeError, "couldn't digest #{ val }"
+    }
+    private_constant :ADD_VALUE_TO_DIGEST
+
     # Internal: Generate a hexdigest for a nested JSON serializable object.
     #
     # This is used for generating cache keys, so its pretty important its
@@ -44,46 +88,8 @@ module Sprockets
     # Returns a String digest of the object.
     def digest(obj)
       digest = digest_class.new
-      queue  = [obj]
-
-      while queue.length > 0
-        obj = queue.shift
-        klass = obj.class
-
-        if klass == String
-          digest << obj
-        elsif klass == Symbol
-          digest << 'Symbol'
-          digest << obj.to_s
-        elsif klass == Fixnum
-          digest << 'Fixnum'
-          digest << obj.to_s
-        elsif klass == Bignum
-          digest << 'Bignum'
-          digest << obj.to_s
-        elsif klass == TrueClass
-          digest << 'TrueClass'
-        elsif klass == FalseClass
-          digest << 'FalseClass'
-        elsif klass == NilClass
-          digest << 'NilClass'.freeze
-        elsif klass == Array
-          digest << 'Array'
-          queue.concat(obj)
-        elsif klass == Hash
-          digest << 'Hash'
-          queue.concat(obj.sort)
-        elsif klass == Set
-          digest << 'Set'
-          queue.concat(obj.to_a)
-        elsif klass == Encoding
-          digest << 'Encoding'
-          digest << obj.name
-        else
-          raise TypeError, "couldn't digest #{klass}"
-        end
-      end
 
+      ADD_VALUE_TO_DIGEST[obj.class].call(obj, digest)
       digest.digest
     end
 
diff --git a/lib/sprockets/eco_template.rb b/lib/sprockets/eco_template.rb
index d2ab4f0..7c678d4 100644
--- a/lib/sprockets/eco_template.rb
+++ b/lib/sprockets/eco_template.rb
@@ -2,5 +2,16 @@ require 'sprockets/eco_processor'
 
 module Sprockets
   # Deprecated
-  EcoTemplate = EcoProcessor
+  module EcoTemplate
+    VERSION = EcoProcessor::VERSION
+
+    def self.cache_key
+      EcoProcessor.cache_key
+    end
+
+    def self.call(*args)
+      Deprecation.new.warn "EcoTemplate is deprecated please use EcoProcessor instead"
+      EcoProcessor.call(*args)
+    end
+  end
 end
diff --git a/lib/sprockets/ejs_template.rb b/lib/sprockets/ejs_template.rb
index d882cd3..d1acd82 100644
--- a/lib/sprockets/ejs_template.rb
+++ b/lib/sprockets/ejs_template.rb
@@ -2,5 +2,16 @@ require 'sprockets/ejs_processor'
 
 module Sprockets
   # Deprecated
-  EjsTemplate = EjsProcessor
+  module EjsTemplate
+    VERSION = EjsProcessor::VERSION
+
+    def self.cache_key
+      EjsProcessor.cache_key
+    end
+
+    def self.call(*args)
+      Deprecation.new.warn "EjsTemplate is deprecated please use EjsProcessor instead"
+      EjsProcessor.call(*args)
+    end
+  end
 end
diff --git a/lib/sprockets/engines.rb b/lib/sprockets/engines.rb
index 0c9f274..09a1637 100644
--- a/lib/sprockets/engines.rb
+++ b/lib/sprockets/engines.rb
@@ -51,6 +51,17 @@ module Sprockets
     #     environment.register_engine '.coffee', CoffeeScriptProcessor
     #
     def register_engine(ext, klass, options = {})
+      unless options[:silence_deprecation]
+        msg = <<-MSG
+Sprockets method `register_engine` is deprecated.
+Please register a mime type using `register_mime_type` then
+use `register_compressor` or `register_transformer`.
+https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
+        MSG
+
+        Deprecation.new([caller.first]).warn(msg)
+      end
+
       ext = Sprockets::Utils.normalize_extension(ext)
 
       self.computed_config = {}
diff --git a/lib/sprockets/erb_template.rb b/lib/sprockets/erb_template.rb
index 8e5436e..789830f 100644
--- a/lib/sprockets/erb_template.rb
+++ b/lib/sprockets/erb_template.rb
@@ -2,5 +2,10 @@ require 'sprockets/erb_processor'
 
 module Sprockets
   # Deprecated
-  ERBTemplate = ERBProcessor
+  class ERBTemplate < ERBProcessor
+    def call(*args)
+      Deprecation.new.warn "ERBTemplate is deprecated please use ERBProcessor instead"
+      super
+    end
+  end
 end
diff --git a/lib/sprockets/legacy_tilt_processor.rb b/lib/sprockets/legacy_tilt_processor.rb
index 46244ca..97272bd 100644
--- a/lib/sprockets/legacy_tilt_processor.rb
+++ b/lib/sprockets/legacy_tilt_processor.rb
@@ -22,7 +22,7 @@ module Sprockets
       data     = input[:data]
       context  = input[:environment].context_class.new(input)
 
-      data = @klass.new(filename) { data }.render(context)
+      data = @klass.new(filename) { data }.render(context, {})
       context.metadata.merge(data: data.to_str)
     end
   end
diff --git a/lib/sprockets/loader.rb b/lib/sprockets/loader.rb
index 13de93f..d39e0c7 100644
--- a/lib/sprockets/loader.rb
+++ b/lib/sprockets/loader.rb
@@ -10,156 +10,10 @@ require 'sprockets/processor_utils'
 require 'sprockets/resolve'
 require 'sprockets/transformers'
 require 'sprockets/uri_utils'
+require 'sprockets/unloaded_asset'
 
 module Sprockets
 
-  # Internal: Used to parse and store the URI to an unloaded asset
-  # Generates keys used to store and retrieve items from cache
-  class UnloadedAsset
-
-    # Internal: Initialize object for generating cache keys
-    #
-    # uri - A String containing complete URI to a file including schema
-    #       and full path such as
-    #       "file:///Path/app/assets/js/app.js?type=application/javascript"
-    # env - The current "environment" that assets are being loaded into.
-    #       We need it so we know where the +root+ (directory where sprockets
-    #       is being invoked). We also need for the `file_digest` method,
-    #       since, for some strange reason, memoization is provided by
-    #       overriding methods such as `stat` in the `PathUtils` module.
-    #
-    # Returns UnloadedAsset.
-    def initialize(uri, env)
-      @uri             = uri
-      @env             = env
-      @root            = env.root
-      @relative_path   = get_relative_path_from_uri
-      @params          = nil # lazy loaded
-      @filename        = nil # lazy loaded
-    end
-    attr_reader :relative_path, :root, :uri
-
-
-    # Internal: Full file path without schema
-    #
-    # This returns a string containing the full path to the asset without the schema.
-    # Information is loaded lazilly since we want `UnloadedAsset.new(dep, self).relative_path`
-    # to be fast. Calling this method the first time allocates an array and a hash.
-    #
-    # Example
-    #
-    # If the URI is `file:///Full/path/app/assets/javascripts/application.js"` then the
-    # filename would be `"/Full/path/app/assets/javascripts/application.js"`
-    #
-    # Returns a String.
-    def filename
-      unless @filename
-        load_file_params
-      end
-      @filename
-    end
-
-    # Internal: Hash of param values
-    #
-    # This information is generated and used internally by sprockets.
-    # Known keys include `:type` which store the asset's mime-type, `:id` which is a fully resolved
-    # digest for the asset (includes dependency digest as opposed to a digest of only file contents)
-    # and `:pipeline`. Hash may be empty.
-    #
-    # Example
-    #
-    # If the URI is `file:///Full/path/app/assets/javascripts/application.js"type=application/javascript`
-    # Then the params would be `{type: "application/javascript"}`
-    #
-    # Returns a Hash.
-    def params
-      unless @params
-        load_file_params
-      end
-      @params
-    end
-
-    # Internal: Key of asset
-    #
-    # Used to retrieve an asset from the cache based on relative path to asset
-    #
-    # Returns a String.
-    def asset_key
-      "asset-uri:#{relative_path}"
-    end
-
-    # Public: Dependency History key
-    #
-    # Used to retrieve an array of "histories" each of which contain a set of stored dependencies
-    # for a given asset path and filename digest.
-    #
-    # A dependency can refer to either an asset i.e. index.js
-    # may rely on jquery.js (so jquery.js is a dependency), or other factors that may affect
-    # compilation, such as the VERSION of sprockets (i.e. the environment) and what "processors"
-    # are used.
-    #
-    # For example a history array with one Set of dependencies may look like:
-    #
-    # [["environment-version", "environment-paths", "processors:type=text/css&file_type=text/css",
-    #   "file-digest:///Full/path/app/assets/stylesheets/application.css",
-    #   "processors:type=text/css&file_type=text/css&pipeline=self",
-    #   "file-digest:///Full/path/app/assets/stylesheets"]]
-    #
-    # This method of asset lookup is used to ensure that none of the dependencies have been modified
-    # since last lookup. If one of them has, the key will be different and a new entry must be stored.
-    #
-    # URI depndencies are later converted to relative paths
-    #
-    # Returns a String.
-    def dependency_history_key
-      "asset-uri-cache-dependencies:#{relative_path}:#{ @env.file_digest(filename) }"
-    end
-
-    # Internal: Digest key
-    #
-    # Used to retrieve a string containing the relative path to an asset based on
-    # a digest. The digest is generated from dependencies stored via information stored in
-    # the `dependency_history_key` after each of the "dependencies" is "resolved" for example
-    # "environment-version" may be resolved to "environment-1.0-3.2.0" for version "3.2.0" of sprockets
-    #
-    # Returns a String.
-    def digest_key(digest)
-      "asset-uri-digest:#{relative_path}:#{digest}"
-    end
-
-    # Internal: File digest key
-    #
-    # The digest for a given file won't change if the path and the stat time hasn't changed
-    # We can save time by not re-computing this information and storing it in the cache
-    #
-    # Returns a String.
-    def file_digest_key(stat)
-      "file_digest:#{relative_path}:#{stat}"
-    end
-
-    private
-      # Internal: Parses uri into filename and params hash
-      #
-      # Returns Array with filename and params hash
-      def load_file_params
-        @filename, @params = URIUtils.parse_asset_uri(uri)
-      end
-
-      # Internal: Converts uri to a relative path
-      #
-      # Returns a relative path if given URI is in the `@env.root` of where sprockets
-      # is running. Otherwise it returns a string of the absolute path
-      #
-      # Returns a String.
-      def get_relative_path_from_uri
-        path = uri.sub(/\Afile:\/\//, "".freeze)
-        if relative_path = PathUtils.split_subpath(root, path)
-          relative_path
-        else
-          path
-        end
-      end
-  end
   # The loader phase takes a asset URI location and returns a constructed Asset
   # object.
   module Loader
@@ -178,7 +32,7 @@ module Sprockets
     def load(uri)
       unloaded = UnloadedAsset.new(uri, self)
       if unloaded.params.key?(:id)
-        unless asset = cache.get(unloaded.asset_key, true)
+        unless asset = asset_from_cache(unloaded.asset_key)
           id = unloaded.params.delete(:id)
           uri_without_id = build_asset_uri(unloaded.filename, unloaded.params)
           asset = load_from_unloaded(UnloadedAsset.new(uri_without_id, self))
@@ -200,7 +54,7 @@ module Sprockets
           if paths
             digest = DigestUtils.digest(resolve_dependencies(paths))
             if uri_from_cache = cache.get(unloaded.digest_key(digest), true)
-              cache.get(UnloadedAsset.new(uri_from_cache, self).asset_key, true)
+              asset_from_cache(UnloadedAsset.new(uri_from_cache, self).asset_key)
             end
           else
             load_from_unloaded(unloaded)
@@ -212,6 +66,32 @@ module Sprockets
 
     private
 
+      # Internal: Load asset hash from cache
+      #
+      # key - A String containing lookup information for an asset
+      #
+      # This method converts all "compressed" paths to absolute paths.
+      # Returns a hash of values representing an asset
+      def asset_from_cache(key)
+        asset = cache.get(key, true)
+        if asset
+          asset[:uri]       = expand_from_root(asset[:uri])
+          asset[:load_path] = expand_from_root(asset[:load_path])
+          asset[:filename]  = expand_from_root(asset[:filename])
+          asset[:metadata][:included].map!          { |uri| expand_from_root(uri) } if asset[:metadata][:included]
+          asset[:metadata][:links].map!             { |uri| expand_from_root(uri) } if asset[:metadata][:links]
+          asset[:metadata][:stubbed].map!           { |uri| expand_from_root(uri) } if asset[:metadata][:stubbed]
+          asset[:metadata][:required].map!          { |uri| expand_from_root(uri) } if asset[:metadata][:required]
+          asset[:metadata][:dependencies].map!      { |uri| uri.start_with?("file-digest://") ? expand_from_root(uri) : uri } if asset[:metadata][:dependencies]
+
+          asset[:metadata].each_key do |k|
+            next unless k =~ /_dependencies\z/
+            asset[:metadata][k].map! { |uri| expand_from_root(uri) }
+          end
+        end
+        asset
+      end
+
       # Internal: Loads an asset and saves it to cache
       #
       # unloaded - An UnloadedAsset
@@ -263,11 +143,10 @@ module Sprockets
           })
           validate_processor_result!(result)
           source = result.delete(:data)
-          metadata = result.merge!(
-            charset: source.encoding.name.downcase,
-            digest: digest(source),
-            length: source.bytesize
-          )
+          metadata = result
+          metadata[:charset] = source.encoding.name.downcase unless metadata.key?(:charset)
+          metadata[:digest]  = digest(source)
+          metadata[:length]  = source.bytesize
         else
           dependencies << build_file_digest_uri(unloaded.filename)
           metadata = {
@@ -303,16 +182,68 @@ module Sprockets
         }.compact.max
         asset[:mtime] ||= self.stat(unloaded.filename).mtime.to_i
 
-        # Unloaded asset and stored_asset now have a different URI
-        stored_asset = UnloadedAsset.new(asset[:uri], self)
+        store_asset(asset, unloaded)
+        asset
+      end
 
+      # Internal: Save a given asset to the cache
+      #
+      # asset - A hash containing values of loaded asset
+      # unloaded - The UnloadedAsset used to lookup the `asset`
+      #
+      # This method converts all absolute paths to "compressed" paths
+      # which are relative if they're in the root.
+      def store_asset(asset, unloaded)
         # Save the asset in the cache under the new URI
-        cache.set(stored_asset.asset_key, asset, true)
+        cached_asset             = asset.dup
+        cached_asset[:uri]       = compress_from_root(asset[:uri])
+        cached_asset[:filename]  = compress_from_root(asset[:filename])
+        cached_asset[:load_path] = compress_from_root(asset[:load_path])
+
+        if cached_asset[:metadata]
+          # Deep dup to avoid modifying `asset`
+          cached_asset[:metadata] = cached_asset[:metadata].dup
+          if cached_asset[:metadata][:included] && !cached_asset[:metadata][:included].empty?
+            cached_asset[:metadata][:included] = cached_asset[:metadata][:included].dup
+            cached_asset[:metadata][:included].map! { |uri| compress_from_root(uri) }
+          end
 
-        # Save the new relative path for the digest key of the unloaded asset
-        cache.set(unloaded.digest_key(asset[:dependencies_digest]), stored_asset.relative_path, true) # wat
+          if cached_asset[:metadata][:links] && !cached_asset[:metadata][:links].empty?
+            cached_asset[:metadata][:links] = cached_asset[:metadata][:links].dup
+            cached_asset[:metadata][:links].map! { |uri| compress_from_root(uri) }
+          end
 
-        asset
+          if cached_asset[:metadata][:stubbed] && !cached_asset[:metadata][:stubbed].empty?
+            cached_asset[:metadata][:stubbed] = cached_asset[:metadata][:stubbed].dup
+            cached_asset[:metadata][:stubbed].map! { |uri| compress_from_root(uri) }
+          end
+
+          if cached_asset[:metadata][:required] && !cached_asset[:metadata][:required].empty?
+            cached_asset[:metadata][:required] = cached_asset[:metadata][:required].dup
+            cached_asset[:metadata][:required].map! { |uri| compress_from_root(uri) }
+          end
+
+          if cached_asset[:metadata][:dependencies] && !cached_asset[:metadata][:dependencies].empty?
+            cached_asset[:metadata][:dependencies] = cached_asset[:metadata][:dependencies].dup
+            cached_asset[:metadata][:dependencies].map! do |uri|
+              uri.start_with?("file-digest://".freeze) ? compress_from_root(uri) : uri
+            end
+          end
+
+          # compress all _dependencies in metadata like `sass_dependencies`
+          cached_asset[:metadata].each do |key, value|
+            next unless key =~ /_dependencies\z/
+            cached_asset[:metadata][key] = value.dup
+            cached_asset[:metadata][key].map! {|uri| compress_from_root(uri) }
+          end
+        end
+
+        # Unloaded asset and stored_asset now have a different URI
+        stored_asset = UnloadedAsset.new(asset[:uri], self)
+        cache.set(stored_asset.asset_key, cached_asset, true)
+
+        # Save the new relative path for the digest key of the unloaded asset
+        cache.set(unloaded.digest_key(asset[:dependencies_digest]), stored_asset.compressed_path, true)
       end
 
 
@@ -334,21 +265,7 @@ module Sprockets
       #
       # Returns array of resolved dependencies
       def resolve_dependencies(uris)
-        uris.map do |uri|
-          dependency = resolve_dependency(uri)
-          case dependency
-          when Array
-            dependency.map do |dep|
-              if dep && dep.is_a?(String)
-                UnloadedAsset.new(dep, self).relative_path
-              else
-                dep
-              end
-            end
-          else
-            dependency
-          end
-        end
+        uris.map { |uri| resolve_dependency(uri) }
       end
 
       # Internal: Retrieves an asset based on its digest
@@ -368,7 +285,7 @@ module Sprockets
       #
       #   [["environment-version", "environment-paths", "processors:type=text/css&file_type=text/css",
       #     "file-digest:///Full/path/app/assets/stylesheets/application.css",
-      #     "processors:type=text/css&file_type=text/css&pipeline=self",
+      #     "processors:type=text/css&file_digesttype=text/css&pipeline=self",
       #     "file-digest:///Full/path/app/assets/stylesheets"]]
       #
       # Where the first entry is a Set of dependencies for last generated version of that asset.
@@ -388,14 +305,19 @@ module Sprockets
 
         history = cache.get(key) || []
         history.each_with_index do |deps, index|
-          if asset = yield(deps)
+          expanded_deps = deps.map do |path|
+            path.start_with?("file-digest://") ? expand_from_root(path) : path
+          end
+          if asset = yield(expanded_deps)
             cache.set(key, history.rotate!(index)) if index > 0
             return asset
           end
         end
 
         asset = yield
-        deps = asset[:metadata][:dependencies]
+        deps  = asset[:metadata][:dependencies].dup.map! do |uri|
+          uri.start_with?("file-digest://") ? compress_from_root(uri) : uri
+        end
         cache.set(key, history.unshift(deps).take(limit))
         asset
       end
diff --git a/lib/sprockets/manifest.rb b/lib/sprockets/manifest.rb
index 7ff85cd..9e6329e 100644
--- a/lib/sprockets/manifest.rb
+++ b/lib/sprockets/manifest.rb
@@ -1,6 +1,10 @@
 require 'json'
 require 'time'
+
+require 'concurrent'
+
 require 'sprockets/manifest_utils'
+require 'sprockets/utils/gzip'
 
 module Sprockets
   # The Manifest logs the contents of assets compiled to a single directory. It
@@ -145,6 +149,23 @@ module Sprockets
       nil
     end
 
+    # Public: Find the source of assets by paths.
+    #
+    # Returns Enumerator of assets file content.
+    def find_sources(*args)
+      return to_enum(__method__, *args) unless block_given?
+
+      if environment
+        find(*args).each do |asset|
+          yield asset.source
+        end
+      else
+        args.each do |path|
+          yield File.binread(File.join(dir, assets[path]))
+        end
+      end
+    end
+
     # Compile and write asset to directory. The asset is written to a
     # fingerprinted filename like
     # `application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js`. An entry is
@@ -157,7 +178,9 @@ module Sprockets
         raise Error, "manifest requires environment for compilation"
       end
 
-      filenames = []
+      filenames              = []
+      concurrent_compressors = []
+      concurrent_writers     = []
 
       find(*args) do |asset|
         files[asset.digest_path] = {
@@ -183,11 +206,28 @@ module Sprockets
           logger.debug "Skipping #{target}, already exists"
         else
           logger.info "Writing #{target}"
-          asset.write_to target
+          write_file = Concurrent::Future.execute { asset.write_to target }
+          concurrent_writers << write_file
         end
-
         filenames << asset.filename
+
+        next if environment.skip_gzip?
+        gzip = Utils::Gzip.new(asset)
+        next if gzip.cannot_compress?(environment.mime_types)
+
+        if File.exist?("#{target}.gz")
+          logger.debug "Skipping #{target}.gz, already exists"
+        else
+          logger.info "Writing #{target}.gz"
+          concurrent_compressors << Concurrent::Future.execute do
+            write_file.wait! if write_file
+            gzip.compress(target)
+          end
+        end
+
       end
+      concurrent_writers.each(&:wait!)
+      concurrent_compressors.each(&:wait!)
       save
 
       filenames
@@ -200,6 +240,7 @@ module Sprockets
     #
     def remove(filename)
       path = File.join(dir, filename)
+      gzip = "#{path}.gz"
       logical_path = files[filename]['logical_path']
 
       if assets[logical_path] == filename
@@ -208,6 +249,7 @@ module Sprockets
 
       files.delete(filename)
       FileUtils.rm(path) if File.exist?(path)
+      FileUtils.rm(gzip) if File.exist?(gzip)
 
       save
 
diff --git a/lib/sprockets/path_utils.rb b/lib/sprockets/path_utils.rb
index 2cea887..f6427fa 100644
--- a/lib/sprockets/path_utils.rb
+++ b/lib/sprockets/path_utils.rb
@@ -1,5 +1,3 @@
-require 'fileutils'
-
 module Sprockets
   # Internal: File and path related utilities. Mixed into Environment.
   #
@@ -55,9 +53,13 @@ module Sprockets
     # Returns an empty `Array` if the directory does not exist.
     def entries(path)
       if File.directory?(path)
-        Dir.entries(path, :encoding => Encoding.default_internal).reject! { |entry|
-          entry =~ /^\.|~$|^\#.*\#$/
-        }.sort!
+        entries = Dir.entries(path, :encoding => Encoding.default_internal)
+        entries.reject! { |entry|
+          entry.start_with?(".".freeze) ||
+            (entry.start_with?("#".freeze) && entry.end_with?("#".freeze)) ||
+            entry.end_with?("~".freeze)
+        }
+        entries.sort!
       else
         []
       end
@@ -146,16 +148,19 @@ module Sprockets
     #
     # Returns [String extname, Object value] or nil nothing matched.
     def match_path_extname(path, extensions)
-      match, key = nil, ""
-      path_extnames(path).reverse_each do |extname|
-        key.prepend(extname)
-        if value = extensions[key]
-          match = [key.dup, value]
-        elsif match
-          break
+      basename = File.basename(path)
+
+      i = basename.index('.'.freeze)
+      while i && i < basename.length - 1
+        extname = basename[i..-1]
+        if value = extensions[extname]
+          return extname, value
         end
+
+        i = basename.index('.'.freeze, i+1)
       end
-      match
+
+      nil
     end
 
     # Internal: Returns all parents for path
@@ -274,9 +279,9 @@ module Sprockets
         yield f
       end
 
-      FileUtils.mv(tmpname, filename)
+      File.rename(tmpname, filename)
     ensure
-      FileUtils.rm(tmpname) if File.exist?(tmpname)
+      File.delete(tmpname) if File.exist?(tmpname)
     end
   end
 end
diff --git a/lib/sprockets/processing.rb b/lib/sprockets/processing.rb
index ba2f4d1..0a8ab1d 100644
--- a/lib/sprockets/processing.rb
+++ b/lib/sprockets/processing.rb
@@ -231,14 +231,24 @@ module Sprockets
         compute_transformers!
       end
 
+      def deprecate_legacy_processor_interface(interface)
+        msg = "You are using the a deprecated processor interface #{ interface.inspect }.\n" +
+        "Please update your processor interface:\n" +
+        "https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors\n"
+
+        Deprecation.new([caller[3]]).warn msg
+      end
+
       def wrap_processor(klass, proc)
         if !proc
           if klass.respond_to?(:call)
             klass
           else
+            deprecate_legacy_processor_interface(klass)
             LegacyTiltProcessor.new(klass)
           end
         elsif proc.respond_to?(:arity) && proc.arity == 2
+          deprecate_legacy_processor_interface(proc)
           LegacyProcProcessor.new(klass.to_s, proc)
         else
           proc
diff --git a/lib/sprockets/processor_utils.rb b/lib/sprockets/processor_utils.rb
index 8bc8441..8b5e366 100644
--- a/lib/sprockets/processor_utils.rb
+++ b/lib/sprockets/processor_utils.rb
@@ -121,6 +121,17 @@ module Sprockets
       Set
     ]).freeze
 
+    # Internal: Hash of all "simple" value types allowed to be returned in
+    # processor metadata.
+    VALID_METADATA_VALUE_TYPES_HASH = VALID_METADATA_VALUE_TYPES.each_with_object({}) do |type, hash|
+      hash[type] = true
+    end.freeze
+
+    # Internal: Hash of all nested compound metadata types that can nest values.
+    VALID_METADATA_COMPOUND_TYPES_HASH = VALID_METADATA_COMPOUND_TYPES.each_with_object({}) do |type, hash|
+      hash[type] = true
+    end.freeze
+
     # Internal: Set of all allowed metadata types.
     VALID_METADATA_TYPES = (VALID_METADATA_VALUE_TYPES + VALID_METADATA_COMPOUND_TYPES).freeze
 
@@ -159,9 +170,9 @@ module Sprockets
     #
     # Returns true if class is in whitelist otherwise false.
     def valid_processor_metadata_value?(value)
-      if VALID_METADATA_VALUE_TYPES.include?(value.class)
+      if VALID_METADATA_VALUE_TYPES_HASH[value.class]
         true
-      elsif VALID_METADATA_COMPOUND_TYPES.include?(value.class)
+      elsif VALID_METADATA_COMPOUND_TYPES_HASH[value.class]
         value.all? { |v| valid_processor_metadata_value?(v) }
       else
         false
diff --git a/lib/sprockets/resolve.rb b/lib/sprockets/resolve.rb
index e240471..9ae14fb 100644
--- a/lib/sprockets/resolve.rb
+++ b/lib/sprockets/resolve.rb
@@ -60,6 +60,7 @@ module Sprockets
         end
 
         message << " with type '#{options[:accept]}'" if options[:accept]
+        message << "\nChecked in these paths: \n  #{ config[:paths].join("\n  ") }"
 
         raise FileNotFound, message
       end
@@ -177,6 +178,7 @@ module Sprockets
         candidates = []
         entries = self.entries(dirname)
         entries.each do |entry|
+          next unless File.basename(entry).start_with?(basename)
           name, type, _, _ = parse_path_extnames(entry)
           if basename == name
             candidates << [File.join(dirname, entry), type]
diff --git a/lib/sprockets/sass_cache_store.rb b/lib/sprockets/sass_cache_store.rb
index 1917b85..7c11127 100644
--- a/lib/sprockets/sass_cache_store.rb
+++ b/lib/sprockets/sass_cache_store.rb
@@ -25,5 +25,10 @@ module Sprockets
   end
 
   # Deprecated: Use Sprockets::SassProcessor::CacheStore instead.
-  SassCacheStore = SassProcessor::CacheStore
+  class SassCacheStore < SassProcessor::CacheStore
+    def initialize(*args)
+      Deprecation.new.warn "SassCacheStore is deprecated please use SassProcessor::CacheStore instead"
+      super
+    end
+  end
 end
diff --git a/lib/sprockets/sass_processor.rb b/lib/sprockets/sass_processor.rb
index 69ca50b..065156b 100644
--- a/lib/sprockets/sass_processor.rb
+++ b/lib/sprockets/sass_processor.rb
@@ -39,8 +39,8 @@ module Sprockets
     # Public: Initialize template with custom options.
     #
     # options - Hash
-    #   cache_version - String custom cache version. Used to force a cache
-    #                   change after code changes are made to Sass Functions.
+    # cache_version - String custom cache version. Used to force a cache
+    #                 change after code changes are made to Sass Functions.
     #
     def initialize(options = {}, &block)
       @cache_version = options[:cache_version]
@@ -59,7 +59,7 @@ module Sprockets
       options = {
         filename: input[:filename],
         syntax: self.class.syntax,
-        cache_store: CacheStore.new(input[:cache], @cache_version),
+        cache_store: build_cache_store(input, @cache_version),
         load_paths: input[:environment].paths,
         sprockets: {
           context: context,
@@ -84,6 +84,18 @@ module Sprockets
       context.metadata.merge(data: css, sass_dependencies: sass_dependencies)
     end
 
+    # Public: Build the cache store to be used by the Sass engine.
+    #
+    # input - the input hash.
+    # version - the cache version.
+    #
+    # Override this method if you need to use a different cache than the
+    # Sprockets cache.
+    def build_cache_store(input, version)
+      CacheStore.new(input[:cache], version)
+    end
+    private :build_cache_store
+
     # Public: Functions injected into Sass context during Sprockets evaluation.
     #
     # This module may be extended to add global functionality to all Sprockets
diff --git a/lib/sprockets/sass_template.rb b/lib/sprockets/sass_template.rb
index d54d783..a81d981 100644
--- a/lib/sprockets/sass_template.rb
+++ b/lib/sprockets/sass_template.rb
@@ -2,6 +2,18 @@ require 'sprockets/sass_processor'
 
 module Sprockets
   # Deprecated
-  SassTemplate = SassProcessor
-  ScssTemplate = ScssProcessor
+  class SassTemplate < SassProcessor
+    def self.call(*args)
+      Deprecation.new.warn "SassTemplate is deprecated please use SassProcessor instead"
+      super
+    end
+  end
+
+  # Deprecated
+  class ScssTemplate < ScssProcessor
+    def self.call(*args)
+      Deprecation.new.warn "ScssTemplate is deprecated please use ScssProcessor instead"
+      super
+    end
+  end
 end
diff --git a/lib/sprockets/uglifier_compressor.rb b/lib/sprockets/uglifier_compressor.rb
index e5b10a6..d3b0f6e 100644
--- a/lib/sprockets/uglifier_compressor.rb
+++ b/lib/sprockets/uglifier_compressor.rb
@@ -41,7 +41,7 @@ module Sprockets
         options[:copyright] ||= false
       else
         # Uglifier >= 2.x
-        options[:copyright] ||= :none
+        options[:comments] ||= :none
       end
 
       @uglifier = Autoload::Uglifier.new(options)
diff --git a/lib/sprockets/unloaded_asset.rb b/lib/sprockets/unloaded_asset.rb
new file mode 100644
index 0000000..fb1c2db
--- /dev/null
+++ b/lib/sprockets/unloaded_asset.rb
@@ -0,0 +1,137 @@
+require 'sprockets/uri_utils'
+require 'sprockets/uri_tar'
+
+module Sprockets
+  # Internal: Used to parse and store the URI to an unloaded asset
+  # Generates keys used to store and retrieve items from cache
+  class UnloadedAsset
+
+    # Internal: Initialize object for generating cache keys
+    #
+    # uri - A String containing complete URI to a file including scheme
+    #       and full path such as
+    #       "file:///Path/app/assets/js/app.js?type=application/javascript"
+    # env - The current "environment" that assets are being loaded into.
+    #       We need it so we know where the +root+ (directory where sprockets
+    #       is being invoked). We also need for the `file_digest` method,
+    #       since, for some strange reason, memoization is provided by
+    #       overriding methods such as `stat` in the `PathUtils` module.
+    #
+    # Returns UnloadedAsset.
+    def initialize(uri, env)
+      @uri               = uri.to_s
+      @env               = env
+      @compressed_path   = URITar.new(uri, env).compressed_path
+      @params            = nil # lazy loaded
+      @filename          = nil # lazy loaded
+    end
+    attr_reader :compressed_path, :uri
+
+    # Internal: Full file path without schema
+    #
+    # This returns a string containing the full path to the asset without the schema.
+    # Information is loaded lazilly since we want `UnloadedAsset.new(dep, self).relative_path`
+    # to be fast. Calling this method the first time allocates an array and a hash.
+    #
+    # Example
+    #
+    # If the URI is `file:///Full/path/app/assets/javascripts/application.js"` then the
+    # filename would be `"/Full/path/app/assets/javascripts/application.js"`
+    #
+    # Returns a String.
+    def filename
+      unless @filename
+        load_file_params
+      end
+      @filename
+    end
+
+    # Internal: Hash of param values
+    #
+    # This information is generated and used internally by sprockets.
+    # Known keys include `:type` which store the asset's mime-type, `:id` which is a fully resolved
+    # digest for the asset (includes dependency digest as opposed to a digest of only file contents)
+    # and `:pipeline`. Hash may be empty.
+    #
+    # Example
+    #
+    # If the URI is `file:///Full/path/app/assets/javascripts/application.js"type=application/javascript`
+    # Then the params would be `{type: "application/javascript"}`
+    #
+    # Returns a Hash.
+    def params
+      unless @params
+        load_file_params
+      end
+      @params
+    end
+
+    # Internal: Key of asset
+    #
+    # Used to retrieve an asset from the cache based on "compressed" path to asset.
+    # A "compressed" path can either be relative to the root of the project or an
+    # absolute path.
+    #
+    # Returns a String.
+    def asset_key
+      "asset-uri:#{compressed_path}"
+    end
+
+    # Public: Dependency History key
+    #
+    # Used to retrieve an array of "histories" each of which contain a set of stored dependencies
+    # for a given asset path and filename digest.
+    #
+    # A dependency can refer to either an asset i.e. index.js
+    # may rely on jquery.js (so jquery.js is a dependency), or other factors that may affect
+    # compilation, such as the VERSION of sprockets (i.e. the environment) and what "processors"
+    # are used.
+    #
+    # For example a history array with one Set of dependencies may look like:
+    #
+    # [["environment-version", "environment-paths", "processors:type=text/css&file_type=text/css",
+    #   "file-digest:///Full/path/app/assets/stylesheets/application.css",
+    #   "processors:type=text/css&file_type=text/css&pipeline=self",
+    #   "file-digest:///Full/path/app/assets/stylesheets"]]
+    #
+    # This method of asset lookup is used to ensure that none of the dependencies have been modified
+    # since last lookup. If one of them has, the key will be different and a new entry must be stored.
+    #
+    # URI depndencies are later converted to "compressed" paths
+    #
+    # Returns a String.
+    def dependency_history_key
+      "asset-uri-cache-dependencies:#{compressed_path}:#{ @env.file_digest(filename) }"
+    end
+
+    # Internal: Digest key
+    #
+    # Used to retrieve a string containing the "compressed" path to an asset based on
+    # a digest. The digest is generated from dependencies stored via information stored in
+    # the `dependency_history_key` after each of the "dependencies" is "resolved" for example
+    # "environment-version" may be resolved to "environment-1.0-3.2.0" for version "3.2.0" of sprockets
+    #
+    # Returns a String.
+    def digest_key(digest)
+      "asset-uri-digest:#{compressed_path}:#{digest}"
+    end
+
+    # Internal: File digest key
+    #
+    # The digest for a given file won't change if the path and the stat time hasn't changed
+    # We can save time by not re-computing this information and storing it in the cache
+    #
+    # Returns a String.
+    def file_digest_key(stat)
+      "file_digest:#{compressed_path}:#{stat}"
+    end
+
+    private
+      # Internal: Parses uri into filename and params hash
+      #
+      # Returns Array with filename and params hash
+      def load_file_params
+        @filename, @params = URIUtils.parse_asset_uri(uri)
+      end
+  end
+end
diff --git a/lib/sprockets/uri_tar.rb b/lib/sprockets/uri_tar.rb
new file mode 100644
index 0000000..eae0aad
--- /dev/null
+++ b/lib/sprockets/uri_tar.rb
@@ -0,0 +1,98 @@
+require 'sprockets/path_utils'
+
+module Sprockets
+ # Internal: used to "expand" and "compress" values for storage
+  class URITar
+    attr_reader :scheme, :root, :path
+
+    # Internal: Initialize object for compression or expansion
+    #
+    # uri - A String containing URI that may or may not contain the scheme
+    # env - The current "environment" that assets are being loaded into.
+    def initialize(uri, env)
+      @root = env.root
+      @env  = env
+      uri   = uri.to_s
+      if uri.include?("://".freeze)
+        @scheme, _, @path = uri.partition("://".freeze)
+        @scheme << "://".freeze
+      else
+        @scheme = "".freeze
+        @path   = uri
+      end
+    end
+
+    # Internal: Converts full uri to a "compressed" uri
+    #
+    # If a uri is inside of an environment's root it will
+    # be shortened to be a relative path.
+    #
+    # If a uri is outside of the environment's root the original
+    # uri will be returned.
+    #
+    # Returns String
+    def compress
+      scheme + compressed_path
+    end
+
+    # Internal: Tells us if we are using an absolute path
+    #
+    # Nix* systems start with a `/` like /Users/schneems.
+    # Windows systems start with a drive letter than colon and slash
+    # like C:/Schneems.
+    def absolute_path?
+      PathUtils.absolute_path?(path)
+    end
+
+    # Internal: Convert a "compressed" uri to an absolute path
+    #
+    # If a uri is inside of the environment's root it will not
+    # start with a slash for example:
+    #
+    #   file://this/is/a/relative/path
+    #
+    # If a uri is outside the root, it will start with a slash:
+    #
+    #   file:///This/is/an/absolute/path
+    #
+    # Returns String
+    def expand
+      if absolute_path?
+        # Stored path was absolute, don't add root
+        scheme + path
+      else
+        if scheme.empty?
+          File.join(root, path)
+        else
+          # We always want to return an absolute uri,
+          # make sure the path starts with a slash.
+          scheme + File.join("/".freeze, root, path)
+        end
+      end
+    end
+
+    # Internal: Returns "compressed" path
+    #
+    # If the input uri is relative to the environment root
+    # it will return a path relative to the environment root.
+    # Otherwise an absolute path will be returned.
+    #
+    # Only path information is returned, and not scheme.
+    #
+    # Returns String
+    def compressed_path
+      # windows
+      if !@root.start_with?("/".freeze) && path.start_with?("/".freeze)
+        consistent_root = "/".freeze + @root
+      else
+        consistent_root = @root
+      end
+
+      if compressed_path = PathUtils.split_subpath(consistent_root, path)
+        compressed_path
+      else
+        path
+      end
+    end
+  end
+end
diff --git a/lib/sprockets/utils.rb b/lib/sprockets/utils.rb
index e7bcf0f..4689b62 100644
--- a/lib/sprockets/utils.rb
+++ b/lib/sprockets/utils.rb
@@ -74,16 +74,19 @@ module Sprockets
     def string_end_with_semicolon?(str)
       i = str.size - 1
       while i >= 0
-        c = str[i]
+        c = str[i].ord
         i -= 1
-        if c == "\n" || c == " " || c == "\t"
-          next
-        elsif c != ";"
-          return false
-        else
-          return true
+
+        # Need to compare against the ordinals because the string can be UTF_8 or UTF_32LE encoded
+        # 0x0A == "\n"
+        # 0x20 == " "
+        # 0x09 == "\t"
+        # 0x3B == ";"
+        unless c == 0x0A || c == 0x20 || c == 0x09
+          return c === 0x3B
         end
       end
+
       true
     end
 
@@ -95,11 +98,21 @@ module Sprockets
     #
     # Returns buf String.
     def concat_javascript_sources(buf, source)
-      if buf.bytesize > 0
-        buf << ";" unless string_end_with_semicolon?(buf)
-        buf << "\n" unless buf.end_with?("\n")
+      if source.bytesize > 0
+        buf << source
+
+        # If the source contains non-ASCII characters, indexing on it becomes O(N).
+        # This will lead to O(N^2) performance in string_end_with_semicolon?, so we should use 32 bit encoding to make sure indexing stays O(1)
+        source = source.encode(Encoding::UTF_32LE) unless source.ascii_only?
+
+        if !string_end_with_semicolon?(source)
+          buf << ";\n"
+        elsif source[source.size - 1].ord != 0x0A
+          buf << "\n"
+        end
       end
-      buf << source
+
+      buf
     end
 
     # Internal: Prepends a leading "." to an extension if its missing.
diff --git a/lib/sprockets/utils/gzip.rb b/lib/sprockets/utils/gzip.rb
new file mode 100644
index 0000000..fe32dfc
--- /dev/null
+++ b/lib/sprockets/utils/gzip.rb
@@ -0,0 +1,67 @@
+module Sprockets
+  module Utils
+    class Gzip
+      # Private: Generates a gzipped file based off of reference file.
+      def initialize(asset)
+        @content_type  = asset.content_type
+        @source        = asset.source
+        @charset       = asset.charset
+      end
+
+      # What non-text mime types should we compress? This list comes from:
+      # https://www.fastly.com/blog/new-gzip-settings-and-deciding-what-compress
+      COMPRESSABLE_MIME_TYPES = {
+        "application/vnd.ms-fontobject" => true,
+        "application/x-font-opentype" => true,
+        "application/x-font-ttf" => true,
+        "image/x-icon" => true,
+        "image/svg+xml" => true
+      }
+
+      # Private: Returns whether or not an asset can be compressed.
+      #
+      # We want to compress any file that is text based.
+      # You do not want to compress binary
+      # files as they may already be compressed and running them
+      # through a compression algorithm would make them larger.
+      #
+      # Return Boolean.
+      def can_compress?(mime_types)
+        # The "charset" of a mime type is present if the value is
+        # encoded text. We can check this value to see if the asset
+        # can be compressed.
+        #
+        # We also check against our list of non-text compressible mime types
+        @charset || COMPRESSABLE_MIME_TYPES.include?(@content_type)
+      end
+
+      # Private: Opposite of `can_compress?`.
+      #
+      # Returns Boolean.
+      def cannot_compress?(mime_types)
+        !can_compress?(mime_types)
+      end
+
+      # Private: Generates a gzipped file based off of reference asset.
+      #
+      # Compresses the target asset's contents and puts it into a file with
+      # the same name plus a `.gz` extension in the same folder as the original.
+      # Does not modify the target asset.
+      #
+      # Returns nothing.
+      def compress(target)
+        mtime = PathUtils.stat(target).mtime
+        PathUtils.atomic_write("#{target}.gz") do |f|
+          gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
+          gz.mtime = mtime
+          gz.write(@source)
+          gz.close
+
+          File.utime(mtime, mtime, f.path)
+        end
+
+        nil
+      end
+    end
+  end
+end
diff --git a/lib/sprockets/version.rb b/lib/sprockets/version.rb
index 4da7a7c..b832c0c 100644
--- a/lib/sprockets/version.rb
+++ b/lib/sprockets/version.rb
@@ -1,3 +1,3 @@
 module Sprockets
-  VERSION = "3.3.0"
+  VERSION = "3.7.0"
 end
diff --git a/metadata.yml b/metadata.yml
deleted file mode 100644
index 38fbd92..0000000
--- a/metadata.yml
+++ /dev/null
@@ -1,317 +0,0 @@
---- !ruby/object:Gem::Specification
-name: sprockets
-version: !ruby/object:Gem::Version
-  version: 3.3.0
-platform: ruby
-authors:
-- Sam Stephenson
-- Joshua Peek
-autorequire: 
-bindir: bin
-cert_chain: []
-date: 2015-08-12 00:00:00.000000000 Z
-dependencies:
-- !ruby/object:Gem::Dependency
-  name: rack
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-  type: :runtime
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-- !ruby/object:Gem::Dependency
-  name: closure-compiler
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.1'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.1'
-- !ruby/object:Gem::Dependency
-  name: coffee-script-source
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.6'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.6'
-- !ruby/object:Gem::Dependency
-  name: coffee-script
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '2.2'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '2.2'
-- !ruby/object:Gem::Dependency
-  name: eco
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-- !ruby/object:Gem::Dependency
-  name: ejs
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-- !ruby/object:Gem::Dependency
-  name: execjs
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '2.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '2.0'
-- !ruby/object:Gem::Dependency
-  name: minitest
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '5.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '5.0'
-- !ruby/object:Gem::Dependency
-  name: nokogiri
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.3'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.3'
-- !ruby/object:Gem::Dependency
-  name: rack-test
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '0.6'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '0.6'
-- !ruby/object:Gem::Dependency
-  name: rake
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '10.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '10.0'
-- !ruby/object:Gem::Dependency
-  name: sass
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '3.1'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '3.1'
-- !ruby/object:Gem::Dependency
-  name: uglifier
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '2.3'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '2.3'
-- !ruby/object:Gem::Dependency
-  name: yui-compressor
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '0.12'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '0.12'
-description: Sprockets is a Rack-based asset packaging system that concatenates and
-  serves JavaScript, CoffeeScript, CSS, LESS, Sass, and SCSS.
-email:
-- sstephenson at gmail.com
-- josh at joshpeek.com
-executables:
-- sprockets
-extensions: []
-extra_rdoc_files: []
-files:
-- CHANGELOG.md
-- LICENSE
-- README.md
-- bin/sprockets
-- lib/rake/sprocketstask.rb
-- lib/sprockets.rb
-- lib/sprockets/asset.rb
-- lib/sprockets/autoload.rb
-- lib/sprockets/autoload/closure.rb
-- lib/sprockets/autoload/coffee_script.rb
-- lib/sprockets/autoload/eco.rb
-- lib/sprockets/autoload/ejs.rb
-- lib/sprockets/autoload/sass.rb
-- lib/sprockets/autoload/uglifier.rb
-- lib/sprockets/autoload/yui.rb
-- lib/sprockets/base.rb
-- lib/sprockets/bower.rb
-- lib/sprockets/bundle.rb
-- lib/sprockets/cache.rb
-- lib/sprockets/cache/file_store.rb
-- lib/sprockets/cache/memory_store.rb
-- lib/sprockets/cache/null_store.rb
-- lib/sprockets/cached_environment.rb
-- lib/sprockets/closure_compressor.rb
-- lib/sprockets/coffee_script_processor.rb
-- lib/sprockets/coffee_script_template.rb
-- lib/sprockets/compressing.rb
-- lib/sprockets/configuration.rb
-- lib/sprockets/context.rb
-- lib/sprockets/dependencies.rb
-- lib/sprockets/digest_utils.rb
-- lib/sprockets/directive_processor.rb
-- lib/sprockets/eco_processor.rb
-- lib/sprockets/eco_template.rb
-- lib/sprockets/ejs_processor.rb
-- lib/sprockets/ejs_template.rb
-- lib/sprockets/encoding_utils.rb
-- lib/sprockets/engines.rb
-- lib/sprockets/environment.rb
-- lib/sprockets/erb_processor.rb
-- lib/sprockets/erb_template.rb
-- lib/sprockets/errors.rb
-- lib/sprockets/file_reader.rb
-- lib/sprockets/http_utils.rb
-- lib/sprockets/jst_processor.rb
-- lib/sprockets/legacy.rb
-- lib/sprockets/legacy_proc_processor.rb
-- lib/sprockets/legacy_tilt_processor.rb
-- lib/sprockets/loader.rb
-- lib/sprockets/manifest.rb
-- lib/sprockets/manifest_utils.rb
-- lib/sprockets/mime.rb
-- lib/sprockets/path_dependency_utils.rb
-- lib/sprockets/path_digest_utils.rb
-- lib/sprockets/path_utils.rb
-- lib/sprockets/paths.rb
-- lib/sprockets/processing.rb
-- lib/sprockets/processor_utils.rb
-- lib/sprockets/resolve.rb
-- lib/sprockets/sass_cache_store.rb
-- lib/sprockets/sass_compressor.rb
-- lib/sprockets/sass_functions.rb
-- lib/sprockets/sass_importer.rb
-- lib/sprockets/sass_processor.rb
-- lib/sprockets/sass_template.rb
-- lib/sprockets/server.rb
-- lib/sprockets/transformers.rb
-- lib/sprockets/uglifier_compressor.rb
-- lib/sprockets/uri_utils.rb
-- lib/sprockets/utils.rb
-- lib/sprockets/version.rb
-- lib/sprockets/yui_compressor.rb
-homepage: https://github.com/rails/sprockets
-licenses:
-- MIT
-metadata: {}
-post_install_message: 
-rdoc_options: []
-require_paths:
-- lib
-required_ruby_version: !ruby/object:Gem::Requirement
-  requirements:
-  - - ">="
-    - !ruby/object:Gem::Version
-      version: 1.9.3
-required_rubygems_version: !ruby/object:Gem::Requirement
-  requirements:
-  - - ">="
-    - !ruby/object:Gem::Version
-      version: '0'
-requirements: []
-rubyforge_project: sprockets
-rubygems_version: 2.4.5
-signing_key: 
-specification_version: 4
-summary: Rack-based asset packaging system
-test_files: []
-has_rdoc: 
diff --git a/sprockets.gemspec b/sprockets.gemspec
new file mode 100644
index 0000000..1a024d6
--- /dev/null
+++ b/sprockets.gemspec
@@ -0,0 +1,78 @@
+#########################################################
+# This file has been automatically generated by gem2tgz #
+#########################################################
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+  s.name = "sprockets"
+  s.version = "3.7.0"
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+  s.authors = ["Sam Stephenson", "Joshua Peek"]
+  s.date = "2016-07-21"
+  s.description = "Sprockets is a Rack-based asset packaging system that concatenates and serves JavaScript, CoffeeScript, CSS, LESS, Sass, and SCSS."
+  s.email = ["sstephenson at gmail.com", "josh at joshpeek.com"]
+  s.executables = ["sprockets"]
+  s.files = ["CHANGELOG.md", "LICENSE", "README.md", "bin/sprockets", "lib/rake/sprocketstask.rb", "lib/sprockets.rb", "lib/sprockets/asset.rb", "lib/sprockets/autoload.rb", "lib/sprockets/autoload/closure.rb", "lib/sprockets/autoload/coffee_script.rb", "lib/sprockets/autoload/eco.rb", "lib/sprockets/autoload/ejs.rb", "lib/sprockets/autoload/sass.rb", "lib/sprockets/autoload/uglifier.rb", "lib/sprockets/autoload/yui.rb", "lib/sprockets/base.rb", "lib/sprockets/bower.rb", "lib/sprockets/b [...]
+  s.homepage = "https://github.com/rails/sprockets"
+  s.licenses = ["MIT"]
+  s.require_paths = ["lib"]
+  s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
+  s.rubyforge_project = "sprockets"
+  s.rubygems_version = "1.8.23"
+  s.summary = "Rack-based asset packaging system"
+
+  if s.respond_to? :specification_version then
+    s.specification_version = 4
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+      s.add_development_dependency(%q<closure-compiler>, ["~> 1.1"])
+      s.add_development_dependency(%q<coffee-script>, ["~> 2.2"])
+      s.add_development_dependency(%q<coffee-script-source>, ["~> 1.6"])
+      s.add_runtime_dependency(%q<concurrent-ruby>, ["~> 1.0"])
+      s.add_development_dependency(%q<eco>, ["~> 1.0"])
+      s.add_development_dependency(%q<ejs>, ["~> 1.0"])
+      s.add_development_dependency(%q<execjs>, ["~> 2.0"])
+      s.add_development_dependency(%q<minitest>, ["~> 5.0"])
+      s.add_development_dependency(%q<nokogiri>, ["~> 1.3"])
+      s.add_runtime_dependency(%q<rack>, ["< 3", "> 1"])
+      s.add_development_dependency(%q<rack-test>, ["~> 0.6"])
+      s.add_development_dependency(%q<rake>, ["~> 10.0"])
+      s.add_development_dependency(%q<sass>, ["~> 3.1"])
+      s.add_development_dependency(%q<uglifier>, ["~> 2.3"])
+      s.add_development_dependency(%q<yui-compressor>, ["~> 0.12"])
+    else
+      s.add_dependency(%q<closure-compiler>, ["~> 1.1"])
+      s.add_dependency(%q<coffee-script>, ["~> 2.2"])
+      s.add_dependency(%q<coffee-script-source>, ["~> 1.6"])
+      s.add_dependency(%q<concurrent-ruby>, ["~> 1.0"])
+      s.add_dependency(%q<eco>, ["~> 1.0"])
+      s.add_dependency(%q<ejs>, ["~> 1.0"])
+      s.add_dependency(%q<execjs>, ["~> 2.0"])
+      s.add_dependency(%q<minitest>, ["~> 5.0"])
+      s.add_dependency(%q<nokogiri>, ["~> 1.3"])
+      s.add_dependency(%q<rack>, ["< 3", "> 1"])
+      s.add_dependency(%q<rack-test>, ["~> 0.6"])
+      s.add_dependency(%q<rake>, ["~> 10.0"])
+      s.add_dependency(%q<sass>, ["~> 3.1"])
+      s.add_dependency(%q<uglifier>, ["~> 2.3"])
+      s.add_dependency(%q<yui-compressor>, ["~> 0.12"])
+    end
+  else
+    s.add_dependency(%q<closure-compiler>, ["~> 1.1"])
+    s.add_dependency(%q<coffee-script>, ["~> 2.2"])
+    s.add_dependency(%q<coffee-script-source>, ["~> 1.6"])
+    s.add_dependency(%q<concurrent-ruby>, ["~> 1.0"])
+    s.add_dependency(%q<eco>, ["~> 1.0"])
+    s.add_dependency(%q<ejs>, ["~> 1.0"])
+    s.add_dependency(%q<execjs>, ["~> 2.0"])
+    s.add_dependency(%q<minitest>, ["~> 5.0"])
+    s.add_dependency(%q<nokogiri>, ["~> 1.3"])
+    s.add_dependency(%q<rack>, ["< 3", "> 1"])
+    s.add_dependency(%q<rack-test>, ["~> 0.6"])
+    s.add_dependency(%q<rake>, ["~> 10.0"])
+    s.add_dependency(%q<sass>, ["~> 3.1"])
+    s.add_dependency(%q<uglifier>, ["~> 2.3"])
+    s.add_dependency(%q<yui-compressor>, ["~> 0.12"])
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-sprockets.git



More information about the Pkg-ruby-extras-commits mailing list