sprockets 2.2.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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