giga-lite-hub 0.0.1

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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/giga-lite-hub.gemspec +12 -0
  3. data/sprockets-4.2.2/CHANGELOG.md +118 -0
  4. data/sprockets-4.2.2/MIT-LICENSE +21 -0
  5. data/sprockets-4.2.2/README.md +716 -0
  6. data/sprockets-4.2.2/bin/sprockets +93 -0
  7. data/sprockets-4.2.2/lib/rake/sprocketstask.rb +157 -0
  8. data/sprockets-4.2.2/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
  9. data/sprockets-4.2.2/lib/sprockets/asset.rb +212 -0
  10. data/sprockets-4.2.2/lib/sprockets/autoload/babel.rb +8 -0
  11. data/sprockets-4.2.2/lib/sprockets/autoload/closure.rb +8 -0
  12. data/sprockets-4.2.2/lib/sprockets/autoload/coffee_script.rb +8 -0
  13. data/sprockets-4.2.2/lib/sprockets/autoload/eco.rb +8 -0
  14. data/sprockets-4.2.2/lib/sprockets/autoload/ejs.rb +8 -0
  15. data/sprockets-4.2.2/lib/sprockets/autoload/jsminc.rb +8 -0
  16. data/sprockets-4.2.2/lib/sprockets/autoload/sass.rb +8 -0
  17. data/sprockets-4.2.2/lib/sprockets/autoload/sassc.rb +8 -0
  18. data/sprockets-4.2.2/lib/sprockets/autoload/uglifier.rb +8 -0
  19. data/sprockets-4.2.2/lib/sprockets/autoload/yui.rb +8 -0
  20. data/sprockets-4.2.2/lib/sprockets/autoload/zopfli.rb +7 -0
  21. data/sprockets-4.2.2/lib/sprockets/autoload.rb +16 -0
  22. data/sprockets-4.2.2/lib/sprockets/babel_processor.rb +66 -0
  23. data/sprockets-4.2.2/lib/sprockets/base.rb +147 -0
  24. data/sprockets-4.2.2/lib/sprockets/bower.rb +61 -0
  25. data/sprockets-4.2.2/lib/sprockets/bundle.rb +105 -0
  26. data/sprockets-4.2.2/lib/sprockets/cache/file_store.rb +208 -0
  27. data/sprockets-4.2.2/lib/sprockets/cache/memory_store.rb +84 -0
  28. data/sprockets-4.2.2/lib/sprockets/cache/null_store.rb +54 -0
  29. data/sprockets-4.2.2/lib/sprockets/cache.rb +271 -0
  30. data/sprockets-4.2.2/lib/sprockets/cached_environment.rb +64 -0
  31. data/sprockets-4.2.2/lib/sprockets/closure_compressor.rb +48 -0
  32. data/sprockets-4.2.2/lib/sprockets/coffee_script_processor.rb +39 -0
  33. data/sprockets-4.2.2/lib/sprockets/compressing.rb +134 -0
  34. data/sprockets-4.2.2/lib/sprockets/configuration.rb +79 -0
  35. data/sprockets-4.2.2/lib/sprockets/context.rb +305 -0
  36. data/sprockets-4.2.2/lib/sprockets/dependencies.rb +74 -0
  37. data/sprockets-4.2.2/lib/sprockets/digest_utils.rb +197 -0
  38. data/sprockets-4.2.2/lib/sprockets/directive_processor.rb +432 -0
  39. data/sprockets-4.2.2/lib/sprockets/eco_processor.rb +33 -0
  40. data/sprockets-4.2.2/lib/sprockets/ejs_processor.rb +32 -0
  41. data/sprockets-4.2.2/lib/sprockets/encoding_utils.rb +261 -0
  42. data/sprockets-4.2.2/lib/sprockets/environment.rb +46 -0
  43. data/sprockets-4.2.2/lib/sprockets/erb_processor.rb +43 -0
  44. data/sprockets-4.2.2/lib/sprockets/errors.rb +12 -0
  45. data/sprockets-4.2.2/lib/sprockets/exporters/base.rb +71 -0
  46. data/sprockets-4.2.2/lib/sprockets/exporters/file_exporter.rb +24 -0
  47. data/sprockets-4.2.2/lib/sprockets/exporters/zlib_exporter.rb +33 -0
  48. data/sprockets-4.2.2/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
  49. data/sprockets-4.2.2/lib/sprockets/exporting.rb +73 -0
  50. data/sprockets-4.2.2/lib/sprockets/file_reader.rb +16 -0
  51. data/sprockets-4.2.2/lib/sprockets/http_utils.rb +135 -0
  52. data/sprockets-4.2.2/lib/sprockets/jsminc_compressor.rb +32 -0
  53. data/sprockets-4.2.2/lib/sprockets/jst_processor.rb +50 -0
  54. data/sprockets-4.2.2/lib/sprockets/loader.rb +347 -0
  55. data/sprockets-4.2.2/lib/sprockets/manifest.rb +339 -0
  56. data/sprockets-4.2.2/lib/sprockets/manifest_utils.rb +48 -0
  57. data/sprockets-4.2.2/lib/sprockets/mime.rb +96 -0
  58. data/sprockets-4.2.2/lib/sprockets/npm.rb +52 -0
  59. data/sprockets-4.2.2/lib/sprockets/path_dependency_utils.rb +77 -0
  60. data/sprockets-4.2.2/lib/sprockets/path_digest_utils.rb +48 -0
  61. data/sprockets-4.2.2/lib/sprockets/path_utils.rb +367 -0
  62. data/sprockets-4.2.2/lib/sprockets/paths.rb +82 -0
  63. data/sprockets-4.2.2/lib/sprockets/preprocessors/default_source_map.rb +49 -0
  64. data/sprockets-4.2.2/lib/sprockets/processing.rb +228 -0
  65. data/sprockets-4.2.2/lib/sprockets/processor_utils.rb +170 -0
  66. data/sprockets-4.2.2/lib/sprockets/resolve.rb +295 -0
  67. data/sprockets-4.2.2/lib/sprockets/sass_cache_store.rb +30 -0
  68. data/sprockets-4.2.2/lib/sprockets/sass_compressor.rb +63 -0
  69. data/sprockets-4.2.2/lib/sprockets/sass_functions.rb +3 -0
  70. data/sprockets-4.2.2/lib/sprockets/sass_importer.rb +3 -0
  71. data/sprockets-4.2.2/lib/sprockets/sass_processor.rb +313 -0
  72. data/sprockets-4.2.2/lib/sprockets/sassc_compressor.rb +56 -0
  73. data/sprockets-4.2.2/lib/sprockets/sassc_processor.rb +297 -0
  74. data/sprockets-4.2.2/lib/sprockets/server.rb +315 -0
  75. data/sprockets-4.2.2/lib/sprockets/source_map_processor.rb +66 -0
  76. data/sprockets-4.2.2/lib/sprockets/source_map_utils.rb +483 -0
  77. data/sprockets-4.2.2/lib/sprockets/transformers.rb +173 -0
  78. data/sprockets-4.2.2/lib/sprockets/uglifier_compressor.rb +66 -0
  79. data/sprockets-4.2.2/lib/sprockets/unloaded_asset.rb +139 -0
  80. data/sprockets-4.2.2/lib/sprockets/uri_tar.rb +99 -0
  81. data/sprockets-4.2.2/lib/sprockets/uri_utils.rb +194 -0
  82. data/sprockets-4.2.2/lib/sprockets/utils/gzip.rb +99 -0
  83. data/sprockets-4.2.2/lib/sprockets/utils.rb +210 -0
  84. data/sprockets-4.2.2/lib/sprockets/version.rb +4 -0
  85. data/sprockets-4.2.2/lib/sprockets/yui_compressor.rb +56 -0
  86. data/sprockets-4.2.2/lib/sprockets.rb +232 -0
  87. metadata +126 -0
@@ -0,0 +1,228 @@
1
+ # frozen_string_literal: true
2
+ require 'sprockets/file_reader'
3
+ require 'sprockets/mime'
4
+ require 'sprockets/processor_utils'
5
+ require 'sprockets/uri_utils'
6
+ require 'sprockets/utils'
7
+
8
+ module Sprockets
9
+ # `Processing` is an internal mixin whose public methods are exposed on
10
+ # the `Environment` and `CachedEnvironment` classes.
11
+ module Processing
12
+ include ProcessorUtils, URIUtils, Utils
13
+
14
+ def pipelines
15
+ config[:pipelines]
16
+ end
17
+
18
+ # Registers a pipeline that will be called by `call_processor` method.
19
+ def register_pipeline(name, proc = nil, &block)
20
+ proc ||= block
21
+
22
+ self.config = hash_reassoc(config, :pipeline_exts) do |pipeline_exts|
23
+ pipeline_exts.merge(".#{name}".freeze => name.to_sym)
24
+ end
25
+
26
+ self.config = hash_reassoc(config, :pipelines) do |pipelines|
27
+ pipelines.merge(name.to_sym => proc)
28
+ end
29
+ end
30
+
31
+ # Preprocessors are ran before Postprocessors and Engine
32
+ # processors.
33
+ def preprocessors
34
+ config[:preprocessors]
35
+ end
36
+ alias_method :processors, :preprocessors
37
+
38
+ # Postprocessors are ran after Preprocessors and Engine processors.
39
+ def postprocessors
40
+ config[:postprocessors]
41
+ end
42
+
43
+ # Registers a new Preprocessor `klass` for `mime_type`.
44
+ #
45
+ # register_preprocessor 'text/css', Sprockets::DirectiveProcessor
46
+ #
47
+ # A block can be passed for to create a shorthand processor.
48
+ #
49
+ # register_preprocessor 'text/css' do |input|
50
+ # input[:data].gsub(...)
51
+ # end
52
+ #
53
+ def register_preprocessor(*args, &block)
54
+ register_config_processor(:preprocessors, *args, &block)
55
+ compute_transformers!(self.config[:registered_transformers])
56
+ end
57
+ alias_method :register_processor, :register_preprocessor
58
+
59
+ # Registers a new Postprocessor `klass` for `mime_type`.
60
+ #
61
+ # register_postprocessor 'application/javascript', Sprockets::DirectiveProcessor
62
+ #
63
+ # A block can be passed for to create a shorthand processor.
64
+ #
65
+ # register_postprocessor 'application/javascript' do |input|
66
+ # input[:data].gsub(...)
67
+ # end
68
+ #
69
+ def register_postprocessor(*args, &block)
70
+ register_config_processor(:postprocessors, *args, &block)
71
+ compute_transformers!(self.config[:registered_transformers])
72
+ end
73
+
74
+ # Remove Preprocessor `klass` for `mime_type`.
75
+ #
76
+ # unregister_preprocessor 'text/css', Sprockets::DirectiveProcessor
77
+ #
78
+ def unregister_preprocessor(*args)
79
+ unregister_config_processor(:preprocessors, *args)
80
+ compute_transformers!(self.config[:registered_transformers])
81
+ end
82
+ alias_method :unregister_processor, :unregister_preprocessor
83
+
84
+ # Remove Postprocessor `klass` for `mime_type`.
85
+ #
86
+ # unregister_postprocessor 'text/css', Sprockets::DirectiveProcessor
87
+ #
88
+ def unregister_postprocessor(*args)
89
+ unregister_config_processor(:postprocessors, *args)
90
+ compute_transformers!(self.config[:registered_transformers])
91
+ end
92
+
93
+ # Bundle Processors are ran on concatenated assets rather than
94
+ # individual files.
95
+ def bundle_processors
96
+ config[:bundle_processors]
97
+ end
98
+
99
+ # Registers a new Bundle Processor `klass` for `mime_type`.
100
+ #
101
+ # register_bundle_processor 'application/javascript', Sprockets::DirectiveProcessor
102
+ #
103
+ # A block can be passed for to create a shorthand processor.
104
+ #
105
+ # register_bundle_processor 'application/javascript' do |input|
106
+ # input[:data].gsub(...)
107
+ # end
108
+ #
109
+ def register_bundle_processor(*args, &block)
110
+ register_config_processor(:bundle_processors, *args, &block)
111
+ end
112
+
113
+ # Remove Bundle Processor `klass` for `mime_type`.
114
+ #
115
+ # unregister_bundle_processor 'application/javascript', Sprockets::DirectiveProcessor
116
+ #
117
+ def unregister_bundle_processor(*args)
118
+ unregister_config_processor(:bundle_processors, *args)
119
+ end
120
+
121
+ # Public: Register bundle metadata reducer function.
122
+ #
123
+ # Examples
124
+ #
125
+ # Sprockets.register_bundle_metadata_reducer 'application/javascript', :jshint_errors, [], :+
126
+ #
127
+ # Sprockets.register_bundle_metadata_reducer 'text/css', :selector_count, 0 { |total, count|
128
+ # total + count
129
+ # }
130
+ #
131
+ # mime_type - String MIME Type. Use '*/*' applies to all types.
132
+ # key - Symbol metadata key
133
+ # initial - Initial memo to pass to the reduce function (default: nil)
134
+ # block - Proc accepting the memo accumulator and current value
135
+ #
136
+ # Returns nothing.
137
+ def register_bundle_metadata_reducer(mime_type, key, *args, &block)
138
+ case args.size
139
+ when 0
140
+ reducer = block
141
+ when 1
142
+ if block_given?
143
+ initial = args[0]
144
+ reducer = block
145
+ else
146
+ initial = nil
147
+ reducer = args[0].to_proc
148
+ end
149
+ when 2
150
+ initial = args[0]
151
+ reducer = args[1].to_proc
152
+ else
153
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 0..2)"
154
+ end
155
+
156
+ self.config = hash_reassoc(config, :bundle_reducers, mime_type) do |reducers|
157
+ reducers.merge(key => [initial, reducer])
158
+ end
159
+ end
160
+
161
+ protected
162
+ def resolve_processors_cache_key_uri(uri)
163
+ params = parse_uri_query_params(uri[11..-1])
164
+ processors = processors_for(params[:type], params[:file_type], params[:pipeline])
165
+ processors_cache_keys(processors)
166
+ end
167
+
168
+ def build_processors_uri(type, file_type, pipeline)
169
+ query = encode_uri_query_params(
170
+ type: type,
171
+ file_type: file_type,
172
+ pipeline: pipeline
173
+ )
174
+ "processors:#{query}"
175
+ end
176
+
177
+ def processors_for(type, file_type, pipeline)
178
+ pipeline ||= :default
179
+ if fn = config[:pipelines][pipeline.to_sym]
180
+ fn.call(self, type, file_type)
181
+ else
182
+ raise Error, "no pipeline: #{pipeline}"
183
+ end
184
+ end
185
+
186
+ def default_processors_for(type, file_type)
187
+ bundled_processors = config[:bundle_processors][type]
188
+ if bundled_processors.any?
189
+ bundled_processors
190
+ else
191
+ self_processors_for(type, file_type)
192
+ end
193
+ end
194
+
195
+ def self_processors_for(type, file_type)
196
+ processors = []
197
+
198
+ processors.concat config[:postprocessors][type]
199
+ if type != file_type && processor = config[:transformers][file_type][type]
200
+ processors << processor
201
+ end
202
+ processors.concat config[:preprocessors][file_type]
203
+
204
+ if processors.any? || mime_type_charset_detecter(type)
205
+ processors << FileReader
206
+ end
207
+
208
+ processors
209
+ end
210
+
211
+ private
212
+ def register_config_processor(type, mime_type, processor = nil, &block)
213
+ processor ||= block
214
+
215
+ self.config = hash_reassoc(config, type, mime_type) do |processors|
216
+ processors.unshift(processor)
217
+ processors
218
+ end
219
+ end
220
+
221
+ def unregister_config_processor(type, mime_type, processor)
222
+ self.config = hash_reassoc(config, type, mime_type) do |processors|
223
+ processors.delete_if { |p| p == processor || p.class == processor }
224
+ processors
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+ require 'set'
3
+
4
+ module Sprockets
5
+ # Functional utilities for dealing with Processor functions.
6
+ #
7
+ # A Processor is a general function that may modify or transform an asset as
8
+ # part of the pipeline. CoffeeScript to JavaScript conversion, Minification
9
+ # or Concatenation are all implemented as separate Processor steps.
10
+ #
11
+ # Processors maybe any object that responds to call. So procs or a class that
12
+ # defines a self.call method.
13
+ #
14
+ # For ergonomics, processors may return a number of shorthand values.
15
+ # Unfortunately, this means that processors can not compose via ordinary
16
+ # function composition. The composition helpers here can help.
17
+ module ProcessorUtils
18
+ extend self
19
+
20
+ class CompositeProcessor < Struct.new(:processor_strategy, :param, :processors) # :nodoc:
21
+ SINGULAR = lambda { |param, input| ProcessorUtils.call_processor param, input }
22
+ PLURAL = lambda { |param, input| ProcessorUtils.call_processors param, input }
23
+
24
+ def self.create(processors)
25
+ if processors.length == 1
26
+ new SINGULAR, processors.first, processors
27
+ else
28
+ new PLURAL, processors, processors
29
+ end
30
+ end
31
+
32
+ def call(input)
33
+ processor_strategy.call param, input
34
+ end
35
+
36
+ def cache_key
37
+ ProcessorUtils.processors_cache_keys(processors)
38
+ end
39
+ end
40
+
41
+ # Public: Compose processors in right to left order.
42
+ #
43
+ # processors - Array of processors callables
44
+ #
45
+ # Returns a composed Proc.
46
+ def compose_processors(*processors)
47
+ CompositeProcessor.create processors
48
+ end
49
+
50
+ # Public: Invoke list of processors in right to left order.
51
+ #
52
+ # The right to left order processing mirrors standard function composition.
53
+ # Think about:
54
+ #
55
+ # bundle.call(uglify.call(coffee.call(input)))
56
+ #
57
+ # processors - Array of processor callables
58
+ # input - Hash of input data to pass to each processor
59
+ #
60
+ # Returns a Hash with :data and other processor metadata key/values.
61
+ def call_processors(processors, input)
62
+ data = input[:data] || ""
63
+ metadata = (input[:metadata] || {}).dup
64
+
65
+ processors.reverse_each do |processor|
66
+ result = call_processor(processor, input.merge(data: data, metadata: metadata))
67
+ data = result.delete(:data)
68
+ metadata.merge!(result)
69
+ end
70
+
71
+ metadata.merge(data: data)
72
+ end
73
+
74
+ # Public: Invoke processor.
75
+ #
76
+ # processor - Processor callables
77
+ # input - Hash of input data to pass to processor
78
+ #
79
+ # Returns a Hash with :data and other processor metadata key/values.
80
+ def call_processor(processor, input)
81
+ metadata = (input[:metadata] || {}).dup
82
+ metadata[:data] = input[:data]
83
+
84
+ case result = processor.call({data: "", metadata: {}}.merge(input))
85
+ when NilClass
86
+ metadata
87
+ when Hash
88
+ metadata.merge(result)
89
+ when String
90
+ metadata.merge(data: result)
91
+ else
92
+ raise TypeError, "invalid processor return type: #{result.class}"
93
+ end
94
+ end
95
+
96
+ # Internal: Get processor defined cached key.
97
+ #
98
+ # processor - Processor function
99
+ #
100
+ # Returns JSON serializable key or nil.
101
+ def processor_cache_key(processor)
102
+ processor.cache_key if processor.respond_to?(:cache_key)
103
+ end
104
+
105
+ # Internal: Get combined cache keys for set of processors.
106
+ #
107
+ # processors - Array of processor functions
108
+ #
109
+ # Returns Array of JSON serializable keys.
110
+ def processors_cache_keys(processors)
111
+ processors.map { |processor| processor_cache_key(processor) }
112
+ end
113
+
114
+ # Internal: Set of all "simple" value types allowed to be returned in
115
+ # processor metadata.
116
+ VALID_METADATA_VALUE_TYPES = Set.new([
117
+ String,
118
+ Symbol,
119
+ TrueClass,
120
+ FalseClass,
121
+ NilClass,
122
+ Integer
123
+ ]).freeze
124
+
125
+ # Internal: Set of all nested compound metadata types that can nest values.
126
+ VALID_METADATA_COMPOUND_TYPES = Set.new([
127
+ Array,
128
+ Hash,
129
+ Set
130
+ ]).freeze
131
+
132
+ # Internal: Hash of all "simple" value types allowed to be returned in
133
+ # processor metadata.
134
+ VALID_METADATA_VALUE_TYPES_HASH = VALID_METADATA_VALUE_TYPES.each_with_object({}) do |type, hash|
135
+ hash[type] = true
136
+ end.freeze
137
+
138
+ # Internal: Hash of all nested compound metadata types that can nest values.
139
+ VALID_METADATA_COMPOUND_TYPES_HASH = VALID_METADATA_COMPOUND_TYPES.each_with_object({}) do |type, hash|
140
+ hash[type] = true
141
+ end.freeze
142
+
143
+ # Internal: Set of all allowed metadata types.
144
+ VALID_METADATA_TYPES = (VALID_METADATA_VALUE_TYPES + VALID_METADATA_COMPOUND_TYPES).freeze
145
+
146
+ # Internal: Validate returned result of calling a processor pipeline and
147
+ # raise a friendly user error message.
148
+ #
149
+ # result - Metadata Hash returned from call_processors
150
+ #
151
+ # Returns result or raises a TypeError.
152
+ def validate_processor_result!(result)
153
+ if !result.instance_of?(Hash)
154
+ raise TypeError, "processor metadata result was expected to be a Hash, but was #{result.class}"
155
+ end
156
+
157
+ if !result[:data].instance_of?(String)
158
+ raise TypeError, "processor :data was expected to be a String, but as #{result[:data].class}"
159
+ end
160
+
161
+ result.each do |key, value|
162
+ if !key.instance_of?(Symbol)
163
+ raise TypeError, "processor metadata[#{key.inspect}] expected to be a Symbol"
164
+ end
165
+ end
166
+
167
+ result
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,295 @@
1
+ # frozen_string_literal: true
2
+ require 'set'
3
+ require 'sprockets/http_utils'
4
+ require 'sprockets/path_dependency_utils'
5
+ require 'sprockets/uri_utils'
6
+
7
+ module Sprockets
8
+ module Resolve
9
+ include HTTPUtils, PathDependencyUtils, URIUtils
10
+
11
+ # Public: Find Asset URI for given a logical path by searching the
12
+ # environment's load paths.
13
+ #
14
+ # resolve("application.js")
15
+ # # => "file:///path/to/app/javascripts/application.js?type=application/javascript"
16
+ #
17
+ # An accept content type can be given if the logical path doesn't have a
18
+ # format extension.
19
+ #
20
+ # resolve("application", accept: "application/javascript")
21
+ # # => "file:///path/to/app/javascripts/application.coffee?type=application/javascript"
22
+ #
23
+ # The String Asset URI is returned or nil if no results are found.
24
+ def resolve(path, load_paths: config[:paths], accept: nil, pipeline: nil, base_path: nil)
25
+ paths = load_paths
26
+
27
+ if valid_asset_uri?(path)
28
+ uri, deps = resolve_asset_uri(path)
29
+ elsif absolute_path?(path)
30
+ filename, type, deps = resolve_absolute_path(paths, path, accept)
31
+ elsif relative_path?(path)
32
+ filename, type, path_pipeline, deps, index_alias = resolve_relative_path(paths, path, base_path, accept)
33
+ else
34
+ filename, type, path_pipeline, deps, index_alias = resolve_logical_path(paths, path, accept)
35
+ end
36
+
37
+ if filename
38
+ uri = build_asset_uri(filename, type: type, pipeline: pipeline || path_pipeline, index_alias: index_alias)
39
+ end
40
+
41
+ return uri, deps
42
+ end
43
+
44
+ # Public: Same as resolve() but raises a FileNotFound exception instead of
45
+ # nil if no assets are found.
46
+ def resolve!(path, **kargs)
47
+ uri, deps = resolve(path, **kargs)
48
+
49
+ unless uri
50
+ message = +"couldn't find file '#{path}'"
51
+
52
+ if relative_path?(path) && kargs[:base_path]
53
+ load_path, _ = paths_split(config[:paths], kargs[:base_path])
54
+ message << " under '#{load_path}'"
55
+ end
56
+
57
+ message << " with type '#{kargs[:accept]}'" if kargs[:accept]
58
+
59
+ load_paths = kargs[:load_paths] || config[:paths]
60
+ message << "\nChecked in these paths: \n #{ load_paths.join("\n ") }"
61
+
62
+ raise FileNotFound, message
63
+ end
64
+
65
+ return uri, deps
66
+ end
67
+
68
+ protected
69
+
70
+ # Internal: Finds an asset given a URI
71
+ #
72
+ # uri - String. Contains file:// scheme, absolute path to
73
+ # file.
74
+ # e.g. "file:///Users/schneems/sprockets/test/fixtures/default/gallery.js?type=application/javascript"
75
+ #
76
+ # Returns Array. Contains a String uri and Set of dependencies
77
+ def resolve_asset_uri(uri)
78
+ filename, _ = URIUtils.parse_asset_uri(uri)
79
+ return uri, Set.new( [URIUtils.build_file_digest_uri(filename)] )
80
+ end
81
+
82
+ # Internal: Finds a file in a set of given paths
83
+ #
84
+ # paths - Array of Strings.
85
+ # filename - String containing absolute path to a file including extension.
86
+ # e.g. "/Users/schneems/sprockets/test/fixtures/asset/application.js"
87
+ # accept - String. A Quality value incoded set of
88
+ # mime types that we are looking for. Can be nil.
89
+ # e.g. "application/javascript" or "text/css, */*"
90
+ #
91
+ # Returns Array. Filename, type, path_pipeline, deps, index_alias
92
+ def resolve_absolute_path(paths, filename, accept)
93
+ deps = Set.new
94
+ filename = File.expand_path(filename)
95
+
96
+ # Ensure path is under load paths
97
+ return nil, nil, deps unless PathUtils.paths_split(paths, filename)
98
+
99
+ _, mime_type = PathUtils.match_path_extname(filename, config[:mime_exts])
100
+ type = resolve_transform_type(mime_type, accept)
101
+ return nil, nil, deps if accept && !type
102
+
103
+ return nil, nil, deps unless file?(filename)
104
+
105
+ deps << URIUtils.build_file_digest_uri(filename)
106
+ return filename, type, deps
107
+ end
108
+
109
+ # Internal: Finds a relative file in a set of given paths
110
+ #
111
+ # paths - Array of Strings.
112
+ # path - String. A relative filename with or without extension
113
+ # e.g. "./jquery" or "../foo.js"
114
+ # dirname - String. Base path where we start looking for the given file.
115
+ # accept - String. A Quality value incoded set of
116
+ # mime types that we are looking for. Can be nil.
117
+ # e.g. "application/javascript" or "text/css, */*"
118
+ #
119
+ # Returns Array. Filename, type, path_pipeline, deps, index_alias
120
+ def resolve_relative_path(paths, path, dirname, accept)
121
+ filename = File.expand_path(path, dirname)
122
+ load_path, _ = PathUtils.paths_split(paths, dirname)
123
+ if load_path && logical_path = PathUtils.split_subpath(load_path, filename)
124
+ resolve_logical_path([load_path], logical_path, accept)
125
+ else
126
+ return nil, nil, nil, Set.new
127
+ end
128
+ end
129
+
130
+ # Internal: Finds a file in a set of given paths
131
+ #
132
+ # paths - Array of Strings.
133
+ # logical_path - String. A filename with extension
134
+ # e.g. "coffee/foo.js" or "foo.js"
135
+ # accept - String. A Quality value incoded set of
136
+ # mime types that we are looking for. Can be nil.
137
+ # e.g. "application/javascript" or "text/css, */*"
138
+ #
139
+ # Finds a file on the given paths.
140
+ #
141
+ # Returns Array. Filename, type, path_pipeline, deps, index_alias
142
+ def resolve_logical_path(paths, logical_path, accept)
143
+ extname, mime_type = PathUtils.match_path_extname(logical_path, config[:mime_exts])
144
+ logical_name = logical_path.chomp(extname)
145
+
146
+ extname, pipeline = PathUtils.match_path_extname(logical_name, config[:pipeline_exts])
147
+ logical_name = logical_name.chomp(extname)
148
+
149
+ parsed_accept = parse_accept_options(mime_type, accept)
150
+ transformed_accepts = expand_transform_accepts(parsed_accept)
151
+
152
+ filename, mime_type, deps, index_alias = resolve_under_paths(paths, logical_name, transformed_accepts)
153
+
154
+ if filename
155
+ deps << build_file_digest_uri(filename)
156
+ type = resolve_transform_type(mime_type, parsed_accept)
157
+ return filename, type, pipeline, deps, index_alias
158
+ else
159
+ return nil, nil, nil, deps
160
+ end
161
+ end
162
+
163
+ # Internal: Finds a file in a set of given paths
164
+ #
165
+ # paths - Array of Strings.
166
+ # logical_name - String. A filename without extension
167
+ # e.g. "application" or "coffee/foo"
168
+ # accepts - Array of array containing mime/version pairs
169
+ # e.g. [["application/javascript", 1.0]]
170
+ #
171
+ # Finds a file with the same name as `logical_name` or "index" inside
172
+ # of the `logical_name` directory that matches a valid mime-type/version from
173
+ # `accepts`.
174
+ #
175
+ # Returns Array. Filename, type, dependencies, and index_alias
176
+ def resolve_under_paths(paths, logical_name, accepts)
177
+ deps = Set.new
178
+ return nil, nil, deps if accepts.empty?
179
+
180
+ # TODO: Allow new path resolves to be registered
181
+ @resolvers ||= [
182
+ method(:resolve_main_under_path),
183
+ method(:resolve_alts_under_path),
184
+ method(:resolve_index_under_path)
185
+ ]
186
+ mime_exts = config[:mime_exts]
187
+
188
+ paths.each do |load_path|
189
+ candidates = []
190
+ @resolvers.each do |fn|
191
+ result = fn.call(load_path, logical_name, mime_exts)
192
+ candidates.concat(result[0])
193
+ deps.merge(result[1])
194
+ end
195
+
196
+ candidate = HTTPUtils.find_best_q_match(accepts, candidates) do |c, matcher|
197
+ match_mime_type?(c[:type] || "application/octet-stream", matcher)
198
+ end
199
+ return candidate[:filename], candidate[:type], deps, candidate[:index_alias] if candidate
200
+ end
201
+
202
+ return nil, nil, deps
203
+ end
204
+
205
+ # Internal: Finds candidate files on a given path
206
+ #
207
+ # load_path - String. An absolute path to a directory
208
+ # logical_name - String. A filename without extension
209
+ # e.g. "application" or "coffee/foo"
210
+ # mime_exts - Hash of file extensions and their mime types
211
+ # e.g. {".xml.builder"=>"application/xml+builder"}
212
+ #
213
+ # Finds files that match a given `logical_name` with an acceptable
214
+ # mime type that is included in `mime_exts` on the `load_path`.
215
+ #
216
+ # Returns Array. First element is an Array of hashes or empty, second is a String
217
+ def resolve_main_under_path(load_path, logical_name, mime_exts)
218
+ dirname = File.dirname(File.join(load_path, logical_name))
219
+ candidates = self.find_matching_path_for_extensions(dirname, File.basename(logical_name), mime_exts)
220
+ candidates.map! do |c|
221
+ { filename: c[0], type: c[1] }
222
+ end
223
+ return candidates, [ URIUtils.build_file_digest_uri(dirname) ]
224
+ end
225
+
226
+
227
+ # Internal: Finds candidate index files in a given path
228
+ #
229
+ # load_path - String. An absolute path to a directory
230
+ # logical_name - String. A filename without extension
231
+ # e.g. "application" or "coffee/foo"
232
+ # mime_exts - Hash of file extensions and their mime types
233
+ # e.g. {".xml.builder"=>"application/xml+builder"}
234
+ #
235
+ # Looking in the given `load_path` this method will find all files under the `logical_name` directory
236
+ # that are named `index` and have a matching mime type in `mime_exts`.
237
+ #
238
+ # Returns Array. First element is an Array of hashes or empty, second is a String
239
+ def resolve_index_under_path(load_path, logical_name, mime_exts)
240
+ dirname = File.join(load_path, logical_name)
241
+
242
+ if self.directory?(dirname)
243
+ candidates = self.find_matching_path_for_extensions(dirname, "index".freeze, mime_exts)
244
+ else
245
+ candidates = []
246
+ end
247
+
248
+ candidates.map! do |c|
249
+ { filename: c[0],
250
+ type: c[1],
251
+ index_alias: compress_from_root(c[0].sub(/\/index(\.[^\/]+)$/, '\1')) }
252
+ end
253
+
254
+ return candidates, [ URIUtils.build_file_digest_uri(dirname) ]
255
+ end
256
+
257
+ def resolve_alts_under_path(load_path, logical_name, mime_exts)
258
+ filenames, deps = self.resolve_alternates(load_path, logical_name)
259
+ filenames.map! do |fn|
260
+ _, mime_type = PathUtils.match_path_extname(fn, mime_exts)
261
+ { filename: fn, type: mime_type }
262
+ end
263
+ return filenames, deps
264
+ end
265
+
266
+ # Internal: Converts mimetype into accept Array
267
+ #
268
+ # - mime_type - String, optional. e.g. "text/html"
269
+ # - explicit_type - String, optional. e.g. "application/javascript"
270
+ #
271
+ # When called with an explicit_type and a mime_type, only a mime_type
272
+ # that matches the given explicit_type will be accepted.
273
+ #
274
+ # Returns Array of Array
275
+ #
276
+ # [["application/javascript", 1.0]]
277
+ # [["*/*", 1.0]]
278
+ # []
279
+ def parse_accept_options(mime_type, explicit_type)
280
+ if mime_type
281
+ return [[mime_type, 1.0]] if explicit_type.nil?
282
+ return [[mime_type, 1.0]] if HTTPUtils.parse_q_values(explicit_type).any? { |accept, _| HTTPUtils.match_mime_type?(mime_type, accept) }
283
+ return []
284
+ end
285
+
286
+ accepts = HTTPUtils.parse_q_values(explicit_type)
287
+ accepts << ['*/*'.freeze, 1.0] if accepts.empty?
288
+ return accepts
289
+ end
290
+
291
+ def resolve_alternates(load_path, logical_name)
292
+ return [], Set.new
293
+ end
294
+ end
295
+ end