sprockets 2.2.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +68 -0
  3. data/README.md +482 -255
  4. data/bin/sprockets +20 -7
  5. data/lib/rake/sprocketstask.rb +28 -15
  6. data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
  7. data/lib/sprockets/asset.rb +142 -207
  8. data/lib/sprockets/autoload/babel.rb +8 -0
  9. data/lib/sprockets/autoload/closure.rb +8 -0
  10. data/lib/sprockets/autoload/coffee_script.rb +8 -0
  11. data/lib/sprockets/autoload/eco.rb +8 -0
  12. data/lib/sprockets/autoload/ejs.rb +8 -0
  13. data/lib/sprockets/autoload/jsminc.rb +8 -0
  14. data/lib/sprockets/autoload/sass.rb +8 -0
  15. data/lib/sprockets/autoload/sassc.rb +8 -0
  16. data/lib/sprockets/autoload/uglifier.rb +8 -0
  17. data/lib/sprockets/autoload/yui.rb +8 -0
  18. data/lib/sprockets/autoload/zopfli.rb +7 -0
  19. data/lib/sprockets/autoload.rb +16 -0
  20. data/lib/sprockets/babel_processor.rb +66 -0
  21. data/lib/sprockets/base.rb +89 -249
  22. data/lib/sprockets/bower.rb +61 -0
  23. data/lib/sprockets/bundle.rb +105 -0
  24. data/lib/sprockets/cache/file_store.rb +190 -14
  25. data/lib/sprockets/cache/memory_store.rb +75 -0
  26. data/lib/sprockets/cache/null_store.rb +54 -0
  27. data/lib/sprockets/cache.rb +271 -0
  28. data/lib/sprockets/cached_environment.rb +64 -0
  29. data/lib/sprockets/closure_compressor.rb +48 -0
  30. data/lib/sprockets/coffee_script_processor.rb +39 -0
  31. data/lib/sprockets/compressing.rb +134 -0
  32. data/lib/sprockets/configuration.rb +79 -0
  33. data/lib/sprockets/context.rb +204 -135
  34. data/lib/sprockets/dependencies.rb +74 -0
  35. data/lib/sprockets/digest_utils.rb +200 -0
  36. data/lib/sprockets/directive_processor.rb +224 -216
  37. data/lib/sprockets/eco_processor.rb +33 -0
  38. data/lib/sprockets/ejs_processor.rb +32 -0
  39. data/lib/sprockets/encoding_utils.rb +262 -0
  40. data/lib/sprockets/environment.rb +23 -68
  41. data/lib/sprockets/erb_processor.rb +37 -0
  42. data/lib/sprockets/errors.rb +6 -13
  43. data/lib/sprockets/exporters/base.rb +72 -0
  44. data/lib/sprockets/exporters/file_exporter.rb +24 -0
  45. data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
  46. data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
  47. data/lib/sprockets/exporting.rb +73 -0
  48. data/lib/sprockets/file_reader.rb +16 -0
  49. data/lib/sprockets/http_utils.rb +135 -0
  50. data/lib/sprockets/jsminc_compressor.rb +32 -0
  51. data/lib/sprockets/jst_processor.rb +36 -19
  52. data/lib/sprockets/loader.rb +343 -0
  53. data/lib/sprockets/manifest.rb +231 -96
  54. data/lib/sprockets/manifest_utils.rb +48 -0
  55. data/lib/sprockets/mime.rb +80 -32
  56. data/lib/sprockets/npm.rb +52 -0
  57. data/lib/sprockets/path_dependency_utils.rb +77 -0
  58. data/lib/sprockets/path_digest_utils.rb +48 -0
  59. data/lib/sprockets/path_utils.rb +367 -0
  60. data/lib/sprockets/paths.rb +82 -0
  61. data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
  62. data/lib/sprockets/processing.rb +140 -192
  63. data/lib/sprockets/processor_utils.rb +169 -0
  64. data/lib/sprockets/resolve.rb +295 -0
  65. data/lib/sprockets/sass_cache_store.rb +30 -0
  66. data/lib/sprockets/sass_compressor.rb +63 -0
  67. data/lib/sprockets/sass_functions.rb +3 -0
  68. data/lib/sprockets/sass_importer.rb +3 -0
  69. data/lib/sprockets/sass_processor.rb +313 -0
  70. data/lib/sprockets/sassc_compressor.rb +56 -0
  71. data/lib/sprockets/sassc_processor.rb +297 -0
  72. data/lib/sprockets/server.rb +138 -90
  73. data/lib/sprockets/source_map_processor.rb +66 -0
  74. data/lib/sprockets/source_map_utils.rb +483 -0
  75. data/lib/sprockets/transformers.rb +173 -0
  76. data/lib/sprockets/uglifier_compressor.rb +66 -0
  77. data/lib/sprockets/unloaded_asset.rb +139 -0
  78. data/lib/sprockets/uri_tar.rb +99 -0
  79. data/lib/sprockets/uri_utils.rb +191 -0
  80. data/lib/sprockets/utils/gzip.rb +99 -0
  81. data/lib/sprockets/utils.rb +186 -53
  82. data/lib/sprockets/version.rb +2 -1
  83. data/lib/sprockets/yui_compressor.rb +56 -0
  84. data/lib/sprockets.rb +217 -52
  85. metadata +250 -59
  86. data/LICENSE +0 -21
  87. data/lib/sprockets/asset_attributes.rb +0 -126
  88. data/lib/sprockets/bundled_asset.rb +0 -79
  89. data/lib/sprockets/caching.rb +0 -96
  90. data/lib/sprockets/charset_normalizer.rb +0 -41
  91. data/lib/sprockets/eco_template.rb +0 -38
  92. data/lib/sprockets/ejs_template.rb +0 -37
  93. data/lib/sprockets/engines.rb +0 -74
  94. data/lib/sprockets/index.rb +0 -99
  95. data/lib/sprockets/processed_asset.rb +0 -152
  96. data/lib/sprockets/processor.rb +0 -32
  97. data/lib/sprockets/safety_colons.rb +0 -28
  98. data/lib/sprockets/static_asset.rb +0 -57
  99. data/lib/sprockets/trail.rb +0 -90
data/bin/sprockets CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ $VERBOSE = nil
2
3
 
3
4
  require 'sprockets'
4
5
  require 'optparse'
@@ -11,7 +12,7 @@ unless ARGV.delete("--noenv")
11
12
  end
12
13
  end
13
14
 
14
- filenames = []
15
+ paths = []
15
16
  environment = Sprockets::Environment.new(Dir.pwd)
16
17
  manifest = nil
17
18
 
@@ -40,9 +41,21 @@ OptionParser.new do |opts|
40
41
  manifest = Sprockets::Manifest.new(environment, directory)
41
42
  end
42
43
 
44
+ opts.on("--css-compressor=COMPRESSOR", "Use CSS compressor") do |compressor|
45
+ environment.css_compressor = compressor.to_sym
46
+ end
47
+
48
+ opts.on("--js-compressor=COMPRESSOR", "Use JavaScript compressor") do |compressor|
49
+ environment.js_compressor = compressor.to_sym
50
+ end
51
+
43
52
  opts.on("--noenv", "Disables .sprocketsrc file") do
44
53
  end
45
54
 
55
+ opts.on("--cache=DIRECTORY", "Enables the FileStore cache using the specified directory") do |directory|
56
+ environment.cache = Sprockets::Cache::FileStore.new(directory)
57
+ end
58
+
46
59
  opts.on_tail("-h", "--help", "Shows this help message") do
47
60
  opts.show_usage
48
61
  end
@@ -55,8 +68,8 @@ OptionParser.new do |opts|
55
68
  opts.show_usage if ARGV.empty?
56
69
 
57
70
  begin
58
- opts.order(ARGV) do |filename|
59
- filenames << File.expand_path(filename)
71
+ opts.order(ARGV) do |path|
72
+ paths << path
60
73
  end
61
74
  rescue OptionParser::ParseError => e
62
75
  opts.warn e.message
@@ -66,14 +79,14 @@ end
66
79
 
67
80
  if environment.paths.empty?
68
81
  warn "No load paths given"
69
- warn "Usage: sprockets -Ijavascripts/ filename"
82
+ warn "Usage: sprockets -Ijavascripts/ path"
70
83
  exit 1
71
84
  end
72
85
 
73
86
  if manifest
74
- manifest.compile(filenames)
75
- elsif filenames.length == 1
76
- puts environment.find_asset(filenames.first).to_s
87
+ manifest.compile(paths)
88
+ elsif paths.length == 1
89
+ puts environment.find_asset(paths.first).to_s
77
90
  else
78
91
  warn "Only one file can be compiled to stdout at a time"
79
92
  exit 1
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rake'
2
3
  require 'rake/tasklib'
3
4
 
@@ -37,6 +38,25 @@ module Rake
37
38
  end
38
39
  attr_writer :environment
39
40
 
41
+ # Returns cached cached environment
42
+ def cached
43
+ @cached ||= environment.cached if environment
44
+ end
45
+ alias_method :index, :cached
46
+
47
+ # `Manifest` instance used for already compiled assets.
48
+ #
49
+ # Will be created by default if an environment and output
50
+ # directory are given
51
+ def manifest
52
+ if !@manifest.is_a?(Sprockets::Manifest) && @manifest.respond_to?(:call)
53
+ @manifest = @manifest.call
54
+ else
55
+ @manifest
56
+ end
57
+ end
58
+ attr_writer :manifest
59
+
40
60
  # Directory to write compiled assets too. As well as the manifest file.
41
61
  #
42
62
  # t.output = "./public/assets"
@@ -79,6 +99,7 @@ module Rake
79
99
  def initialize(name = :assets)
80
100
  @name = name
81
101
  @environment = lambda { Sprockets::Environment.new(Dir.pwd) }
102
+ @manifest = lambda { Sprockets::Manifest.new(cached, output) }
82
103
  @logger = Logger.new($stderr)
83
104
  @logger.level = Logger::INFO
84
105
  @keep = 2
@@ -104,7 +125,7 @@ module Rake
104
125
  end
105
126
  end
106
127
 
107
- task :clobber => ["clobber_#{name}"]
128
+ task clobber: ["clobber_#{name}"]
108
129
 
109
130
  desc name == :assets ? "Clean old assets" : "Clean old #{name} assets"
110
131
  task "clean_#{name}" do
@@ -113,28 +134,20 @@ module Rake
113
134
  end
114
135
  end
115
136
 
116
- task :clean => ["clean_#{name}"]
137
+ task clean: ["clean_#{name}"]
117
138
  end
118
139
 
119
140
  private
120
- # Returns cached indexed environment
121
- def index
122
- @index ||= environment.index
123
- end
124
-
125
- # Returns manifest for tasks
126
- def manifest
127
- @manifest ||= Sprockets::Manifest.new(index, output)
128
- end
129
-
130
141
  # Sub out environment logger with our rake task logger that
131
142
  # writes to stderr.
132
143
  def with_logger
133
- old_logger = index.logger
134
- index.logger = @logger
144
+ if env = manifest.environment
145
+ old_logger = env.logger
146
+ env.logger = @logger
147
+ end
135
148
  yield
136
149
  ensure
137
- index.logger = old_logger
150
+ env.logger = old_logger if env
138
151
  end
139
152
  end
140
153
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ require 'sprockets/uri_utils'
3
+ require 'sprockets/path_utils'
4
+
5
+ module Sprockets
6
+ # This is a processor designed to add a source map "comment"
7
+ # to the bottom of a css or JS file that is serving a source
8
+ # map. An example of a comment might look like this
9
+ #
10
+ # //# application.js-80af0efcc960fc2ac93eda2f7b12e3db40ab360bf6ea269ceed3bea3678326f9.map
11
+ #
12
+ # As an asset is built it gets source map information added
13
+ # to the `asset.to_hash[:metadata][:map]` key. This contains all the
14
+ # information that is needed to build a source map file.
15
+ #
16
+ # To add this comment we must have an asset we can link to.
17
+ # To do this we ensure that the original aset is loaded, then
18
+ # we use a use a special mime type. For example `application/js-sourcemap+json`
19
+ # for a JS source map.
20
+ #
21
+ # This will trigger a new asset to be loaded and generated by the
22
+ # `SourceMapProcessor` processor.
23
+ #
24
+ # Finally once we have that file, we can generate a link to it
25
+ # with it's full fingerprint. This is done and then
26
+ # added to the original asset as a comment at the bottom.
27
+ #
28
+ class AddSourceMapCommentToAssetProcessor
29
+ def self.call(input)
30
+
31
+ case input[:content_type]
32
+ when "application/javascript"
33
+ comment = "\n//# sourceMappingURL=%s"
34
+ map_type = "application/js-sourcemap+json"
35
+ when "text/css"
36
+ comment = "\n/*# sourceMappingURL=%s */"
37
+ map_type = "application/css-sourcemap+json"
38
+ else
39
+ fail input[:content_type]
40
+ end
41
+
42
+ env = input[:environment]
43
+
44
+ uri, _ = env.resolve!(input[:filename], accept: input[:content_type])
45
+ asset = env.load(uri)
46
+
47
+ uri, _ = env.resolve!(input[:filename], accept: map_type)
48
+ map = env.load(uri)
49
+
50
+ uri, params = URIUtils.parse_asset_uri(input[:uri])
51
+ uri = env.expand_from_root(params[:index_alias]) if params[:index_alias]
52
+ path = PathUtils.relative_path_from(PathUtils.split_subpath(input[:load_path], uri), map.digest_path)
53
+
54
+ asset.metadata.merge(
55
+ data: asset.source + (comment % path) + "\n",
56
+ links: asset.links + [asset.uri, map.uri]
57
+ )
58
+ end
59
+ end
60
+ end
@@ -1,260 +1,195 @@
1
- require 'time'
2
- require 'set'
1
+ # frozen_string_literal: true
2
+ require 'fileutils'
3
+ require 'sprockets/digest_utils'
3
4
 
4
5
  module Sprockets
5
- # `Asset` is the base class for `BundledAsset` and `StaticAsset`.
6
6
  class Asset
7
- # Internal initializer to load `Asset` from serialized `Hash`.
8
- def self.from_hash(environment, hash)
9
- return unless hash.is_a?(Hash)
7
+ attr_reader :logical_path
10
8
 
11
- klass = case hash['class']
12
- when 'BundledAsset'
13
- BundledAsset
14
- when 'ProcessedAsset'
15
- ProcessedAsset
16
- when 'StaticAsset'
17
- StaticAsset
18
- else
19
- nil
20
- end
21
-
22
- if klass
23
- asset = klass.allocate
24
- asset.init_with(environment, hash)
25
- asset
26
- end
27
- rescue UnserializeError
28
- nil
29
- end
30
-
31
- attr_reader :logical_path, :pathname
32
- attr_reader :content_type, :mtime, :length, :digest
33
-
34
- def initialize(environment, logical_path, pathname)
35
- @root = environment.root
36
- @logical_path = logical_path.to_s
37
- @pathname = Pathname.new(pathname)
38
- @content_type = environment.content_type_of(pathname)
39
- @mtime = environment.stat(pathname).mtime
40
- @length = environment.stat(pathname).size
41
- @digest = environment.file_digest(pathname).hexdigest
9
+ # Private: Intialize Asset wrapper from attributes Hash.
10
+ #
11
+ # Asset wrappers should not be initialized directly, only
12
+ # Environment#find_asset should vend them.
13
+ #
14
+ # attributes - Hash of ivars
15
+ #
16
+ # Returns Asset.
17
+ def initialize(attributes = {})
18
+ @attributes = attributes
19
+ @content_type = attributes[:content_type]
20
+ @filename = attributes[:filename]
21
+ @id = attributes[:id]
22
+ @load_path = attributes[:load_path]
23
+ @logical_path = attributes[:logical_path]
24
+ @metadata = attributes[:metadata]
25
+ @name = attributes[:name]
26
+ @source = attributes[:source]
27
+ @uri = attributes[:uri]
28
+ end
29
+
30
+ # Internal: Return all internal instance variables as a hash.
31
+ #
32
+ # Returns a Hash.
33
+ def to_hash
34
+ @attributes
42
35
  end
43
36
 
44
- # Initialize `Asset` from serialized `Hash`.
45
- def init_with(environment, coder)
46
- @root = environment.root
37
+ # Public: Metadata accumulated from pipeline process.
38
+ #
39
+ # The API status of the keys is dependent on the pipeline processors
40
+ # itself. So some values maybe considered public and others internal.
41
+ # See the pipeline proccessor documentation itself.
42
+ #
43
+ # Returns Hash.
44
+ attr_reader :metadata
47
45
 
48
- @logical_path = coder['logical_path']
49
- @content_type = coder['content_type']
50
- @digest = coder['digest']
46
+ # Public: Returns String path of asset.
47
+ attr_reader :filename
51
48
 
52
- if pathname = coder['pathname']
53
- # Expand `$root` placeholder and wrapper string in a `Pathname`
54
- @pathname = Pathname.new(expand_root_path(pathname))
55
- end
56
-
57
- if mtime = coder['mtime']
58
- # Parse time string
59
- @mtime = Time.parse(mtime)
60
- end
61
-
62
- if length = coder['length']
63
- # Convert length to an `Integer`
64
- @length = Integer(length)
65
- end
66
- end
49
+ # Internal: Unique asset object ID.
50
+ #
51
+ # Returns a String.
52
+ attr_reader :id
67
53
 
68
- # Copy serialized attributes to the coder object
69
- def encode_with(coder)
70
- coder['class'] = self.class.name.sub(/Sprockets::/, '')
71
- coder['logical_path'] = logical_path
72
- coder['pathname'] = relativize_root_path(pathname).to_s
73
- coder['content_type'] = content_type
74
- coder['mtime'] = mtime.iso8601
75
- coder['length'] = length
76
- coder['digest'] = digest
77
- end
54
+ # Public: Internal URI to lookup asset by.
55
+ #
56
+ # NOT a publically accessible URL.
57
+ #
58
+ # Returns URI.
59
+ attr_reader :uri
78
60
 
79
- # Return logical path with digest spliced in.
61
+ # Public: Return logical path with digest spliced in.
80
62
  #
81
63
  # "foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"
82
64
  #
65
+ # Returns String.
83
66
  def digest_path
84
- logical_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" }
67
+ logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" }
85
68
  end
86
69
 
87
- # Return an `Array` of `Asset` files that are declared dependencies.
88
- def dependencies
89
- []
70
+ # Public: Return load path + logical path with digest spliced in.
71
+ #
72
+ # Returns String.
73
+ def full_digest_path
74
+ File.join(@load_path, digest_path)
90
75
  end
91
76
 
92
- # Expand asset into an `Array` of parts.
77
+ # Public: Returns String MIME type of asset. Returns nil if type is unknown.
78
+ attr_reader :content_type
79
+
80
+ # Public: Get all externally linked asset filenames from asset.
93
81
  #
94
- # Appending all of an assets body parts together should give you
95
- # the asset's contents as a whole.
82
+ # All linked assets should be compiled anytime this asset is.
96
83
  #
97
- # This allows you to link to individual files for debugging
98
- # purposes.
99
- def to_a
100
- [self]
84
+ # Returns Set of String asset URIs.
85
+ def links
86
+ metadata[:links] || Set.new
101
87
  end
102
88
 
103
- # `body` is aliased to source by default if it can't have any dependencies.
104
- def body
105
- source
89
+ # Public: Return `String` of concatenated source.
90
+ #
91
+ # Returns String.
92
+ def source
93
+ if @source
94
+ @source
95
+ else
96
+ # File is read everytime to avoid memory bloat of large binary files
97
+ File.binread(filename)
98
+ end
106
99
  end
107
100
 
108
- # Return `String` of concatenated source.
101
+ # Public: Alias for #source.
102
+ #
103
+ # Returns String.
109
104
  def to_s
110
105
  source
111
106
  end
112
107
 
113
- # Add enumerator to allow `Asset` instances to be used as Rack
114
- # compatible body objects.
115
- def each
116
- yield to_s
108
+ # Public: Get charset of source.
109
+ #
110
+ # Returns a String charset name or nil if binary.
111
+ def charset
112
+ metadata[:charset]
117
113
  end
118
114
 
119
- # Checks if Asset is fresh by comparing the actual mtime and
120
- # digest to the inmemory model.
121
- #
122
- # Used to test if cached models need to be rebuilt.
123
- def fresh?(environment)
124
- # Check current mtime and digest
125
- dependency_fresh?(environment, self)
115
+ # Public: Returns Integer length of source.
116
+ def length
117
+ metadata[:length]
126
118
  end
119
+ alias_method :bytesize, :length
127
120
 
128
- # Checks if Asset is stale by comparing the actual mtime and
129
- # digest to the inmemory model.
130
- #
131
- # Subclass must override `fresh?` or `stale?`.
132
- def stale?(environment)
133
- !fresh?(environment)
121
+ # Public: Returns String byte digest of source.
122
+ def digest
123
+ metadata[:digest]
134
124
  end
135
125
 
136
- # Save asset to disk.
137
- def write_to(filename, options = {})
138
- # Gzip contents if filename has '.gz'
139
- options[:compress] ||= File.extname(filename) == '.gz'
126
+ # Public: Returns String hexdigest of source.
127
+ def hexdigest
128
+ DigestUtils.pack_hexdigest(digest)
129
+ end
140
130
 
141
- FileUtils.mkdir_p File.dirname(filename)
131
+ # Pubic: ETag String of Asset.
132
+ alias_method :etag, :hexdigest
142
133
 
143
- File.open("#{filename}+", 'wb') do |f|
144
- if options[:compress]
145
- # Run contents through `Zlib`
146
- gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
147
- gz.write to_s
148
- gz.close
149
- else
150
- # Write out as is
151
- f.write to_s
152
- f.close
153
- end
154
- end
134
+ # Public: Returns String base64 digest of source.
135
+ def base64digest
136
+ DigestUtils.pack_base64digest(digest)
137
+ end
138
+
139
+ # Public: A "named information" URL for subresource integrity.
140
+ def integrity
141
+ DigestUtils.integrity_uri(metadata[:digest])
142
+ end
143
+
144
+ # Public: Add enumerator to allow `Asset` instances to be used as Rack
145
+ # compatible body objects.
146
+ #
147
+ # block
148
+ # part - String body chunk
149
+ #
150
+ # Returns nothing.
151
+ def each
152
+ yield to_s
153
+ end
155
154
 
156
- # Atomic write
157
- FileUtils.mv("#{filename}+", filename)
155
+ # Deprecated: Save asset to disk.
156
+ #
157
+ # filename - String target
158
+ #
159
+ # Returns nothing.
160
+ def write_to(filename)
161
+ FileUtils.mkdir_p File.dirname(filename)
158
162
 
159
- # Set mtime correctly
160
- File.utime(mtime, mtime, filename)
163
+ PathUtils.atomic_write(filename) do |f|
164
+ f.write source
165
+ end
161
166
 
162
167
  nil
163
- ensure
164
- # Ensure tmp file gets cleaned up
165
- FileUtils.rm("#{filename}+") if File.exist?("#{filename}+")
166
168
  end
167
169
 
168
- # Pretty inspect
170
+ # Public: Pretty inspect
171
+ #
172
+ # Returns String.
169
173
  def inspect
170
- "#<#{self.class}:0x#{object_id.to_s(16)} " +
171
- "pathname=#{pathname.to_s.inspect}, " +
172
- "mtime=#{mtime.inspect}, " +
173
- "digest=#{digest.inspect}" +
174
- ">"
174
+ "#<#{self.class}:#{object_id.to_s(16)} #{uri.inspect}>"
175
175
  end
176
176
 
177
+ # Public: Implements Object#hash so Assets can be used as a Hash key or
178
+ # in a Set.
179
+ #
180
+ # Returns Integer hash of the id.
177
181
  def hash
178
- digest.hash
182
+ id.hash
179
183
  end
180
184
 
181
- # Assets are equal if they share the same path, mtime and digest.
185
+ # Public: Compare assets.
186
+ #
187
+ # Assets are equal if they share the same path and digest.
188
+ #
189
+ # Returns true or false.
182
190
  def eql?(other)
183
- other.class == self.class &&
184
- other.logical_path == self.logical_path &&
185
- other.mtime.to_i == self.mtime.to_i &&
186
- other.digest == self.digest
191
+ self.class == other.class && self.id == other.id
187
192
  end
188
193
  alias_method :==, :eql?
189
-
190
- protected
191
- # Internal: String paths that are marked as dependencies after processing.
192
- #
193
- # Default to an empty `Array`.
194
- def dependency_paths
195
- @dependency_paths ||= []
196
- end
197
-
198
- # Internal: `ProccessedAsset`s that are required after processing.
199
- #
200
- # Default to an empty `Array`.
201
- def required_assets
202
- @required_assets ||= []
203
- end
204
-
205
- # Get pathname with its root stripped.
206
- def relative_pathname
207
- @relative_pathname ||= Pathname.new(relativize_root_path(pathname))
208
- end
209
-
210
- # Replace `$root` placeholder with actual environment root.
211
- def expand_root_path(path)
212
- path.to_s.sub(/^\$root/, @root)
213
- end
214
-
215
- # Replace actual environment root with `$root` placeholder.
216
- def relativize_root_path(path)
217
- path.to_s.sub(/^#{Regexp.escape(@root)}/, '$root')
218
- end
219
-
220
- # Check if dependency is fresh.
221
- #
222
- # `dep` is a `Hash` with `path`, `mtime` and `hexdigest` keys.
223
- #
224
- # A `Hash` is used rather than other `Asset` object because we
225
- # want to test non-asset files and directories.
226
- def dependency_fresh?(environment, dep)
227
- path, mtime, hexdigest = dep.pathname.to_s, dep.mtime, dep.digest
228
-
229
- stat = environment.stat(path)
230
-
231
- # If path no longer exists, its definitely stale.
232
- if stat.nil?
233
- return false
234
- end
235
-
236
- # Compare dependency mime to the actual mtime. If the
237
- # dependency mtime is newer than the actual mtime, the file
238
- # hasn't changed since we created this `Asset` instance.
239
- #
240
- # However, if the mtime is newer it doesn't mean the asset is
241
- # stale. Many deployment environments may recopy or recheckout
242
- # assets on each deploy. In this case the mtime would be the
243
- # time of deploy rather than modified time.
244
- if mtime >= stat.mtime
245
- return true
246
- end
247
-
248
- digest = environment.file_digest(path)
249
-
250
- # If the mtime is newer, do a full digest comparsion. Return
251
- # fresh if the digests match.
252
- if hexdigest == digest.hexdigest
253
- return true
254
- end
255
-
256
- # Otherwise, its stale.
257
- false
258
- end
259
194
  end
260
195
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'babel/transpiler'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Babel = ::Babel
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'closure-compiler'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Closure = ::Closure
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'coffee_script'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ CoffeeScript = ::CoffeeScript
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'eco'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Eco = ::Eco
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'ejs'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ EJS = ::EJS
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'jsminc'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ JSMinC = ::JSMinC
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'sass'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Sass = ::Sass
7
+ end
8
+ end