bpm 1.0.0.beta.8 → 1.0.0.beta.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +9 -0
  3. data/bpm.gemspec +2 -7
  4. data/lib/bpm/pipeline/generated_asset.rb +19 -21
  5. data/lib/bpm/pipeline/plugin_context.rb +7 -7
  6. data/lib/bpm/pipeline/plugin_processor.rb +11 -20
  7. data/lib/bpm/pipeline/transport_processor.rb +8 -13
  8. data/lib/bpm/pipeline.rb +47 -42
  9. data/lib/bpm/project_generator.rb +2 -2
  10. data/lib/bpm/version.rb +1 -1
  11. data/lib/bpm.rb +0 -3
  12. data/spec/cli/init_spec.rb +48 -48
  13. data/spec/cli/rebuild_spec.rb +30 -30
  14. data/spec/fixtures/projects/init_app/assets/bpm_libs.js +1 -1
  15. data/spec/fixtures/projects/init_app/assets/bpm_styles.css +1 -1
  16. data/spec/fixtures/projects/init_default/assets/bpm_libs.js +1 -1
  17. data/spec/fixtures/projects/init_default/assets/bpm_styles.css +1 -1
  18. data/spec/plugins/minifier_spec.rb +8 -8
  19. data/templates/project/index.html +0 -2
  20. data/templates/project/{app → lib}/main.js +0 -0
  21. metadata +24 -209
  22. data/.gitmodules +0 -3
  23. data/vendor/sprockets/.gitignore +0 -7
  24. data/vendor/sprockets/.travis.yml +0 -7
  25. data/vendor/sprockets/Gemfile +0 -2
  26. data/vendor/sprockets/LICENSE +0 -20
  27. data/vendor/sprockets/README.md +0 -22
  28. data/vendor/sprockets/Rakefile +0 -8
  29. data/vendor/sprockets/lib/sprockets/asset.rb +0 -198
  30. data/vendor/sprockets/lib/sprockets/asset_attributes.rb +0 -178
  31. data/vendor/sprockets/lib/sprockets/base.rb +0 -134
  32. data/vendor/sprockets/lib/sprockets/bundled_asset.rb +0 -249
  33. data/vendor/sprockets/lib/sprockets/cache/file_store.rb +0 -41
  34. data/vendor/sprockets/lib/sprockets/caching.rb +0 -126
  35. data/vendor/sprockets/lib/sprockets/charset_normalizer.rb +0 -41
  36. data/vendor/sprockets/lib/sprockets/context.rb +0 -221
  37. data/vendor/sprockets/lib/sprockets/digest.rb +0 -73
  38. data/vendor/sprockets/lib/sprockets/directive_processor.rb +0 -397
  39. data/vendor/sprockets/lib/sprockets/eco_template.rb +0 -38
  40. data/vendor/sprockets/lib/sprockets/ejs_template.rb +0 -37
  41. data/vendor/sprockets/lib/sprockets/engines.rb +0 -117
  42. data/vendor/sprockets/lib/sprockets/environment.rb +0 -94
  43. data/vendor/sprockets/lib/sprockets/errors.rb +0 -17
  44. data/vendor/sprockets/lib/sprockets/index.rb +0 -81
  45. data/vendor/sprockets/lib/sprockets/jst_processor.rb +0 -26
  46. data/vendor/sprockets/lib/sprockets/mime.rb +0 -38
  47. data/vendor/sprockets/lib/sprockets/processing.rb +0 -269
  48. data/vendor/sprockets/lib/sprockets/processor.rb +0 -32
  49. data/vendor/sprockets/lib/sprockets/safety_colons.rb +0 -28
  50. data/vendor/sprockets/lib/sprockets/server.rb +0 -270
  51. data/vendor/sprockets/lib/sprockets/static_asset.rb +0 -86
  52. data/vendor/sprockets/lib/sprockets/static_compilation.rb +0 -74
  53. data/vendor/sprockets/lib/sprockets/trail.rb +0 -123
  54. data/vendor/sprockets/lib/sprockets/utils.rb +0 -67
  55. data/vendor/sprockets/lib/sprockets/version.rb +0 -3
  56. data/vendor/sprockets/lib/sprockets.rb +0 -31
  57. data/vendor/sprockets/sprockets.gemspec +0 -30
  58. data/vendor/sprockets/test/fixtures/asset/POW.png +0 -0
  59. data/vendor/sprockets/test/fixtures/asset/application.js +0 -6
  60. data/vendor/sprockets/test/fixtures/asset/bar-utf8.css +0 -2
  61. data/vendor/sprockets/test/fixtures/asset/charset.css +0 -2
  62. data/vendor/sprockets/test/fixtures/asset/circle/a.js +0 -2
  63. data/vendor/sprockets/test/fixtures/asset/circle/b.js +0 -2
  64. data/vendor/sprockets/test/fixtures/asset/circle/c.js +0 -2
  65. data/vendor/sprockets/test/fixtures/asset/compat.js +0 -4
  66. data/vendor/sprockets/test/fixtures/asset/constants.js +0 -2
  67. data/vendor/sprockets/test/fixtures/asset/constants.yml +0 -1
  68. data/vendor/sprockets/test/fixtures/asset/default_mime_type.js +0 -1
  69. data/vendor/sprockets/test/fixtures/asset/filename.js.erb +0 -1
  70. data/vendor/sprockets/test/fixtures/asset/foo-utf8.css +0 -2
  71. data/vendor/sprockets/test/fixtures/asset/included_header.js +0 -4
  72. data/vendor/sprockets/test/fixtures/asset/jquery.tmpl.min.js +0 -1
  73. data/vendor/sprockets/test/fixtures/asset/mismatch.js +0 -1
  74. data/vendor/sprockets/test/fixtures/asset/multiple.js +0 -2
  75. data/vendor/sprockets/test/fixtures/asset/multipleengine.js +0 -1
  76. data/vendor/sprockets/test/fixtures/asset/noengine.js +0 -1
  77. data/vendor/sprockets/test/fixtures/asset/noformat.coffee +0 -1
  78. data/vendor/sprockets/test/fixtures/asset/one.css +0 -1
  79. data/vendor/sprockets/test/fixtures/asset/oneengine.js +0 -1
  80. data/vendor/sprockets/test/fixtures/asset/project.css +0 -1
  81. data/vendor/sprockets/test/fixtures/asset/project.js.erb +0 -4
  82. data/vendor/sprockets/test/fixtures/asset/relative/include.js +0 -4
  83. data/vendor/sprockets/test/fixtures/asset/relative/require.js +0 -1
  84. data/vendor/sprockets/test/fixtures/asset/relative/require_outside_path.js +0 -1
  85. data/vendor/sprockets/test/fixtures/asset/require_self.css +0 -9
  86. data/vendor/sprockets/test/fixtures/asset/require_self_twice.css +0 -8
  87. data/vendor/sprockets/test/fixtures/asset/semicolons/bar.js +0 -1
  88. data/vendor/sprockets/test/fixtures/asset/semicolons/index.js +0 -5
  89. data/vendor/sprockets/test/fixtures/asset/sprite.css.erb +0 -12
  90. data/vendor/sprockets/test/fixtures/asset/tree/all/b/c/d.js +0 -2
  91. data/vendor/sprockets/test/fixtures/asset/tree/all/b/c/e.js +0 -1
  92. data/vendor/sprockets/test/fixtures/asset/tree/all/b/c.js +0 -1
  93. data/vendor/sprockets/test/fixtures/asset/tree/all/b.css +0 -2
  94. data/vendor/sprockets/test/fixtures/asset/tree/all/b.js.erb +0 -1
  95. data/vendor/sprockets/test/fixtures/asset/tree/all/d/c.js.coffee +0 -1
  96. data/vendor/sprockets/test/fixtures/asset/tree/all/d/e.js +0 -1
  97. data/vendor/sprockets/test/fixtures/asset/tree/all_with_require.js +0 -7
  98. data/vendor/sprockets/test/fixtures/asset/tree/all_with_require_directory.js +0 -1
  99. data/vendor/sprockets/test/fixtures/asset/tree/all_with_require_tree.js +0 -2
  100. data/vendor/sprockets/test/fixtures/asset/tree/directory/application.js +0 -2
  101. data/vendor/sprockets/test/fixtures/asset/tree/directory/bar.js +0 -1
  102. data/vendor/sprockets/test/fixtures/asset/tree/directory/foo.js +0 -1
  103. data/vendor/sprockets/test/fixtures/asset/tree/tree/application.js +0 -2
  104. data/vendor/sprockets/test/fixtures/asset/tree/tree/bar.js +0 -1
  105. data/vendor/sprockets/test/fixtures/asset/tree/tree/foo.js +0 -1
  106. data/vendor/sprockets/test/fixtures/asset/tree/with_logical_path/a/a.js +0 -1
  107. data/vendor/sprockets/test/fixtures/asset/tree/with_logical_path/require_tree_with_logical_path.js +0 -1
  108. data/vendor/sprockets/test/fixtures/asset/tree/without_argument/a.js +0 -1
  109. data/vendor/sprockets/test/fixtures/asset/tree/without_argument/b.js +0 -1
  110. data/vendor/sprockets/test/fixtures/asset/tree/without_argument/require_tree_without_argument.js +0 -1
  111. data/vendor/sprockets/test/fixtures/asset/two.css +0 -1
  112. data/vendor/sprockets/test/fixtures/asset/unicode.js +0 -2
  113. data/vendor/sprockets/test/fixtures/asset/unknownexts.min.js +0 -2
  114. data/vendor/sprockets/test/fixtures/asset/users.js.erb.str +0 -4
  115. data/vendor/sprockets/test/fixtures/context/POW.png +0 -0
  116. data/vendor/sprockets/test/fixtures/context/application.js.yml +0 -3
  117. data/vendor/sprockets/test/fixtures/context/bar.js +0 -1
  118. data/vendor/sprockets/test/fixtures/context/foo.js +0 -2
  119. data/vendor/sprockets/test/fixtures/context/helpers.css.erb +0 -3
  120. data/vendor/sprockets/test/fixtures/context/properties.js.erb +0 -7
  121. data/vendor/sprockets/test/fixtures/context/require_glob.js +0 -1
  122. data/vendor/sprockets/test/fixtures/context/resolve_content_type.js.erb +0 -4
  123. data/vendor/sprockets/test/fixtures/context/sprite.css.embed +0 -3
  124. data/vendor/sprockets/test/fixtures/default/application.js.coffee +0 -4
  125. data/vendor/sprockets/test/fixtures/default/blank.gif +0 -0
  126. data/vendor/sprockets/test/fixtures/default/coffee/foo.coffee +0 -1
  127. data/vendor/sprockets/test/fixtures/default/coffee/index.js +0 -3
  128. data/vendor/sprockets/test/fixtures/default/empty +0 -0
  129. data/vendor/sprockets/test/fixtures/default/gallery.css.erb +0 -3
  130. data/vendor/sprockets/test/fixtures/default/gallery.js +0 -1
  131. data/vendor/sprockets/test/fixtures/default/goodbye.jst.eco +0 -1
  132. data/vendor/sprockets/test/fixtures/default/hello.jst.ejs +0 -1
  133. data/vendor/sprockets/test/fixtures/default/hello.txt +0 -1
  134. data/vendor/sprockets/test/fixtures/default/interpolation.js +0 -1
  135. data/vendor/sprockets/test/fixtures/default/missing_require.js +0 -1
  136. data/vendor/sprockets/test/fixtures/default/mobile/a.js +0 -1
  137. data/vendor/sprockets/test/fixtures/default/mobile/b.js +0 -1
  138. data/vendor/sprockets/test/fixtures/default/mobile/c.css +0 -1
  139. data/vendor/sprockets/test/fixtures/default/mobile/d.css +0 -1
  140. data/vendor/sprockets/test/fixtures/default/mobile/index.css +0 -3
  141. data/vendor/sprockets/test/fixtures/default/mobile/index.js +0 -1
  142. data/vendor/sprockets/test/fixtures/default/noreturn.js +0 -1
  143. data/vendor/sprockets/test/fixtures/default/project.js.coffee.erb +0 -2
  144. data/vendor/sprockets/test/fixtures/default/with_data_uri.css.erb +0 -3
  145. data/vendor/sprockets/test/fixtures/directives/code_before_comment +0 -3
  146. data/vendor/sprockets/test/fixtures/directives/comment_without_directives +0 -6
  147. data/vendor/sprockets/test/fixtures/directives/directive_word_splitting +0 -6
  148. data/vendor/sprockets/test/fixtures/directives/directives_after_header +0 -16
  149. data/vendor/sprockets/test/fixtures/directives/double_slash +0 -9
  150. data/vendor/sprockets/test/fixtures/directives/hash +0 -8
  151. data/vendor/sprockets/test/fixtures/directives/no_header +0 -2
  152. data/vendor/sprockets/test/fixtures/directives/slash_star +0 -10
  153. data/vendor/sprockets/test/fixtures/directives/slash_star_single +0 -4
  154. data/vendor/sprockets/test/fixtures/directives/space_between_directive_word +0 -2
  155. data/vendor/sprockets/test/fixtures/directives/triple_hash +0 -10
  156. data/vendor/sprockets/test/fixtures/encoding/ascii.js +0 -1
  157. data/vendor/sprockets/test/fixtures/encoding/ascii_utf8.js +0 -2
  158. data/vendor/sprockets/test/fixtures/encoding/utf16.js +0 -0
  159. data/vendor/sprockets/test/fixtures/encoding/utf8.js +0 -1
  160. data/vendor/sprockets/test/fixtures/encoding/utf8_bom.js +0 -1
  161. data/vendor/sprockets/test/fixtures/engines/hello.alert +0 -1
  162. data/vendor/sprockets/test/fixtures/engines/moo.js.str +0 -1
  163. data/vendor/sprockets/test/fixtures/public/compiled-digest-0aa2105d29558f3eb790d411d7d8fb66.js +0 -3
  164. data/vendor/sprockets/test/fixtures/public/compiled-digest-1c41eb0cf934a0c76babe875f982f9d1.js +0 -1
  165. data/vendor/sprockets/test/fixtures/server/app/javascripts/application.js +0 -5
  166. data/vendor/sprockets/test/fixtures/server/app/javascripts/bar.js +0 -1
  167. data/vendor/sprockets/test/fixtures/server/app/javascripts/foo.js +0 -1
  168. data/vendor/sprockets/test/fixtures/server/app/javascripts/hello.txt +0 -2
  169. data/vendor/sprockets/test/fixtures/server/app/javascripts/tree.js +0 -1
  170. data/vendor/sprockets/test/fixtures/server/vendor/javascripts/missing_require.js +0 -1
  171. data/vendor/sprockets/test/fixtures/server/vendor/stylesheets/missing_require.css +0 -1
  172. data/vendor/sprockets/test/sprockets_test.rb +0 -56
  173. data/vendor/sprockets/test/test_asset.rb +0 -699
  174. data/vendor/sprockets/test/test_asset_attributes.rb +0 -150
  175. data/vendor/sprockets/test/test_caching.rb +0 -62
  176. data/vendor/sprockets/test/test_context.rb +0 -115
  177. data/vendor/sprockets/test/test_directive_processor.rb +0 -124
  178. data/vendor/sprockets/test/test_encoding.rb +0 -65
  179. data/vendor/sprockets/test/test_engines.rb +0 -73
  180. data/vendor/sprockets/test/test_environment.rb +0 -587
  181. data/vendor/sprockets/test/test_server.rb +0 -227
@@ -1,178 +0,0 @@
1
- require 'pathname'
2
-
3
- module Sprockets
4
- # `AssetAttributes` is a wrapper similar to `Pathname` that provides
5
- # some helper accessors.
6
- #
7
- # These methods should be considered internalish.
8
- class AssetAttributes
9
- attr_reader :environment, :pathname
10
-
11
- def initialize(environment, path)
12
- @environment = environment
13
- @pathname = path.is_a?(Pathname) ? path : Pathname.new(path.to_s)
14
- end
15
-
16
- # Replaces `$root` placeholder with actual environment root.
17
- def expand_root
18
- pathname.to_s.sub(/^\$root/, environment.root)
19
- end
20
-
21
- # Replaces environment root with `$root` placeholder.
22
- def relativize_root
23
- pathname.to_s.sub(/^#{Regexp.escape(environment.root)}/, '$root')
24
- end
25
-
26
- # Strips `$HOME` and environment root for a nicer output.
27
- def pretty_path
28
- @pretty_path ||= @pathname.
29
- sub(/^#{Regexp.escape(ENV['HOME'] || '')}/, '~').
30
- sub(/^#{Regexp.escape(environment.root)}\//, '')
31
- end
32
-
33
- # Returns paths search the load path for.
34
- def search_paths
35
- paths = [pathname.to_s]
36
-
37
- if format_extension && engine_extensions.empty?
38
- environment.engine_formats(format_extension).each do |ext, engine|
39
- paths << pathname.sub(format_extension, ext).to_s
40
- end
41
- end
42
-
43
- if pathname.basename(extensions.join).to_s != 'index'
44
- path_without_extensions = extensions.inject(pathname) { |p, ext| p.sub(ext, '') }
45
- index_path = path_without_extensions.join("index#{extensions.join}").to_s
46
-
47
- paths << index_path
48
-
49
- if format_extension && engine_extensions.empty?
50
- environment.engine_formats(format_extension).each do |ext, engine|
51
- paths << index_path.sub(format_extension, ext).to_s
52
- end
53
- end
54
- end
55
-
56
- paths
57
- end
58
-
59
- # Reverse guess logical path for fully expanded path.
60
- #
61
- # This has some known issues. For an example if a file is
62
- # shaddowed in the path, but is required relatively, its logical
63
- # path will be incorrect.
64
- def logical_path
65
- raise ArgumentError unless pathname.absolute?
66
-
67
- if root_path = environment.paths.detect { |path| pathname.to_s[path] }
68
- path = pathname.relative_path_from(Pathname.new(root_path)).to_s
69
- path = engine_extensions.inject(path) { |p, ext| p.sub(ext, '') }
70
- path = "#{path}#{engine_format_extension}" unless format_extension
71
- path
72
- end
73
- end
74
-
75
- # Returns `Array` of extension `String`s.
76
- #
77
- # "foo.js.coffee"
78
- # # => [".js", ".coffee"]
79
- #
80
- def extensions
81
- @extensions ||= @pathname.basename.to_s.scan(/\.[^.]+/)
82
- end
83
-
84
- # Returns the format extension.
85
- #
86
- # "foo.js.coffee"
87
- # # => ".js"
88
- #
89
- def format_extension
90
- extensions.detect { |ext|
91
- @environment.mime_types(ext) && !@environment.engines(ext)
92
- }
93
- end
94
-
95
- # Returns an `Array` of engine extensions.
96
- #
97
- # "foo.js.coffee.erb"
98
- # # => [".coffee", ".erb"]
99
- #
100
- def engine_extensions
101
- exts = extensions
102
-
103
- if offset = extensions.index(format_extension)
104
- exts = extensions[offset+1..-1]
105
- end
106
-
107
- exts.select { |ext| @environment.engines(ext) }
108
- end
109
-
110
- # Returns engine classes.
111
- def engines
112
- engine_extensions.map { |ext| @environment.engines(ext) }
113
- end
114
-
115
- # Returns all processors to run on the path.
116
- def processors
117
- environment.preprocessors(content_type) +
118
- engines.reverse +
119
- environment.postprocessors(content_type)
120
- end
121
-
122
- # Returns the content type for the pathname. Falls back to `application/octet-stream`.
123
- def content_type
124
- @content_type ||= begin
125
- if format_extension.nil?
126
- engine_content_type || 'application/octet-stream'
127
- else
128
- @environment.mime_types(format_extension) ||
129
- engine_content_type ||
130
- 'application/octet-stream'
131
- end
132
- end
133
- end
134
-
135
- # Gets digest fingerprint.
136
- #
137
- # "foo-0aa2105d29558f3eb790d411d7d8fb66.js"
138
- # # => "0aa2105d29558f3eb790d411d7d8fb66"
139
- #
140
- def path_fingerprint
141
- pathname.basename(extensions.join).to_s =~ /-([0-9a-f]{7,40})$/ ? $1 : nil
142
- end
143
-
144
- # Injects digest fingerprint into path.
145
- #
146
- # "foo.js"
147
- # # => "foo-0aa2105d29558f3eb790d411d7d8fb66.js"
148
- #
149
- def path_with_fingerprint(digest)
150
- if path_fingerprint
151
- path.sub($1, digest)
152
- else
153
- basename = "#{pathname.basename(extensions.join)}-#{digest}#{extensions.join}"
154
- pathname.dirname.to_s == '.' ? basename : pathname.dirname.join(basename).to_s
155
- end
156
- end
157
-
158
- private
159
- # Returns implicit engine content type.
160
- #
161
- # `.coffee` files carry an implicit `application/javascript`
162
- # content type.
163
- def engine_content_type
164
- engines.reverse.each do |engine|
165
- if engine.respond_to?(:default_mime_type) && engine.default_mime_type
166
- return engine.default_mime_type
167
- end
168
- end
169
- nil
170
- end
171
-
172
- def engine_format_extension
173
- if content_type = engine_content_type
174
- environment.extension_for_mime_type(content_type)
175
- end
176
- end
177
- end
178
- end
@@ -1,134 +0,0 @@
1
- require 'sprockets/asset_attributes'
2
- require 'sprockets/bundled_asset'
3
- require 'sprockets/caching'
4
- require 'sprockets/digest'
5
- require 'sprockets/processing'
6
- require 'sprockets/server'
7
- require 'sprockets/static_asset'
8
- require 'sprockets/static_compilation'
9
- require 'sprockets/trail'
10
- require 'pathname'
11
-
12
- module Sprockets
13
- # `Base` class for `Environment` and `Index`.
14
- class Base
15
- include Digest
16
- include Caching, Processing, Server, StaticCompilation, Trail
17
-
18
- # Get and set `Logger` instance.
19
- attr_accessor :logger
20
-
21
- # Get `Context` class.
22
- #
23
- # This class maybe mutated and mixed in with custom helpers.
24
- #
25
- # environment.context_class.instance_eval do
26
- # include MyHelpers
27
- # def asset_url; end
28
- # end
29
- #
30
- attr_reader :context_class
31
-
32
- # Get persistent cache store
33
- attr_reader :cache
34
-
35
- # Set persistent cache store
36
- #
37
- # The cache store must implement a pair of getters and
38
- # setters. Either `get(key)`/`set(key, value)`,
39
- # `[key]`/`[key]=value`, `read(key)`/`write(key, value)`.
40
- def cache=(cache)
41
- expire_index!
42
- @cache = cache
43
- end
44
-
45
- # Return an `Index`. Must be implemented by the subclass.
46
- def index
47
- raise NotImplementedError
48
- end
49
-
50
- # Works like `Dir.entries`.
51
- #
52
- # Subclasses may cache this method.
53
- def entries(pathname)
54
- trail.entries(pathname)
55
- end
56
-
57
- # Works like `File.stat`.
58
- #
59
- # Subclasses may cache this method.
60
- def stat(path)
61
- trail.stat(path)
62
- end
63
-
64
- # Read and compute digest of filename.
65
- #
66
- # Subclasses may cache this method.
67
- def file_digest(path, data = nil)
68
- if stat = self.stat(path)
69
- # `data` maybe provided
70
- if data
71
- digest.update(data)
72
-
73
- # If its a file, digest the contents
74
- elsif stat.file?
75
- digest.file(path)
76
-
77
- # If its a directive, digest the list of filenames
78
- elsif stat.directory?
79
- contents = self.entries(path).join(',')
80
- digest.update(contents)
81
- end
82
- end
83
- end
84
-
85
- # Internal. Return a `AssetAttributes` for `path`.
86
- def attributes_for(path)
87
- AssetAttributes.new(self, path)
88
- end
89
-
90
- # Internal. Return content type of `path`.
91
- def content_type_of(path)
92
- attributes_for(path).content_type
93
- end
94
-
95
- # Find asset by logical path or expanded path.
96
- def find_asset(path, options = {})
97
- pathname = Pathname.new(path)
98
-
99
- if pathname.absolute?
100
- build_asset(attributes_for(pathname).logical_path, pathname, options)
101
- else
102
- find_asset_in_path(pathname, options)
103
- end
104
- end
105
-
106
- # Preferred `find_asset` shorthand.
107
- #
108
- # environment['application.js']
109
- #
110
- def [](*args)
111
- find_asset(*args)
112
- end
113
-
114
- protected
115
- # Clear index after mutating state. Must be implemented by the subclass.
116
- def expire_index!
117
- raise NotImplementedError
118
- end
119
-
120
- def build_asset(logical_path, pathname, options)
121
- pathname = Pathname.new(pathname)
122
-
123
- return unless stat(pathname)
124
-
125
- # If there are any processors to run on the pathname, use
126
- # `BundledAsset`. Otherwise use `StaticAsset` and treat is as binary.
127
- if attributes_for(pathname).processors.any?
128
- BundledAsset.new(self, logical_path, pathname, options)
129
- else
130
- StaticAsset.new(self, logical_path, pathname)
131
- end
132
- end
133
- end
134
- end
@@ -1,249 +0,0 @@
1
- require 'sprockets/asset'
2
- require 'sprockets/errors'
3
- require 'fileutils'
4
- require 'set'
5
- require 'zlib'
6
-
7
- module Sprockets
8
- # `BundledAsset`s are used for files that need to be processed and
9
- # concatenated with other assets. Use for `.js` and `.css` files.
10
- class BundledAsset < Asset
11
- # Define extra attributes to be serialized.
12
- def self.serialized_attributes
13
- super + %w( content_type mtime )
14
- end
15
-
16
- def initialize(environment, logical_path, pathname, options)
17
- super(environment, logical_path, pathname)
18
- @options = options || {}
19
- end
20
-
21
- # Initialize `BundledAsset` from serialized `Hash`.
22
- def init_with(environment, coder)
23
- @options = {}
24
-
25
- super
26
-
27
- @body = coder['body']
28
- @assets = coder['asset_paths'].map { |p|
29
- p = expand_root_path(p)
30
- p == pathname.to_s ? self : environment[p, @options]
31
- }
32
-
33
- @dependency_paths = coder['dependency_paths'].map { |h|
34
- h.merge('path' => expand_root_path(h['path']))
35
- }
36
- @dependency_paths.each do |dep|
37
- dep['mtime'] = Time.parse(dep['mtime']) if dep['mtime'].is_a?(String)
38
- end
39
- end
40
-
41
- # Serialize custom attributes in `BundledAsset`.
42
- def encode_with(coder)
43
- super
44
-
45
- coder['body'] = body
46
- coder['asset_paths'] = to_a.map { |a| relativize_root_path(a.pathname) }
47
- coder['dependency_paths'] = dependency_paths.map { |h|
48
- h.merge('path' => relativize_root_path(h['path']))
49
- }
50
- end
51
-
52
- # Get asset's own processed contents. Excludes any of its required
53
- # dependencies but does run any processors or engines on the
54
- # original file.
55
- def body
56
- @body ||= build_dependency_context_and_body[1]
57
- end
58
-
59
- # Get latest mtime of all its dependencies.
60
- def mtime
61
- @mtime ||= dependency_paths.map { |h| h['mtime'] }.max
62
- end
63
-
64
- # Get size of concatenated source.
65
- def length
66
- @length ||= build_source['length']
67
- end
68
-
69
- # Compute digest of concatenated source.
70
- def digest
71
- @digest ||= build_source['digest']
72
- end
73
-
74
- # Return an `Array` of `Asset` files that are declared dependencies.
75
- def dependencies
76
- to_a - [self]
77
- end
78
-
79
- # Expand asset into an `Array` of parts.
80
- def to_a
81
- @assets ||= build_dependencies_paths_and_assets[1]
82
- end
83
-
84
- # Checks if Asset is stale by comparing the actual mtime and
85
- # digest to the inmemory model.
86
- def fresh?
87
- # Check freshness of all declared dependencies
88
- dependency_paths.all? { |h| dependency_fresh?(h) }
89
- end
90
-
91
- # Return `String` of concatenated source.
92
- def to_s
93
- @source ||= build_source['source']
94
- end
95
-
96
- # Save asset to disk.
97
- def write_to(filename, options = {})
98
- # Gzip contents if filename has '.gz'
99
- options[:compress] ||= File.extname(filename) == '.gz'
100
-
101
- File.open("#{filename}+", 'wb') do |f|
102
- if options[:compress]
103
- # Run contents through `Zlib`
104
- gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
105
- gz.write to_s
106
- gz.close
107
- else
108
- # Write out as is
109
- f.write to_s
110
- f.close
111
- end
112
- end
113
-
114
- # Atomic write
115
- FileUtils.mv("#{filename}+", filename)
116
-
117
- # Set mtime correctly
118
- File.utime(mtime, mtime, filename)
119
-
120
- nil
121
- ensure
122
- # Ensure tmp file gets cleaned up
123
- FileUtils.rm("#{filename}+") if File.exist?("#{filename}+")
124
- end
125
-
126
- protected
127
- # Return new blank `Context` to evaluate processors in.
128
- def blank_context
129
- environment.context_class.new(environment, logical_path.to_s, pathname)
130
- end
131
-
132
- # Get `Context` after processors have been ran on it. This
133
- # trackes any dependencies that processors have added to it.
134
- def dependency_context
135
- @dependency_context ||= build_dependency_context_and_body[0]
136
- end
137
-
138
- # All paths that this asset depends on. This list may include
139
- # non-assets like directories.
140
- def dependency_paths
141
- @dependency_paths ||= build_dependencies_paths_and_assets[0]
142
- end
143
-
144
- private
145
- # Check if self has already been required and raise a fast
146
- # error. Otherwise you end up with a StackOverflow error.
147
- def check_circular_dependency!
148
- requires = @options[:_requires] ||= []
149
- if requires.include?(pathname.to_s)
150
- raise CircularDependencyError, "#{pathname} has already been required"
151
- end
152
- requires << pathname.to_s
153
- end
154
-
155
- def build_dependency_context_and_body
156
- context = blank_context
157
-
158
- # Read original data once and pass it along to `Context`
159
- data = Sprockets::Utils.read_unicode(pathname)
160
-
161
- # Prime digest cache with data, since we happen to have it
162
- environment.file_digest(pathname, data)
163
-
164
- # Runs all processors on `Context`
165
- body = context.evaluate(pathname, :data => data)
166
-
167
- @dependency_context, @body = context, body
168
-
169
- return context, body
170
- end
171
-
172
- def build_dependencies_paths_and_assets
173
- check_circular_dependency!
174
-
175
- paths, assets = {}, []
176
-
177
- # Define an `add_dependency` helper
178
- add_dependency = lambda do |asset|
179
- unless assets.any? { |a| a.pathname == asset.pathname }
180
- assets << asset
181
- end
182
- end
183
-
184
- # Iterate over all the declared require paths from the `Context`
185
- dependency_context._required_paths.each do |required_path|
186
- # Catch `require_self`
187
- if required_path == pathname.to_s
188
- add_dependency.call(self)
189
- else
190
- # Recursively lookup required asset
191
- environment[required_path, @options].to_a.each do |asset|
192
- add_dependency.call(asset)
193
- end
194
- end
195
- end
196
-
197
- # Ensure self is added to the dependency list
198
- add_dependency.call(self)
199
-
200
- dependency_context._dependency_paths.each do |path|
201
- paths[path] ||= {
202
- 'path' => path,
203
- 'mtime' => environment.stat(path).mtime,
204
- 'hexdigest' => environment.file_digest(path).hexdigest
205
- }
206
- end
207
-
208
- dependency_context._dependency_assets.each do |path|
209
- # Skip if depending on self
210
- next if path == pathname.to_s
211
-
212
- # Recursively lookup required asset
213
- environment[path, @options].to_a.each do |asset|
214
- asset.dependency_paths.each do |dep|
215
- paths[dep['path']] ||= dep
216
- end
217
- end
218
- end
219
-
220
- @dependency_paths, @assets = paths.values, assets
221
-
222
- return @dependency_paths, @assets
223
- end
224
-
225
- def build_source
226
- hash = environment.cache_hash("#{pathname}:source", id) do
227
- data = ""
228
-
229
- # Explode Asset into parts and gather the dependency bodies
230
- to_a.each { |dependency| data << dependency.body }
231
-
232
- # Run bundle processors on concatenated source
233
- data = blank_context.evaluate(pathname, :data => data,
234
- :processors => environment.bundle_processors(content_type))
235
-
236
- { 'length' => Rack::Utils.bytesize(data),
237
- 'digest' => environment.digest.update(data).hexdigest,
238
- 'source' => data }
239
- end
240
- hash['length'] = Integer(hash['length']) if hash['length'].is_a?(String)
241
-
242
- @length = hash['length']
243
- @digest = hash['digest']
244
- @source = hash['source']
245
-
246
- hash
247
- end
248
- end
249
- end
@@ -1,41 +0,0 @@
1
- require 'digest/md5'
2
- require 'fileutils'
3
- require 'pathname'
4
-
5
- module Sprockets
6
- module Cache
7
- # A simple file system cache store.
8
- #
9
- # environment.cache = Sprockets::Cache::FileStore.new("tmp/sprockets")
10
- #
11
- class FileStore
12
- def initialize(root)
13
- @root = Pathname.new(root)
14
-
15
- # Ensure directory exists
16
- FileUtils.mkdir_p @root
17
- end
18
-
19
- # Lookup value in cache
20
- def [](key)
21
- pathname = path_for(key)
22
- pathname.exist? ? pathname.open('rb') { |f| Marshal.load(f) } : nil
23
- end
24
-
25
- # Save value to cache
26
- def []=(key, value)
27
- path_for(key).open('w') { |f| Marshal.dump(value, f)}
28
- value
29
- end
30
-
31
- private
32
- # Returns path for cache key.
33
- #
34
- # The key may include some funky characters so hash it into
35
- # safe hex.
36
- def path_for(key)
37
- @root.join(::Digest::MD5.hexdigest(key))
38
- end
39
- end
40
- end
41
- end