sprockets 3.7.2 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -270
- data/README.md +443 -320
- data/bin/sprockets +11 -7
- data/lib/rake/sprocketstask.rb +3 -2
- data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
- data/lib/sprockets/asset.rb +16 -21
- data/lib/sprockets/autoload/babel.rb +8 -0
- data/lib/sprockets/autoload/closure.rb +1 -0
- data/lib/sprockets/autoload/coffee_script.rb +1 -0
- data/lib/sprockets/autoload/eco.rb +1 -0
- data/lib/sprockets/autoload/ejs.rb +1 -0
- data/lib/sprockets/autoload/jsminc.rb +8 -0
- data/lib/sprockets/autoload/sass.rb +1 -0
- data/lib/sprockets/autoload/sassc.rb +8 -0
- data/lib/sprockets/autoload/uglifier.rb +1 -0
- data/lib/sprockets/autoload/yui.rb +1 -0
- data/lib/sprockets/autoload/zopfli.rb +7 -0
- data/lib/sprockets/autoload.rb +5 -0
- data/lib/sprockets/babel_processor.rb +66 -0
- data/lib/sprockets/base.rb +47 -10
- data/lib/sprockets/bower.rb +5 -2
- data/lib/sprockets/bundle.rb +40 -4
- data/lib/sprockets/cache/file_store.rb +25 -3
- data/lib/sprockets/cache/memory_store.rb +9 -0
- data/lib/sprockets/cache/null_store.rb +8 -0
- data/lib/sprockets/cache.rb +36 -1
- data/lib/sprockets/cached_environment.rb +14 -19
- data/lib/sprockets/closure_compressor.rb +1 -0
- data/lib/sprockets/coffee_script_processor.rb +18 -4
- data/lib/sprockets/compressing.rb +43 -3
- data/lib/sprockets/configuration.rb +3 -7
- data/lib/sprockets/context.rb +97 -24
- data/lib/sprockets/dependencies.rb +1 -0
- data/lib/sprockets/digest_utils.rb +25 -5
- data/lib/sprockets/directive_processor.rb +45 -35
- data/lib/sprockets/eco_processor.rb +1 -0
- data/lib/sprockets/ejs_processor.rb +1 -0
- data/lib/sprockets/encoding_utils.rb +1 -0
- data/lib/sprockets/environment.rb +9 -4
- data/lib/sprockets/erb_processor.rb +28 -21
- data/lib/sprockets/errors.rb +1 -0
- data/lib/sprockets/exporters/base.rb +72 -0
- data/lib/sprockets/exporters/file_exporter.rb +24 -0
- data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
- data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
- data/lib/sprockets/exporting.rb +73 -0
- data/lib/sprockets/file_reader.rb +1 -0
- data/lib/sprockets/http_utils.rb +25 -7
- data/lib/sprockets/jsminc_compressor.rb +32 -0
- data/lib/sprockets/jst_processor.rb +11 -10
- data/lib/sprockets/loader.rb +85 -67
- data/lib/sprockets/manifest.rb +64 -62
- data/lib/sprockets/manifest_utils.rb +9 -6
- data/lib/sprockets/mime.rb +8 -42
- data/lib/sprockets/npm.rb +52 -0
- data/lib/sprockets/path_dependency_utils.rb +3 -11
- data/lib/sprockets/path_digest_utils.rb +2 -1
- data/lib/sprockets/path_utils.rb +87 -7
- data/lib/sprockets/paths.rb +1 -0
- data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
- data/lib/sprockets/processing.rb +31 -61
- data/lib/sprockets/processor_utils.rb +24 -35
- data/lib/sprockets/resolve.rb +177 -93
- data/lib/sprockets/sass_cache_store.rb +2 -6
- data/lib/sprockets/sass_compressor.rb +13 -1
- data/lib/sprockets/sass_functions.rb +1 -0
- data/lib/sprockets/sass_importer.rb +1 -0
- data/lib/sprockets/sass_processor.rb +30 -9
- data/lib/sprockets/sassc_compressor.rb +56 -0
- data/lib/sprockets/sassc_processor.rb +297 -0
- data/lib/sprockets/server.rb +26 -23
- data/lib/sprockets/source_map_processor.rb +66 -0
- data/lib/sprockets/source_map_utils.rb +483 -0
- data/lib/sprockets/transformers.rb +63 -35
- data/lib/sprockets/uglifier_compressor.rb +21 -11
- data/lib/sprockets/unloaded_asset.rb +13 -11
- data/lib/sprockets/uri_tar.rb +1 -0
- data/lib/sprockets/uri_utils.rb +11 -8
- data/lib/sprockets/utils/gzip.rb +46 -14
- data/lib/sprockets/utils.rb +41 -74
- data/lib/sprockets/version.rb +2 -1
- data/lib/sprockets/yui_compressor.rb +1 -0
- data/lib/sprockets.rb +99 -39
- metadata +127 -23
- data/LICENSE +0 -21
- data/lib/sprockets/coffee_script_template.rb +0 -17
- data/lib/sprockets/deprecation.rb +0 -90
- data/lib/sprockets/eco_template.rb +0 -17
- data/lib/sprockets/ejs_template.rb +0 -17
- data/lib/sprockets/engines.rb +0 -92
- data/lib/sprockets/erb_template.rb +0 -11
- data/lib/sprockets/legacy.rb +0 -330
- data/lib/sprockets/legacy_proc_processor.rb +0 -35
- data/lib/sprockets/legacy_tilt_processor.rb +0 -29
- data/lib/sprockets/sass_template.rb +0 -19
data/bin/sprockets
CHANGED
|
@@ -12,7 +12,7 @@ unless ARGV.delete("--noenv")
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
paths = []
|
|
16
16
|
environment = Sprockets::Environment.new(Dir.pwd)
|
|
17
17
|
manifest = nil
|
|
18
18
|
|
|
@@ -52,6 +52,10 @@ OptionParser.new do |opts|
|
|
|
52
52
|
opts.on("--noenv", "Disables .sprocketsrc file") do
|
|
53
53
|
end
|
|
54
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
|
+
|
|
55
59
|
opts.on_tail("-h", "--help", "Shows this help message") do
|
|
56
60
|
opts.show_usage
|
|
57
61
|
end
|
|
@@ -64,8 +68,8 @@ OptionParser.new do |opts|
|
|
|
64
68
|
opts.show_usage if ARGV.empty?
|
|
65
69
|
|
|
66
70
|
begin
|
|
67
|
-
opts.order(ARGV) do |
|
|
68
|
-
|
|
71
|
+
opts.order(ARGV) do |path|
|
|
72
|
+
paths << path
|
|
69
73
|
end
|
|
70
74
|
rescue OptionParser::ParseError => e
|
|
71
75
|
opts.warn e.message
|
|
@@ -75,14 +79,14 @@ end
|
|
|
75
79
|
|
|
76
80
|
if environment.paths.empty?
|
|
77
81
|
warn "No load paths given"
|
|
78
|
-
warn "Usage: sprockets -Ijavascripts/
|
|
82
|
+
warn "Usage: sprockets -Ijavascripts/ path"
|
|
79
83
|
exit 1
|
|
80
84
|
end
|
|
81
85
|
|
|
82
86
|
if manifest
|
|
83
|
-
manifest.compile(
|
|
84
|
-
elsif
|
|
85
|
-
puts environment.find_asset(
|
|
87
|
+
manifest.compile(paths)
|
|
88
|
+
elsif paths.length == 1
|
|
89
|
+
puts environment.find_asset(paths.first).to_s
|
|
86
90
|
else
|
|
87
91
|
warn "Only one file can be compiled to stdout at a time"
|
|
88
92
|
exit 1
|
data/lib/rake/sprocketstask.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'rake'
|
|
2
3
|
require 'rake/tasklib'
|
|
3
4
|
|
|
@@ -124,7 +125,7 @@ module Rake
|
|
|
124
125
|
end
|
|
125
126
|
end
|
|
126
127
|
|
|
127
|
-
task :
|
|
128
|
+
task clobber: ["clobber_#{name}"]
|
|
128
129
|
|
|
129
130
|
desc name == :assets ? "Clean old assets" : "Clean old #{name} assets"
|
|
130
131
|
task "clean_#{name}" do
|
|
@@ -133,7 +134,7 @@ module Rake
|
|
|
133
134
|
end
|
|
134
135
|
end
|
|
135
136
|
|
|
136
|
-
task :
|
|
137
|
+
task clean: ["clean_#{name}"]
|
|
137
138
|
end
|
|
138
139
|
|
|
139
140
|
private
|
|
@@ -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
|
data/lib/sprockets/asset.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'fileutils'
|
|
2
3
|
require 'sprockets/digest_utils'
|
|
3
4
|
|
|
@@ -13,8 +14,7 @@ module Sprockets
|
|
|
13
14
|
# attributes - Hash of ivars
|
|
14
15
|
#
|
|
15
16
|
# Returns Asset.
|
|
16
|
-
def initialize(
|
|
17
|
-
@environment = environment
|
|
17
|
+
def initialize(attributes = {})
|
|
18
18
|
@attributes = attributes
|
|
19
19
|
@content_type = attributes[:content_type]
|
|
20
20
|
@filename = attributes[:filename]
|
|
@@ -22,7 +22,6 @@ module Sprockets
|
|
|
22
22
|
@load_path = attributes[:load_path]
|
|
23
23
|
@logical_path = attributes[:logical_path]
|
|
24
24
|
@metadata = attributes[:metadata]
|
|
25
|
-
@mtime = attributes[:mtime]
|
|
26
25
|
@name = attributes[:name]
|
|
27
26
|
@source = attributes[:source]
|
|
28
27
|
@uri = attributes[:uri]
|
|
@@ -68,6 +67,13 @@ module Sprockets
|
|
|
68
67
|
logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" }
|
|
69
68
|
end
|
|
70
69
|
|
|
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)
|
|
75
|
+
end
|
|
76
|
+
|
|
71
77
|
# Public: Returns String MIME type of asset. Returns nil if type is unknown.
|
|
72
78
|
attr_reader :content_type
|
|
73
79
|
|
|
@@ -80,14 +86,6 @@ module Sprockets
|
|
|
80
86
|
metadata[:links] || Set.new
|
|
81
87
|
end
|
|
82
88
|
|
|
83
|
-
# Public: Get all internally required assets that were concated into this
|
|
84
|
-
# asset.
|
|
85
|
-
#
|
|
86
|
-
# Returns Array of String asset URIs.
|
|
87
|
-
def included
|
|
88
|
-
metadata[:included]
|
|
89
|
-
end
|
|
90
|
-
|
|
91
89
|
# Public: Return `String` of concatenated source.
|
|
92
90
|
#
|
|
93
91
|
# Returns String.
|
|
@@ -120,22 +118,22 @@ module Sprockets
|
|
|
120
118
|
end
|
|
121
119
|
alias_method :bytesize, :length
|
|
122
120
|
|
|
121
|
+
# Public: Returns String byte digest of source.
|
|
122
|
+
def digest
|
|
123
|
+
metadata[:digest]
|
|
124
|
+
end
|
|
125
|
+
|
|
123
126
|
# Public: Returns String hexdigest of source.
|
|
124
127
|
def hexdigest
|
|
125
|
-
DigestUtils.pack_hexdigest(
|
|
128
|
+
DigestUtils.pack_hexdigest(digest)
|
|
126
129
|
end
|
|
127
130
|
|
|
128
|
-
# Deprecated: Returns String hexdigest of source.
|
|
129
|
-
#
|
|
130
|
-
# In 4.x this will be changed to return a raw Digest byte String.
|
|
131
|
-
alias_method :digest, :hexdigest
|
|
132
|
-
|
|
133
131
|
# Pubic: ETag String of Asset.
|
|
134
132
|
alias_method :etag, :hexdigest
|
|
135
133
|
|
|
136
134
|
# Public: Returns String base64 digest of source.
|
|
137
135
|
def base64digest
|
|
138
|
-
DigestUtils.pack_base64digest(
|
|
136
|
+
DigestUtils.pack_base64digest(digest)
|
|
139
137
|
end
|
|
140
138
|
|
|
141
139
|
# Public: A "named information" URL for subresource integrity.
|
|
@@ -166,9 +164,6 @@ module Sprockets
|
|
|
166
164
|
f.write source
|
|
167
165
|
end
|
|
168
166
|
|
|
169
|
-
# Set mtime correctly
|
|
170
|
-
File.utime(mtime, mtime, filename)
|
|
171
|
-
|
|
172
167
|
nil
|
|
173
168
|
end
|
|
174
169
|
|
data/lib/sprockets/autoload.rb
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Sprockets
|
|
2
3
|
module Autoload
|
|
4
|
+
autoload :Babel, 'sprockets/autoload/babel'
|
|
3
5
|
autoload :Closure, 'sprockets/autoload/closure'
|
|
4
6
|
autoload :CoffeeScript, 'sprockets/autoload/coffee_script'
|
|
5
7
|
autoload :Eco, 'sprockets/autoload/eco'
|
|
6
8
|
autoload :EJS, 'sprockets/autoload/ejs'
|
|
9
|
+
autoload :JSMinC, 'sprockets/autoload/jsminc'
|
|
7
10
|
autoload :Sass, 'sprockets/autoload/sass'
|
|
11
|
+
autoload :SassC, 'sprockets/autoload/sassc'
|
|
8
12
|
autoload :Uglifier, 'sprockets/autoload/uglifier'
|
|
9
13
|
autoload :YUI, 'sprockets/autoload/yui'
|
|
14
|
+
autoload :Zopfli, 'sprockets/autoload/zopfli'
|
|
10
15
|
end
|
|
11
16
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'sprockets/autoload'
|
|
3
|
+
require 'sprockets/path_utils'
|
|
4
|
+
require 'sprockets/source_map_utils'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
module Sprockets
|
|
8
|
+
class BabelProcessor
|
|
9
|
+
VERSION = '1'
|
|
10
|
+
|
|
11
|
+
def self.instance
|
|
12
|
+
@instance ||= new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.call(input)
|
|
16
|
+
instance.call(input)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.cache_key
|
|
20
|
+
instance.cache_key
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attr_reader :cache_key
|
|
24
|
+
|
|
25
|
+
def initialize(options = {})
|
|
26
|
+
@options = options.merge({
|
|
27
|
+
'blacklist' => (options['blacklist'] || []) + ['useStrict'],
|
|
28
|
+
'sourceMap' => true
|
|
29
|
+
}).freeze
|
|
30
|
+
|
|
31
|
+
@cache_key = [
|
|
32
|
+
self.class.name,
|
|
33
|
+
Autoload::Babel::Transpiler::VERSION,
|
|
34
|
+
Autoload::Babel::Source::VERSION,
|
|
35
|
+
VERSION,
|
|
36
|
+
@options
|
|
37
|
+
].freeze
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def call(input)
|
|
41
|
+
data = input[:data]
|
|
42
|
+
|
|
43
|
+
result = input[:cache].fetch(@cache_key + [input[:filename]] + [data]) do
|
|
44
|
+
opts = {
|
|
45
|
+
'moduleRoot' => nil,
|
|
46
|
+
'filename' => input[:filename],
|
|
47
|
+
'filenameRelative' => PathUtils.split_subpath(input[:load_path], input[:filename]),
|
|
48
|
+
'sourceFileName' => File.basename(input[:filename]),
|
|
49
|
+
'sourceMapTarget' => input[:filename]
|
|
50
|
+
}.merge(@options)
|
|
51
|
+
|
|
52
|
+
if opts['moduleIds'] && opts['moduleRoot']
|
|
53
|
+
opts['moduleId'] ||= File.join(opts['moduleRoot'], input[:name])
|
|
54
|
+
elsif opts['moduleIds']
|
|
55
|
+
opts['moduleId'] ||= input[:name]
|
|
56
|
+
end
|
|
57
|
+
Autoload::Babel::Transpiler.transform(data, opts)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
map = SourceMapUtils.format_source_map(result["map"], input)
|
|
61
|
+
map = SourceMapUtils.combine_source_maps(input[:metadata][:map], map)
|
|
62
|
+
|
|
63
|
+
{ data: result['code'], map: map }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/sprockets/base.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'sprockets/asset'
|
|
2
3
|
require 'sprockets/bower'
|
|
3
4
|
require 'sprockets/cache'
|
|
@@ -5,22 +6,36 @@ require 'sprockets/configuration'
|
|
|
5
6
|
require 'sprockets/digest_utils'
|
|
6
7
|
require 'sprockets/errors'
|
|
7
8
|
require 'sprockets/loader'
|
|
8
|
-
require 'sprockets/
|
|
9
|
+
require 'sprockets/npm'
|
|
9
10
|
require 'sprockets/path_dependency_utils'
|
|
11
|
+
require 'sprockets/path_digest_utils'
|
|
10
12
|
require 'sprockets/path_utils'
|
|
11
13
|
require 'sprockets/resolve'
|
|
12
14
|
require 'sprockets/server'
|
|
13
|
-
require 'sprockets/
|
|
15
|
+
require 'sprockets/source_map_utils'
|
|
14
16
|
require 'sprockets/uri_tar'
|
|
15
17
|
|
|
16
18
|
module Sprockets
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
class DoubleLinkError < Sprockets::Error
|
|
21
|
+
def initialize(parent_filename:, logical_path:, last_filename:, filename:)
|
|
22
|
+
super <<~MSG
|
|
23
|
+
Multiple files with the same output path cannot be linked (#{logical_path.inspect})
|
|
24
|
+
In #{parent_filename.inspect} these files were linked:
|
|
25
|
+
- #{last_filename}
|
|
26
|
+
- #{filename}
|
|
27
|
+
MSG
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# `Base` class for `Environment` and `CachedEnvironment`.
|
|
18
32
|
class Base
|
|
19
|
-
include PathUtils, PathDependencyUtils, PathDigestUtils, DigestUtils
|
|
33
|
+
include PathUtils, PathDependencyUtils, PathDigestUtils, DigestUtils, SourceMapUtils
|
|
20
34
|
include Configuration
|
|
21
35
|
include Server
|
|
22
36
|
include Resolve, Loader
|
|
23
37
|
include Bower
|
|
38
|
+
include Npm
|
|
24
39
|
|
|
25
40
|
# Get persistent cache store
|
|
26
41
|
attr_reader :cache
|
|
@@ -34,7 +49,7 @@ module Sprockets
|
|
|
34
49
|
@cache = Cache.new(cache, logger)
|
|
35
50
|
end
|
|
36
51
|
|
|
37
|
-
# Return an `
|
|
52
|
+
# Return an `CachedEnvironment`. Must be implemented by the subclass.
|
|
38
53
|
def cached
|
|
39
54
|
raise NotImplementedError
|
|
40
55
|
end
|
|
@@ -60,24 +75,36 @@ module Sprockets
|
|
|
60
75
|
end
|
|
61
76
|
|
|
62
77
|
# Find asset by logical path or expanded path.
|
|
63
|
-
def find_asset(
|
|
64
|
-
uri, _ = resolve(
|
|
78
|
+
def find_asset(*args, **options)
|
|
79
|
+
uri, _ = resolve(*args, **options)
|
|
65
80
|
if uri
|
|
66
81
|
load(uri)
|
|
67
82
|
end
|
|
68
83
|
end
|
|
69
84
|
|
|
70
|
-
def find_all_linked_assets(
|
|
71
|
-
return to_enum(__method__,
|
|
85
|
+
def find_all_linked_assets(*args)
|
|
86
|
+
return to_enum(__method__, *args) unless block_given?
|
|
72
87
|
|
|
73
|
-
asset = find_asset(
|
|
88
|
+
parent_asset = asset = find_asset(*args)
|
|
74
89
|
return unless asset
|
|
75
90
|
|
|
76
91
|
yield asset
|
|
77
92
|
stack = asset.links.to_a
|
|
93
|
+
linked_paths = {}
|
|
78
94
|
|
|
79
95
|
while uri = stack.shift
|
|
80
96
|
yield asset = load(uri)
|
|
97
|
+
|
|
98
|
+
last_filename = linked_paths[asset.logical_path]
|
|
99
|
+
if last_filename && last_filename != asset.filename
|
|
100
|
+
raise DoubleLinkError.new(
|
|
101
|
+
parent_filename: parent_asset.filename,
|
|
102
|
+
last_filename: last_filename,
|
|
103
|
+
logical_path: asset.logical_path,
|
|
104
|
+
filename: asset.filename
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
linked_paths[asset.logical_path] = asset.filename
|
|
81
108
|
stack = asset.links.to_a + stack
|
|
82
109
|
end
|
|
83
110
|
|
|
@@ -92,6 +119,16 @@ module Sprockets
|
|
|
92
119
|
find_asset(*args)
|
|
93
120
|
end
|
|
94
121
|
|
|
122
|
+
# Find asset by logical path or expanded path.
|
|
123
|
+
#
|
|
124
|
+
# If the asset is not found an error will be raised.
|
|
125
|
+
def find_asset!(*args)
|
|
126
|
+
uri, _ = resolve!(*args)
|
|
127
|
+
if uri
|
|
128
|
+
load(uri)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
95
132
|
# Pretty inspect
|
|
96
133
|
def inspect
|
|
97
134
|
"#<#{self.class}:0x#{object_id.to_s(16)} " +
|
data/lib/sprockets/bower.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'json'
|
|
2
3
|
|
|
3
4
|
module Sprockets
|
|
@@ -17,7 +18,7 @@ module Sprockets
|
|
|
17
18
|
candidates, deps = super
|
|
18
19
|
|
|
19
20
|
# bower.json can only be nested one level deep
|
|
20
|
-
if !logical_path.index('/')
|
|
21
|
+
if !logical_path.index('/'.freeze)
|
|
21
22
|
dirname = File.join(load_path, logical_path)
|
|
22
23
|
|
|
23
24
|
if directory?(dirname)
|
|
@@ -27,7 +28,9 @@ module Sprockets
|
|
|
27
28
|
if filename
|
|
28
29
|
deps << build_file_digest_uri(filename)
|
|
29
30
|
read_bower_main(dirname, filename) do |path|
|
|
30
|
-
|
|
31
|
+
if file?(path)
|
|
32
|
+
candidates << path
|
|
33
|
+
end
|
|
31
34
|
end
|
|
32
35
|
end
|
|
33
36
|
end
|
data/lib/sprockets/bundle.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'set'
|
|
2
3
|
require 'sprockets/utils'
|
|
4
|
+
require 'sprockets/uri_utils'
|
|
3
5
|
|
|
4
6
|
module Sprockets
|
|
5
7
|
# Internal: Bundle processor takes a single file asset and prepends all the
|
|
@@ -15,15 +17,32 @@ module Sprockets
|
|
|
15
17
|
def self.call(input)
|
|
16
18
|
env = input[:environment]
|
|
17
19
|
type = input[:content_type]
|
|
20
|
+
input[:links] ||= Set.new
|
|
18
21
|
dependencies = Set.new(input[:metadata][:dependencies])
|
|
19
22
|
|
|
20
|
-
processed_uri, deps = env.resolve(input[:filename], accept: type, pipeline: :self
|
|
23
|
+
processed_uri, deps = env.resolve(input[:filename], accept: type, pipeline: :self)
|
|
21
24
|
dependencies.merge(deps)
|
|
22
25
|
|
|
26
|
+
# DirectiveProcessor (and any other transformers called here with pipeline=self)
|
|
27
|
+
primary_asset = env.load(processed_uri)
|
|
28
|
+
to_load = primary_asset.metadata.delete(:to_load) || Set.new
|
|
29
|
+
to_link = primary_asset.metadata.delete(:to_link) || Set.new
|
|
30
|
+
|
|
31
|
+
to_load.each do |uri|
|
|
32
|
+
loaded_asset = env.load(uri)
|
|
33
|
+
dependencies.merge(loaded_asset.metadata[:dependencies])
|
|
34
|
+
if to_link.include?(uri)
|
|
35
|
+
primary_metadata = primary_asset.metadata
|
|
36
|
+
input[:links] << loaded_asset.uri
|
|
37
|
+
primary_metadata[:links] << loaded_asset.uri
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
23
41
|
find_required = proc { |uri| env.load(uri).metadata[:required] }
|
|
24
42
|
required = Utils.dfs(processed_uri, &find_required)
|
|
25
43
|
stubbed = Utils.dfs(env.load(processed_uri).metadata[:stubbed], &find_required)
|
|
26
44
|
required.subtract(stubbed)
|
|
45
|
+
dedup(required)
|
|
27
46
|
assets = required.map { |uri| env.load(uri) }
|
|
28
47
|
|
|
29
48
|
(required + stubbed).each do |uri|
|
|
@@ -31,21 +50,38 @@ module Sprockets
|
|
|
31
50
|
end
|
|
32
51
|
|
|
33
52
|
reducers = Hash[env.match_mime_type_keys(env.config[:bundle_reducers], type).flat_map(&:to_a)]
|
|
34
|
-
process_bundle_reducers(assets, reducers).merge(dependencies: dependencies, included: assets.map(&:uri))
|
|
53
|
+
process_bundle_reducers(input, assets, reducers).merge(dependencies: dependencies, included: assets.map(&:uri))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Internal: Removes uri from required if it's already included as an alias.
|
|
57
|
+
#
|
|
58
|
+
# required - Set of required uris
|
|
59
|
+
#
|
|
60
|
+
# Returns deduped set of uris
|
|
61
|
+
def self.dedup(required)
|
|
62
|
+
dupes = required.reduce([]) do |r, uri|
|
|
63
|
+
path, params = URIUtils.parse_asset_uri(uri)
|
|
64
|
+
if (params.delete(:index_alias))
|
|
65
|
+
r << URIUtils.build_asset_uri(path, params)
|
|
66
|
+
end
|
|
67
|
+
r
|
|
68
|
+
end
|
|
69
|
+
required.subtract(dupes)
|
|
35
70
|
end
|
|
36
71
|
|
|
37
72
|
# Internal: Run bundle reducers on set of Assets producing a reduced
|
|
38
73
|
# metadata Hash.
|
|
39
74
|
#
|
|
75
|
+
# filename - String bundle filename
|
|
40
76
|
# assets - Array of Assets
|
|
41
77
|
# reducers - Array of [initial, reducer_proc] pairs
|
|
42
78
|
#
|
|
43
79
|
# Returns reduced asset metadata Hash.
|
|
44
|
-
def self.process_bundle_reducers(assets, reducers)
|
|
80
|
+
def self.process_bundle_reducers(input, assets, reducers)
|
|
45
81
|
initial = {}
|
|
46
82
|
reducers.each do |k, (v, _)|
|
|
47
83
|
if v.respond_to?(:call)
|
|
48
|
-
initial[k] = v.call
|
|
84
|
+
initial[k] = v.call(input)
|
|
49
85
|
elsif !v.nil?
|
|
50
86
|
initial[k] = v
|
|
51
87
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'fileutils'
|
|
2
3
|
require 'logger'
|
|
3
4
|
require 'sprockets/encoding_utils'
|
|
@@ -19,7 +20,9 @@ module Sprockets
|
|
|
19
20
|
class FileStore
|
|
20
21
|
# Internal: Default key limit for store.
|
|
21
22
|
DEFAULT_MAX_SIZE = 25 * 1024 * 1024
|
|
22
|
-
|
|
23
|
+
EXCLUDED_DIRS = ['.', '..'].freeze
|
|
24
|
+
GITKEEP_FILES = ['.gitkeep', '.keep'].freeze
|
|
25
|
+
|
|
23
26
|
# Internal: Default standard error fatal logger.
|
|
24
27
|
#
|
|
25
28
|
# Returns a Logger.
|
|
@@ -32,8 +35,10 @@ module Sprockets
|
|
|
32
35
|
# Public: Initialize the cache store.
|
|
33
36
|
#
|
|
34
37
|
# root - A String path to a directory to persist cached values to.
|
|
35
|
-
# max_size - A Integer of the maximum
|
|
36
|
-
# (default:
|
|
38
|
+
# max_size - A Integer of the maximum size the store will hold (in bytes).
|
|
39
|
+
# (default: 25MB).
|
|
40
|
+
# logger - The logger to which some info will be printed.
|
|
41
|
+
# (default logger level is FATAL and won't output anything).
|
|
37
42
|
def initialize(root, max_size = DEFAULT_MAX_SIZE, logger = self.class.default_logger)
|
|
38
43
|
@root = root
|
|
39
44
|
@max_size = max_size
|
|
@@ -122,6 +127,23 @@ module Sprockets
|
|
|
122
127
|
"#<#{self.class} size=#{size}/#{@max_size}>"
|
|
123
128
|
end
|
|
124
129
|
|
|
130
|
+
# Public: Clear the cache
|
|
131
|
+
#
|
|
132
|
+
# adapted from ActiveSupport::Cache::FileStore#clear
|
|
133
|
+
#
|
|
134
|
+
# Deletes all items from the cache. In this case it deletes all the entries in the specified
|
|
135
|
+
# file store directory except for .keep or .gitkeep. Be careful which directory is specified
|
|
136
|
+
# as @root because everything in that directory will be deleted.
|
|
137
|
+
#
|
|
138
|
+
# Returns true
|
|
139
|
+
def clear(options=nil)
|
|
140
|
+
if File.exist?(@root)
|
|
141
|
+
root_dirs = Dir.entries(@root).reject { |f| (EXCLUDED_DIRS + GITKEEP_FILES).include?(f) }
|
|
142
|
+
FileUtils.rm_r(root_dirs.collect{ |f| File.join(@root, f) })
|
|
143
|
+
end
|
|
144
|
+
true
|
|
145
|
+
end
|
|
146
|
+
|
|
125
147
|
private
|
|
126
148
|
# Internal: Get all cache files along with stats.
|
|
127
149
|
#
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Sprockets
|
|
2
3
|
class Cache
|
|
3
4
|
# Public: Basic in memory LRU cache.
|
|
@@ -61,6 +62,14 @@ module Sprockets
|
|
|
61
62
|
def inspect
|
|
62
63
|
"#<#{self.class} size=#{@cache.size}/#{@max_size}>"
|
|
63
64
|
end
|
|
65
|
+
|
|
66
|
+
# Public: Clear the cache
|
|
67
|
+
#
|
|
68
|
+
# Returns true
|
|
69
|
+
def clear(options=nil)
|
|
70
|
+
@cache.clear
|
|
71
|
+
true
|
|
72
|
+
end
|
|
64
73
|
end
|
|
65
74
|
end
|
|
66
75
|
end
|