sprockets 2.2.3 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +68 -0
- data/README.md +482 -255
- data/bin/sprockets +20 -7
- data/lib/rake/sprocketstask.rb +28 -15
- data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
- data/lib/sprockets/asset.rb +142 -207
- data/lib/sprockets/autoload/babel.rb +8 -0
- data/lib/sprockets/autoload/closure.rb +8 -0
- data/lib/sprockets/autoload/coffee_script.rb +8 -0
- data/lib/sprockets/autoload/eco.rb +8 -0
- data/lib/sprockets/autoload/ejs.rb +8 -0
- data/lib/sprockets/autoload/jsminc.rb +8 -0
- data/lib/sprockets/autoload/sass.rb +8 -0
- data/lib/sprockets/autoload/sassc.rb +8 -0
- data/lib/sprockets/autoload/uglifier.rb +8 -0
- data/lib/sprockets/autoload/yui.rb +8 -0
- data/lib/sprockets/autoload/zopfli.rb +7 -0
- data/lib/sprockets/autoload.rb +16 -0
- data/lib/sprockets/babel_processor.rb +66 -0
- data/lib/sprockets/base.rb +89 -249
- data/lib/sprockets/bower.rb +61 -0
- data/lib/sprockets/bundle.rb +105 -0
- data/lib/sprockets/cache/file_store.rb +190 -14
- data/lib/sprockets/cache/memory_store.rb +75 -0
- data/lib/sprockets/cache/null_store.rb +54 -0
- data/lib/sprockets/cache.rb +271 -0
- data/lib/sprockets/cached_environment.rb +64 -0
- data/lib/sprockets/closure_compressor.rb +48 -0
- data/lib/sprockets/coffee_script_processor.rb +39 -0
- data/lib/sprockets/compressing.rb +134 -0
- data/lib/sprockets/configuration.rb +79 -0
- data/lib/sprockets/context.rb +204 -135
- data/lib/sprockets/dependencies.rb +74 -0
- data/lib/sprockets/digest_utils.rb +200 -0
- data/lib/sprockets/directive_processor.rb +224 -216
- data/lib/sprockets/eco_processor.rb +33 -0
- data/lib/sprockets/ejs_processor.rb +32 -0
- data/lib/sprockets/encoding_utils.rb +262 -0
- data/lib/sprockets/environment.rb +23 -68
- data/lib/sprockets/erb_processor.rb +37 -0
- data/lib/sprockets/errors.rb +6 -13
- 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 +16 -0
- data/lib/sprockets/http_utils.rb +135 -0
- data/lib/sprockets/jsminc_compressor.rb +32 -0
- data/lib/sprockets/jst_processor.rb +36 -19
- data/lib/sprockets/loader.rb +343 -0
- data/lib/sprockets/manifest.rb +231 -96
- data/lib/sprockets/manifest_utils.rb +48 -0
- data/lib/sprockets/mime.rb +80 -32
- data/lib/sprockets/npm.rb +52 -0
- data/lib/sprockets/path_dependency_utils.rb +77 -0
- data/lib/sprockets/path_digest_utils.rb +48 -0
- data/lib/sprockets/path_utils.rb +367 -0
- data/lib/sprockets/paths.rb +82 -0
- data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
- data/lib/sprockets/processing.rb +140 -192
- data/lib/sprockets/processor_utils.rb +169 -0
- data/lib/sprockets/resolve.rb +295 -0
- data/lib/sprockets/sass_cache_store.rb +30 -0
- data/lib/sprockets/sass_compressor.rb +63 -0
- data/lib/sprockets/sass_functions.rb +3 -0
- data/lib/sprockets/sass_importer.rb +3 -0
- data/lib/sprockets/sass_processor.rb +313 -0
- data/lib/sprockets/sassc_compressor.rb +56 -0
- data/lib/sprockets/sassc_processor.rb +297 -0
- data/lib/sprockets/server.rb +138 -90
- data/lib/sprockets/source_map_processor.rb +66 -0
- data/lib/sprockets/source_map_utils.rb +483 -0
- data/lib/sprockets/transformers.rb +173 -0
- data/lib/sprockets/uglifier_compressor.rb +66 -0
- data/lib/sprockets/unloaded_asset.rb +139 -0
- data/lib/sprockets/uri_tar.rb +99 -0
- data/lib/sprockets/uri_utils.rb +191 -0
- data/lib/sprockets/utils/gzip.rb +99 -0
- data/lib/sprockets/utils.rb +186 -53
- data/lib/sprockets/version.rb +2 -1
- data/lib/sprockets/yui_compressor.rb +56 -0
- data/lib/sprockets.rb +217 -52
- metadata +250 -59
- data/LICENSE +0 -21
- data/lib/sprockets/asset_attributes.rb +0 -126
- data/lib/sprockets/bundled_asset.rb +0 -79
- data/lib/sprockets/caching.rb +0 -96
- data/lib/sprockets/charset_normalizer.rb +0 -41
- data/lib/sprockets/eco_template.rb +0 -38
- data/lib/sprockets/ejs_template.rb +0 -37
- data/lib/sprockets/engines.rb +0 -74
- data/lib/sprockets/index.rb +0 -99
- data/lib/sprockets/processed_asset.rb +0 -152
- data/lib/sprockets/processor.rb +0 -32
- data/lib/sprockets/safety_colons.rb +0 -28
- data/lib/sprockets/static_asset.rb +0 -57
- 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
|
-
|
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 |
|
59
|
-
|
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/
|
82
|
+
warn "Usage: sprockets -Ijavascripts/ path"
|
70
83
|
exit 1
|
71
84
|
end
|
72
85
|
|
73
86
|
if manifest
|
74
|
-
manifest.compile(
|
75
|
-
elsif
|
76
|
-
puts environment.find_asset(
|
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
|
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
|
|
@@ -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 :
|
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 :
|
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
|
-
|
134
|
-
|
144
|
+
if env = manifest.environment
|
145
|
+
old_logger = env.logger
|
146
|
+
env.logger = @logger
|
147
|
+
end
|
135
148
|
yield
|
136
149
|
ensure
|
137
|
-
|
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
|
data/lib/sprockets/asset.rb
CHANGED
@@ -1,260 +1,195 @@
|
|
1
|
-
|
2
|
-
require '
|
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
|
-
|
8
|
-
def self.from_hash(environment, hash)
|
9
|
-
return unless hash.is_a?(Hash)
|
7
|
+
attr_reader :logical_path
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@
|
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
|
-
#
|
45
|
-
|
46
|
-
|
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
|
-
|
49
|
-
|
50
|
-
@digest = coder['digest']
|
46
|
+
# Public: Returns String path of asset.
|
47
|
+
attr_reader :filename
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
-
#
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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| "-#{
|
67
|
+
logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" }
|
85
68
|
end
|
86
69
|
|
87
|
-
# Return
|
88
|
-
|
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
|
-
#
|
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
|
-
#
|
95
|
-
# the asset's contents as a whole.
|
82
|
+
# All linked assets should be compiled anytime this asset is.
|
96
83
|
#
|
97
|
-
#
|
98
|
-
|
99
|
-
|
100
|
-
[self]
|
84
|
+
# Returns Set of String asset URIs.
|
85
|
+
def links
|
86
|
+
metadata[:links] || Set.new
|
101
87
|
end
|
102
88
|
|
103
|
-
# `
|
104
|
-
|
105
|
-
|
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
|
-
#
|
101
|
+
# Public: Alias for #source.
|
102
|
+
#
|
103
|
+
# Returns String.
|
109
104
|
def to_s
|
110
105
|
source
|
111
106
|
end
|
112
107
|
|
113
|
-
#
|
114
|
-
#
|
115
|
-
|
116
|
-
|
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
|
-
#
|
120
|
-
|
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
|
-
#
|
129
|
-
|
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
|
-
#
|
137
|
-
def
|
138
|
-
|
139
|
-
|
126
|
+
# Public: Returns String hexdigest of source.
|
127
|
+
def hexdigest
|
128
|
+
DigestUtils.pack_hexdigest(digest)
|
129
|
+
end
|
140
130
|
|
141
|
-
|
131
|
+
# Pubic: ETag String of Asset.
|
132
|
+
alias_method :etag, :hexdigest
|
142
133
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
-
|
157
|
-
|
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
|
-
|
160
|
-
|
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}
|
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
|
-
|
182
|
+
id.hash
|
179
183
|
end
|
180
184
|
|
181
|
-
#
|
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
|
-
|
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
|