middleman-sprockets 4.0.0.beta.1 → 4.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -3
  3. data/Gemfile +15 -16
  4. data/README.md +0 -58
  5. data/Rakefile +1 -16
  6. data/features/asset_hash.feature +5 -6
  7. data/features/bower.feature +6 -6
  8. data/features/sprockets.feature +13 -65
  9. data/features/sprockets_gems.feature +7 -26
  10. data/features/step_definitions/server_steps.rb +0 -4
  11. data/fixtures/asset-paths-app/config.rb +1 -4
  12. data/fixtures/bower-app/config.rb +0 -2
  13. data/fixtures/bower-app/source/javascripts/application.js +1 -1
  14. data/fixtures/bower-app/source/javascripts/import.js +1 -0
  15. data/fixtures/bower-individual-outputdir-app/config.rb +0 -4
  16. data/fixtures/bower-individual-outputdir-app/source/javascripts/application.js +3 -0
  17. data/fixtures/bower-multiple-assets-app/config.rb +1 -7
  18. data/fixtures/{sprockets-app-debug-assets/source/stylesheets/dependency1.css → bower-multiple-assets-app/source/index.html} +0 -0
  19. data/fixtures/bower-multiple-assets-app/source/javascripts/core.js +2 -0
  20. data/fixtures/jquery-mobile-app/source/javascripts/app.js +1 -0
  21. data/fixtures/sprockets-app/config.rb +0 -5
  22. data/fixtures/sprockets-app/source/library/css/bootstrap_include.css.scss +1 -1
  23. data/fixtures/sprockets-app/source/library/css/plain.css +2 -0
  24. data/fixtures/sprockets-app/source/library/css/sprockets_base2.css.scss +1 -1
  25. data/fixtures/sprockets-app/source/library/js/jquery_include.js +1 -1
  26. data/fixtures/sprockets-app/source/library/js/plain.js +3 -0
  27. data/fixtures/sprockets-app2/source/stylesheets/sprockets_base2.css.scss +1 -1
  28. data/fixtures/sprockets-imported-asset-path-conflicts-app/config.rb +1 -1
  29. data/fixtures/sprockets-imported-assets-match-multiple-paths-app/config.rb +1 -1
  30. data/fixtures/sprockets-multiple-extensions-app/config.rb +0 -3
  31. data/fixtures/sprockets-multiple-extensions-app/source/stylesheets/app.css.scss +3 -0
  32. data/fixtures/sprockets-svg-font-app/config.rb +0 -4
  33. data/fixtures/sprockets-svg-font-app/source/stylesheets/app.css.scss +4 -0
  34. data/lib/middleman-sprockets.rb +1 -6
  35. data/lib/middleman-sprockets/extension.rb +197 -113
  36. data/lib/middleman-sprockets/version.rb +1 -1
  37. data/middleman-sprockets.gemspec +2 -4
  38. metadata +29 -74
  39. data/Gemfile-Sprockets3 +0 -36
  40. data/Gemfile-v3 +0 -36
  41. data/features/asset_hash-3.0.feature +0 -105
  42. data/fixtures/sprockets-app-debug-assets/config.rb +0 -1
  43. data/fixtures/sprockets-app-debug-assets/source/index.html.erb +0 -8
  44. data/fixtures/sprockets-app-debug-assets/source/javascripts/dependency1.js +0 -3
  45. data/fixtures/sprockets-app-debug-assets/source/javascripts/dependency2.js +0 -1
  46. data/fixtures/sprockets-app-debug-assets/source/javascripts/main.js +0 -4
  47. data/fixtures/sprockets-app-debug-assets/source/stylesheets/app.css.scss +0 -4
  48. data/fixtures/sprockets-app-debug-assets/source/stylesheets/dependency2.css.scss +0 -0
  49. data/lib/middleman-sprockets/asset.rb +0 -142
  50. data/lib/middleman-sprockets/asset_tag_helpers.rb +0 -54
  51. data/lib/middleman-sprockets/config_only_environment.rb +0 -50
  52. data/lib/middleman-sprockets/environment.rb +0 -293
  53. data/lib/middleman-sprockets/imported_asset.rb +0 -30
  54. data/lib/middleman-sprockets/sass_function_hack.rb +0 -9
  55. data/lib/middleman-sprockets/sass_utils.rb +0 -14
  56. data/spec/asset_spec.rb +0 -118
  57. data/spec/imported_asset_spec.rb +0 -42
@@ -1 +0,0 @@
1
- set :debug_assets, true
@@ -1,8 +0,0 @@
1
- <%= javascript_include_tag "main", :data => { :name => "main" } %>
2
- <%= javascript_include_tag "//domain.com/script.js" %>
3
- <%= javascript_include_tag "http://domain.com/script.js" %>
4
- <%= javascript_include_tag "https://domain.com/script.js" %>
5
- <%= stylesheet_link_tag "app" %>
6
- <%= stylesheet_link_tag "//domain.com/styles.css" %>
7
- <%= stylesheet_link_tag "http://domain.com/styles.css" %>
8
- <%= stylesheet_link_tag "https://domain.com/styles.css" %>
@@ -1,3 +0,0 @@
1
- //= require dependency2
2
-
3
- function dependency1() {}
@@ -1 +0,0 @@
1
- function dependency2() {}
@@ -1,4 +0,0 @@
1
- //= require dependency1
2
- //= require bootstrap
3
-
4
- function main() {}
@@ -1,4 +0,0 @@
1
- //= require_self
2
- //= require "dependency1"
3
- //= require "dependency2.css.scss"
4
- body{margin:0px}
@@ -1,142 +0,0 @@
1
- # encoding: utf-8
2
- module Middleman
3
- module Sprockets
4
-
5
- class Asset
6
-
7
- attr_reader :app, :sprockets, :asset
8
-
9
- def initialize app, lookup_path, sprockets = app.sprockets
10
- @app = app
11
- @sprockets = sprockets
12
- @asset = sprockets[ sprockets.resolve(lookup_path) ]
13
-
14
- raise ::Sprockets::FileNotFound, "Couldn't find asset '#{lookup_path}'" if @asset.nil?
15
- end
16
-
17
- def destination_path
18
- case type
19
- when :image then
20
- Pathname.new(app.config[:images_dir]) + remove_asset_dir(asset.logical_path, image_paths)
21
- when :script then
22
- Pathname.new(app.config[:js_dir]) + remove_asset_dir(asset.logical_path, script_paths)
23
- when :font then
24
- Pathname.new(app.config[:fonts_dir]) + remove_asset_dir(asset.logical_path, font_paths)
25
- when :stylesheet then
26
- Pathname.new(app.config[:css_dir]) + remove_asset_dir(asset.logical_path, stylesheet_paths)
27
- else
28
- asset.logical_path
29
- end
30
- end
31
-
32
- def source_dir
33
- @source_dir ||= source_path.sub /\/?#{asset.logical_path}$/, ''
34
- end
35
-
36
- def source_path
37
- asset.pathname
38
- end
39
-
40
- def exist?
41
- File.exist?(asset.pathname)
42
- end
43
-
44
- def type
45
- @type ||= if is_image?
46
- :image
47
- elsif is_script?
48
- :script
49
- elsif is_stylesheet?
50
- :stylesheet
51
- elsif is_font?
52
- :font
53
- else
54
- :unknown
55
- end
56
- end
57
-
58
- private
59
-
60
- def has_extname? *exts
61
- !(exts & asset.pathname.to_s.scan(/(\.[^.]+)/).flatten).empty?
62
- end
63
-
64
- def remove_asset_dir pathname, asset_dir_paths
65
- pathname.sub(/^(#{asset_dir_paths.map { |p| Regexp.new(p) }.join('|')})\/?/, '')
66
- end
67
-
68
- def is_image?
69
- is_image_by_path? || (is_image_by_extension? && !is_font_by_path?)
70
- end
71
-
72
- def is_image_by_path?
73
- image_paths.include?(source_path.dirname.basename.to_s) ||
74
- image_paths.include?(File.basename(source_dir.to_s))
75
- end
76
- alias_method :is_in_images_directory?, :is_image_by_path?
77
-
78
- def is_image_by_extension?
79
- has_extname?(*%w(.gif .png .jpg .jpeg .webp .svg .svgz))
80
- end
81
-
82
- def image_paths
83
- %w( images img )
84
- end
85
-
86
- def is_stylesheet?
87
- is_stylesheet_by_path? || is_stylesheet_by_extension?
88
- end
89
-
90
- def is_stylesheet_by_path?
91
- stylesheet_paths.include?(source_path.dirname.basename.to_s) ||
92
- stylesheet_paths.include?(File.basename(source_dir.to_s))
93
- end
94
- alias_method :is_in_stylesheet_directory?, :is_stylesheet_by_path?
95
-
96
- def is_stylesheet_by_extension?
97
- has_extname?(*%w(.css .sass .scss .styl .less))
98
- end
99
-
100
- def stylesheet_paths
101
- %w( stylesheets css )
102
- end
103
-
104
- def is_font?
105
- is_font_by_path? || is_font_by_extension?
106
- end
107
-
108
- def is_font_by_path?
109
- font_paths.include?(source_path.dirname.basename.to_s) ||
110
- font_paths.include?(File.basename(source_dir.to_s))
111
- end
112
- alias_method :is_in_fonts_directory?, :is_font_by_path?
113
-
114
- def is_font_by_extension?
115
- has_extname?(*%w(.ttf .woff .woff2 .eot .otf .svg .svgz))
116
- end
117
-
118
- def font_paths
119
- %w( fonts )
120
- end
121
-
122
- def is_script?
123
- is_script_by_path? || is_script_by_extension?
124
- end
125
-
126
- def is_script_by_path?
127
- script_paths.include?(source_path.dirname.basename.to_s) ||
128
- script_paths.include?(File.basename(source_dir.to_s))
129
- end
130
- alias_method :is_in_scripts_directory?, :is_script_by_path?
131
-
132
- def is_script_by_extension?
133
- has_extname?(*%w(.js .coffee))
134
- end
135
-
136
- def script_paths
137
- %w( javascripts js )
138
- end
139
-
140
- end
141
- end
142
- end
@@ -1,54 +0,0 @@
1
- module Middleman
2
- module Sprockets
3
- module AssetTagHelpers
4
-
5
- # extend padrinos javascript_include_tag with debug functionality
6
- # splits up script dependencies in individual files when
7
- # configuration variable :debug_assets is set to true
8
- def javascript_include_tag(*sources)
9
- if sprockets.debug_assets
10
- options = sources.extract_options!.symbolize_keys
11
- sources.map do |source|
12
- super(dependencies_paths('.js', source), options)
13
- end.join("").gsub("body=1.js", "body=1")
14
- else
15
- super
16
- end
17
- end
18
-
19
- # extend padrinos stylesheet_link_tag with debug functionality
20
- # splits up stylesheets dependencies in individual files when
21
- # configuration variable :debug_assets is set to true
22
- def stylesheet_link_tag(*sources)
23
- if sprockets.debug_assets
24
- options = sources.extract_options!.symbolize_keys
25
- sources.map do |source|
26
- super(dependencies_paths('.css', source), options)
27
- end.join("").gsub("body=1.css", "body=1")
28
- else
29
- super
30
- end
31
- end
32
-
33
- private
34
-
35
- # Find the paths for all the dependencies of a given source file.
36
- def dependencies_paths(extension, source)
37
- source_file_name = source.to_s
38
-
39
- if source_file_name.start_with?('//', 'http')
40
- # Don't touch external sources
41
- source_file_name
42
- else
43
- source_file_name << extension unless source_file_name.end_with?(extension)
44
-
45
- dependencies_paths = sprockets[source_file_name].to_a.map do |dependency|
46
- # if sprockets sees "?body=1" it only gives back the body
47
- # of the script without the dependencies included
48
- dependency.logical_path + "?body=1"
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,50 +0,0 @@
1
- module Middleman
2
- module Sprockets
3
- # A fake Sprockets environment that just exposes the
4
- # waits to create the environment until asked, but can still
5
- # service most of the interesting configuration methods. This
6
- # allows sprockets to be configured any time in config.rb, rather
7
- # than having to use an after_configuration block.
8
- class ConfigOnlyEnvironment
9
- attr_reader :imported_assets
10
- attr_reader :appended_paths
11
- attr_reader :prepended_paths
12
-
13
- def initialize(options={})
14
- @imported_assets = []
15
- @appended_paths = []
16
- @prepended_paths = []
17
- end
18
-
19
- def method_missing?(method)
20
- raise NoMethodError, "The Sprockets environment is not ready yet, so you can't call #{method} on it. If you need to call this method do it in a 'ready' block."
21
- end
22
-
23
- def apply_to_environment(environment)
24
- @imported_assets.each do |(path, directory)|
25
- environment.import_asset path, &directory
26
- end
27
-
28
- @appended_paths.each do |path|
29
- environment.append_path path
30
- end
31
-
32
- @prepended_paths.each do |path|
33
- environment.prepend_path path
34
- end
35
- end
36
-
37
- def import_asset(asset_logical_path, &output_directory)
38
- @imported_assets << [asset_logical_path, output_directory]
39
- end
40
-
41
- def append_path(path)
42
- @appended_paths << path
43
- end
44
-
45
- def prepend_path(path)
46
- @prepended_paths << path
47
- end
48
- end
49
- end
50
- end
@@ -1,293 +0,0 @@
1
- require "middleman-sprockets/asset"
2
-
3
- module Middleman
4
- module Sprockets
5
- # Generic Middleman Sprockets env
6
- class Environment < ::Sprockets::Environment
7
- # Whether or not we should debug assets by splitting them all out into individual includes
8
- attr_reader :debug_assets
9
-
10
- # A list of Sprockets logical paths for assets that should be brought into the
11
- # Middleman application and built.
12
- attr_reader :imported_assets
13
-
14
- # The current path, useful when inside helper methods
15
- attr_reader :last_request_path
16
-
17
- # Setup
18
- def initialize(app, options={})
19
- @imported_assets = []
20
- @app = app
21
- @debug_assets = options.fetch(:debug_assets, false)
22
-
23
- super app.source_dir
24
-
25
- # By default, sprockets has no cache! Give it an in-memory one using a Hash
26
- # There is also a Sprockets::Cache::FileStore option, but it is fraught with cache-invalidation
27
- # peril, so we choose not to use it.
28
- @cache = FakeCache.new
29
-
30
- enhance_context_class!
31
-
32
- # Remove compressors, we handle these with middleware
33
- unregister_bundle_processor 'application/javascript', :js_compressor
34
- unregister_bundle_processor 'text/css', :css_compressor
35
-
36
- # configure search paths
37
- append_path app.config[:js_dir]
38
- append_path app.config[:css_dir]
39
- append_path app.config[:images_dir]
40
- append_path app.config[:fonts_dir]
41
-
42
- if app.config.respond_to?(:bower_dir)
43
- warn ":bower_dir is deprecated. Call sprockets.append_path from a 'ready' block instead."
44
- append_path app.config[:bower_dir]
45
- end
46
-
47
- # add custom assets paths to the scope
48
- app.config[:js_assets_paths].each do |p|
49
- warn ":js_assets_paths is deprecated. Call sprockets.append_path from a 'ready' block instead."
50
- append_path p
51
- end if app.config.respond_to?(:js_assets_paths)
52
-
53
- # Stylus support
54
- if defined?(::Stylus)
55
- require 'stylus/sprockets'
56
- ::Stylus.setup(self, app.config[:styl])
57
- end
58
- end
59
-
60
- # Make sure all the defined imported assets still exist
61
- def prune_imported_assets!
62
- @imported_assets = @imported_assets.select do |a|
63
- begin
64
- a = Middleman::Sprockets::Asset.new(@app, a.logical_path, self)
65
- a.exist?
66
- rescue
67
- false
68
- end
69
- end
70
- end
71
-
72
- # Add our own customizations to the Sprockets context class
73
- def enhance_context_class!
74
- app = @app
75
- env = self
76
-
77
- # Make the app context available to Sprockets
78
- context_class.send(:define_method, :app) { app }
79
- context_class.send(:define_method, :env) { env }
80
-
81
- context_class.class_eval do
82
- def asset_path(path, options={})
83
- # Handle people calling with the Middleman/Padrino asset path signature
84
- if path.is_a?(::Symbol) && !options.is_a?(::Hash)
85
- kind = path
86
- path = options
87
- else
88
-
89
- kind = case options[:type]
90
- when :image then :images
91
- when :font then :fonts
92
- when :javascript then :js
93
- when :stylesheet then :css
94
- else options[:type]
95
- end
96
- end
97
-
98
- # If Middleman v4, we don't have a global for current path, so pass it in.
99
- if self.env.last_request_path
100
- app.asset_path(kind, path, {
101
- :current_resource => app.sitemap.find_resource_by_destination_path(
102
- self.env.last_request_path
103
- )
104
- })
105
- else
106
- app.asset_path(kind, path)
107
- end
108
- end
109
-
110
- # These helpers are already defined in later versions of Sprockets, but we define
111
- # them ourself to help older versions and to provide extra options that Sass wants.
112
-
113
- # Expand logical image asset path.
114
- def image_path(path, options={})
115
- asset_path(path, :type => :image)
116
- end
117
-
118
- # Expand logical font asset path.
119
- def font_path(path, options={})
120
- # Knock .fonts off the end, because Middleman < 3.1 doesn't handle fonts
121
- # in asset_path
122
- asset_path(path, :type => :font).sub(/\.fonts$/, '')
123
- end
124
-
125
- # Expand logical javascript asset path.
126
- def javascript_path(path, options={})
127
- asset_path(path, :type => :javascript)
128
- end
129
-
130
- # Expand logical stylesheet asset path.
131
- def stylesheet_path(path, options={})
132
- asset_path(path, :type => :stylesheet)
133
- end
134
-
135
- def method_missing(*args)
136
- name = args.first
137
- if app.respond_to?(name)
138
- app.send(*args)
139
- else
140
- super
141
- end
142
- end
143
-
144
- # Needed so that method_missing makes sense
145
- def respond_to?(method, include_private = false)
146
- super || app.respond_to?(method, include_private)
147
- end
148
- end
149
- end
150
- private :enhance_context_class!
151
-
152
- # Override Sprockets' default digest function to *not*
153
- # change depending on the exact Sprockets version. It still takes
154
- # into account "version" which is a user-suppliable version
155
- # number that can be used to force assets to have a new
156
- # hash.
157
- def digest
158
- @digest ||= Digest::SHA1.new.update(version.to_s)
159
- @digest.dup
160
- end
161
-
162
- # Strip our custom 8-char hex/sha
163
- def path_fingerprint(path)
164
- path[/-([0-9a-f]{8})\.[^.]+$/, 1]
165
- end
166
-
167
- # Invalidate sitemap when users mess with the sprockets load paths
168
- def append_path(path)
169
- @app.sitemap.rebuild_resource_list!(:sprockets_paths)
170
-
171
- super
172
- end
173
-
174
- def prepend_path(path)
175
- @app.sitemap.rebuild_resource_list!(:sprockets_paths)
176
-
177
- super
178
- end
179
-
180
- def clear_paths
181
- @app.sitemap.rebuild_resource_list!(:sprockets_paths)
182
- super
183
- end
184
-
185
- def css_exception_response(exception)
186
- raise exception if @app.build?
187
- super
188
- end
189
-
190
- def javascript_exception_response(exception)
191
- raise exception if @app.build?
192
- super
193
- end
194
-
195
- # Never return 304s, downstream may want to manipulate data.
196
- def etag_match?(asset, env)
197
- false
198
- end
199
-
200
- def call(env)
201
- # Set the app current path based on the full URL so that helpers work
202
- script_name = env['SCRIPT_NAME'].dup
203
- script_name.gsub!(/^#{@app.config[:http_prefix]}/i, '') if @app.config[:http_prefix]
204
- request_path = URI.decode(File.join(script_name, env['PATH_INFO']))
205
- if request_path.respond_to? :force_encoding
206
- request_path.force_encoding('UTF-8')
207
- end
208
- resource = @app.sitemap.find_resource_by_destination_path(request_path)
209
-
210
- if !resource && !debug_assets
211
- response = ::Rack::Response.new
212
- response.status = 404
213
- response.write """<html><body><h1>File Not Found</h1><p>#{request_path}</p>
214
- <p>If this is an an asset from a gem, add <tt>sprockets.import_asset '#{File.basename(request_path)}'</tt>
215
- to your <tt>config.rb</tt>.</body>"""
216
- return response.finish
217
- end
218
-
219
- if @app.respond_to?(:current_path=)
220
- @app.current_path = request_path
221
- else
222
- @last_request_path = request_path
223
- end
224
-
225
- # Fix https://github.com/sstephenson/sprockets/issues/533
226
- if resource && File.basename(resource.path) == 'bower.json'
227
- file = ::Rack::File.new nil
228
- file.path = if resource.source_file.is_a? String
229
- resource.source_file
230
- else
231
- resource.source_file[:full_path]
232
- end
233
- response = file.serving({})
234
- response[1]['Content-Type'] = resource.content_type
235
- return response
236
- end
237
-
238
- if resource
239
- # incase the path has been rewrite, let sprockets know the original so it can find it
240
- logical_path = resource.metadata.fetch(:options, {})
241
- .fetch(:sprockets, {})
242
- .fetch(:logical_path, nil)
243
- env['PATH_INFO'] = logical_path.to_s if logical_path
244
- end
245
-
246
- super
247
- end
248
-
249
- # Tell Middleman to build this asset, referenced as a logical path.
250
- def import_asset(asset_logical_path, &determine_output_dir)
251
- args = []
252
- args << asset_logical_path
253
- args << determine_output_dir if block_given?
254
-
255
- @imported_assets << ImportedAsset.new(*args)
256
-
257
- @app.sitemap.rebuild_resource_list!(:sprockets_import_asset)
258
- end
259
-
260
- # Sprocket 3 API change :(
261
- def files_in_paths(load_paths)
262
- if self.respond_to?(:each_entry)
263
- load_paths.flat_map do |path|
264
- output = []
265
-
266
- self.each_entry(path).each do |p|
267
- output << [p, path]
268
- end
269
-
270
- output
271
- end
272
- else
273
- logical_paths.map do |_, path|
274
- found_path = load_paths.find do |load_path|
275
- path.start_with?(load_path)
276
- end
277
-
278
- if found_path
279
- [Pathname(path), found_path]
280
- else
281
- nil
282
- end
283
- end.reject(&:nil?)
284
- end
285
- end
286
- end
287
-
288
- class FakeCache < Hash
289
- alias_method :_get, :[]
290
- alias_method :_set, :[]=
291
- end
292
- end
293
- end