lux-fw 0.1.17 → 0.1.35
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/bin/cli/am +38 -29
- data/bin/cli/assets +8 -4
- data/bin/cli/exceptions +6 -6
- data/bin/cli/generate +0 -0
- data/bin/cli/get +0 -0
- data/bin/cli/nginx +11 -5
- data/bin/cli/routes +0 -0
- data/bin/cli/systemd +36 -0
- data/bin/forever +0 -0
- data/bin/job_que +0 -0
- data/bin/lux +1 -0
- data/lib/common/base32.rb +0 -0
- data/lib/common/class_attributes.rb +13 -4
- data/lib/common/crypt.rb +6 -10
- data/lib/common/dynamic_class.rb +23 -0
- data/lib/common/generic_model.rb +0 -0
- data/lib/common/hash_with_indifferent_access.rb +352 -0
- data/lib/common/method_attr.rb +69 -0
- data/lib/lux/api/api.rb +26 -27
- data/lib/lux/api/lib/application_api.rb +26 -7
- data/lib/lux/api/lib/doc_builder.rb +18 -17
- data/lib/lux/api/lib/dsl.rb +23 -41
- data/lib/lux/api/lib/error.rb +3 -0
- data/lib/lux/api/lib/model_api.rb +22 -20
- data/lib/lux/api/lib/rescue.rb +5 -15
- data/lib/lux/api/lib/response.rb +46 -0
- data/lib/lux/cache/cache.rb +13 -6
- data/lib/lux/cell/cell.rb +3 -14
- data/lib/lux/config/config.rb +4 -3
- data/lib/lux/controller/controller.rb +3 -3
- data/lib/lux/controller/lib/nav.rb +6 -2
- data/lib/lux/error/error.rb +15 -14
- data/lib/lux/helper/helper.rb +5 -5
- data/lib/lux/helper/lib/html_tag.rb +67 -0
- data/lib/lux/html/lib/input_types.rb +26 -16
- data/lib/lux/lib/lux.rb +51 -0
- data/lib/lux/lux.rb +5 -52
- data/lib/lux/page/lib/response.rb +178 -0
- data/lib/lux/page/page.rb +72 -51
- data/lib/lux/rescue_from/rescue_from.rb +8 -6
- data/lib/lux/template/template.rb +1 -0
- data/lib/lux-fw.rb +2 -0
- data/lib/overload/array.rb +4 -0
- data/lib/overload/date.rb +2 -0
- data/lib/overload/hash.rb +19 -10
- data/lib/overload/it.rb +29 -0
- data/lib/overload/object.rb +3 -19
- data/lib/overload/r.rb +53 -0
- data/lib/overload/string.rb +5 -6
- data/lib/overload/string_inflections.rb +4 -3
- data/lib/plugins/assets/assets_plug.rb +9 -4
- data/lib/plugins/assets/helper_module_adapter.rb +4 -2
- data/lib/plugins/db_helpers/link_plugin.rb +2 -2
- data/lib/plugins/db_logger/init.rb +1 -1
- data/lib/vendor/mini_assets/lib/asset/css.rb +19 -0
- data/lib/vendor/mini_assets/lib/asset/js.rb +17 -0
- data/lib/vendor/mini_assets/lib/asset.rb +71 -0
- data/lib/vendor/mini_assets/lib/base/javascript.rb +13 -0
- data/lib/vendor/mini_assets/lib/base/stylesheet.rb +5 -0
- data/lib/vendor/mini_assets/lib/base.rb +69 -0
- data/lib/vendor/mini_assets/lib/manifest.rb +18 -0
- data/lib/vendor/mini_assets/lib/opts.rb +16 -0
- data/lib/vendor/mini_assets/mini_assets.rb +74 -0
- metadata +23 -10
- data/lib/common/class_method_params.rb +0 -94
- data/lib/overload/hash_wia.rb +0 -282
- data/lib/overload/inflections.rb +0 -199
- data/lib/vendor/mini_assets/mini_asset/base.rb +0 -167
- data/lib/vendor/mini_assets/mini_asset/css.rb +0 -38
- data/lib/vendor/mini_assets/mini_asset/js.rb +0 -38
- data/lib/vendor/mini_assets/mini_asset.rb +0 -31
data/lib/overload/hash_wia.rb
DELETED
@@ -1,282 +0,0 @@
|
|
1
|
-
# exrtacted from Rails
|
2
|
-
|
3
|
-
class HashWithIndifferentAccess < Hash
|
4
|
-
# Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
|
5
|
-
# this class.
|
6
|
-
def extractable_options?
|
7
|
-
true
|
8
|
-
end
|
9
|
-
|
10
|
-
def with_indifferent_access
|
11
|
-
dup
|
12
|
-
end
|
13
|
-
|
14
|
-
def initialize(constructor = {})
|
15
|
-
if constructor.respond_to?(:to_hash)
|
16
|
-
super()
|
17
|
-
update(constructor)
|
18
|
-
|
19
|
-
hash = constructor.to_hash
|
20
|
-
self.default = hash.default if hash.default
|
21
|
-
self.default_proc = hash.default_proc if hash.default_proc
|
22
|
-
else
|
23
|
-
super(constructor)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def default(*args)
|
28
|
-
arg_key = args.first
|
29
|
-
|
30
|
-
if include?(key = convert_key(arg_key))
|
31
|
-
self[key]
|
32
|
-
else
|
33
|
-
super
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.[](*args)
|
38
|
-
new.merge!(Hash[*args])
|
39
|
-
end
|
40
|
-
|
41
|
-
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
42
|
-
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
43
|
-
|
44
|
-
# Assigns a new value to the hash:
|
45
|
-
#
|
46
|
-
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
47
|
-
# hash[:key] = 'value'
|
48
|
-
#
|
49
|
-
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
50
|
-
def []=(key, value)
|
51
|
-
regular_writer(convert_key(key), convert_value(value, for: :assignment))
|
52
|
-
end
|
53
|
-
|
54
|
-
alias_method :store, :[]=
|
55
|
-
|
56
|
-
# Updates the receiver in-place, merging in the hash passed as argument:
|
57
|
-
#
|
58
|
-
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
59
|
-
# hash_1[:key] = 'value'
|
60
|
-
#
|
61
|
-
# hash_2 = ActiveSupport::HashWithIndifferentAccess.new
|
62
|
-
# hash_2[:key] = 'New Value!'
|
63
|
-
#
|
64
|
-
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
65
|
-
#
|
66
|
-
# The argument can be either an
|
67
|
-
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
68
|
-
# In either case the merge respects the semantics of indifferent access.
|
69
|
-
#
|
70
|
-
# If the argument is a regular hash with keys +:key+ and +"key"+ only one
|
71
|
-
# of the values end up in the receiver, but which one is unspecified.
|
72
|
-
#
|
73
|
-
# When given a block, the value for duplicated keys will be determined
|
74
|
-
# by the result of invoking the block with the duplicated key, the value
|
75
|
-
# in the receiver, and the value in +other_hash+. The rules for duplicated
|
76
|
-
# keys follow the semantics of indifferent access:
|
77
|
-
#
|
78
|
-
# hash_1[:key] = 10
|
79
|
-
# hash_2['key'] = 12
|
80
|
-
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
81
|
-
def update(other_hash)
|
82
|
-
if other_hash.is_a? HashWithIndifferentAccess
|
83
|
-
super(other_hash)
|
84
|
-
else
|
85
|
-
other_hash.to_hash.each_pair do |key, value|
|
86
|
-
if block_given? && key?(key)
|
87
|
-
value = yield(convert_key(key), self[key], value)
|
88
|
-
end
|
89
|
-
regular_writer(convert_key(key), convert_value(value))
|
90
|
-
end
|
91
|
-
self
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
alias_method :merge!, :update
|
96
|
-
|
97
|
-
# Checks the hash for a key matching the argument passed in:
|
98
|
-
#
|
99
|
-
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
100
|
-
# hash['key'] = 'value'
|
101
|
-
# hash.key?(:key) # => true
|
102
|
-
# hash.key?('key') # => true
|
103
|
-
def key?(key)
|
104
|
-
super(convert_key(key))
|
105
|
-
end
|
106
|
-
|
107
|
-
alias_method :include?, :key?
|
108
|
-
alias_method :has_key?, :key?
|
109
|
-
alias_method :member?, :key?
|
110
|
-
|
111
|
-
# Same as <tt>Hash#[]</tt> where the key passed as argument can be
|
112
|
-
# either a string or a symbol:
|
113
|
-
#
|
114
|
-
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
115
|
-
# counters[:foo] = 1
|
116
|
-
#
|
117
|
-
# counters['foo'] # => 1
|
118
|
-
# counters[:foo] # => 1
|
119
|
-
# counters[:zoo] # => nil
|
120
|
-
def [](key)
|
121
|
-
super(convert_key(key))
|
122
|
-
end
|
123
|
-
|
124
|
-
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
125
|
-
# either a string or a symbol:
|
126
|
-
#
|
127
|
-
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
128
|
-
# counters[:foo] = 1
|
129
|
-
#
|
130
|
-
# counters.fetch('foo') # => 1
|
131
|
-
# counters.fetch(:bar, 0) # => 0
|
132
|
-
# counters.fetch(:bar) { |key| 0 } # => 0
|
133
|
-
# counters.fetch(:zoo) # => KeyError: key not found: "zoo"
|
134
|
-
def fetch(key, *extras)
|
135
|
-
super(convert_key(key), *extras)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Returns an array of the values at the specified indices:
|
139
|
-
#
|
140
|
-
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
141
|
-
# hash[:a] = 'x'
|
142
|
-
# hash[:b] = 'y'
|
143
|
-
# hash.values_at('a', 'b') # => ["x", "y"]
|
144
|
-
def values_at(*indices)
|
145
|
-
indices.collect { |key| self[convert_key(key)] }
|
146
|
-
end
|
147
|
-
|
148
|
-
# Returns an array of the values at the specified indices, but also
|
149
|
-
# raises an exception when one of the keys can't be found.
|
150
|
-
#
|
151
|
-
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
152
|
-
# hash[:a] = 'x'
|
153
|
-
# hash[:b] = 'y'
|
154
|
-
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
155
|
-
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
156
|
-
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
157
|
-
def fetch_values(*indices, &block)
|
158
|
-
indices.collect { |key| fetch(key, &block) }
|
159
|
-
end if Hash.method_defined?(:fetch_values)
|
160
|
-
|
161
|
-
# Returns a shallow copy of the hash.
|
162
|
-
#
|
163
|
-
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
164
|
-
# dup = hash.dup
|
165
|
-
# dup[:a][:c] = 'c'
|
166
|
-
#
|
167
|
-
# hash[:a][:c] # => nil
|
168
|
-
# dup[:a][:c] # => "c"
|
169
|
-
def dup
|
170
|
-
self.class.new(self).tap do |new_hash|
|
171
|
-
set_defaults(new_hash)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# This method has the same semantics of +update+, except it does not
|
176
|
-
# modify the receiver but rather returns a new hash with indifferent
|
177
|
-
# access with the result of the merge.
|
178
|
-
def merge(hash, &block)
|
179
|
-
dup.update(hash, &block)
|
180
|
-
end
|
181
|
-
|
182
|
-
# Like +merge+ but the other way around: Merges the receiver into the
|
183
|
-
# argument and returns a new hash with indifferent access as result:
|
184
|
-
#
|
185
|
-
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
186
|
-
# hash['a'] = nil
|
187
|
-
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
|
188
|
-
def reverse_merge(other_hash)
|
189
|
-
super(self.class.new(other_hash))
|
190
|
-
end
|
191
|
-
alias_method :with_defaults, :reverse_merge
|
192
|
-
|
193
|
-
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
194
|
-
def reverse_merge!(other_hash)
|
195
|
-
replace(reverse_merge(other_hash))
|
196
|
-
end
|
197
|
-
alias_method :with_defaults!, :reverse_merge!
|
198
|
-
|
199
|
-
# Replaces the contents of this hash with other_hash.
|
200
|
-
#
|
201
|
-
# h = { "a" => 100, "b" => 200 }
|
202
|
-
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
|
203
|
-
def replace(other_hash)
|
204
|
-
super(self.class.new(other_hash))
|
205
|
-
end
|
206
|
-
|
207
|
-
# Removes the specified key from the hash.
|
208
|
-
def delete(key)
|
209
|
-
super(convert_key(key))
|
210
|
-
end
|
211
|
-
|
212
|
-
def stringify_keys!; self end
|
213
|
-
def deep_stringify_keys!; self end
|
214
|
-
def stringify_keys; dup end
|
215
|
-
def deep_stringify_keys; dup end
|
216
|
-
# undef :symbolize_keys!
|
217
|
-
# undef :deep_symbolize_keys!
|
218
|
-
def symbolize_keys; to_hash.symbolize_keys! end
|
219
|
-
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
220
|
-
def to_options!; self end
|
221
|
-
|
222
|
-
def select(*args, &block)
|
223
|
-
return to_enum(:select) unless block_given?
|
224
|
-
dup.tap { |hash| hash.select!(*args, &block) }
|
225
|
-
end
|
226
|
-
|
227
|
-
def reject(*args, &block)
|
228
|
-
return to_enum(:reject) unless block_given?
|
229
|
-
dup.tap { |hash| hash.reject!(*args, &block) }
|
230
|
-
end
|
231
|
-
|
232
|
-
def transform_values(*args, &block)
|
233
|
-
return to_enum(:transform_values) unless block_given?
|
234
|
-
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
235
|
-
end
|
236
|
-
|
237
|
-
def compact
|
238
|
-
dup.tap(&:compact!)
|
239
|
-
end
|
240
|
-
|
241
|
-
# Convert to a regular hash with string keys.
|
242
|
-
def to_hash
|
243
|
-
_new_hash = Hash.new
|
244
|
-
set_defaults(_new_hash)
|
245
|
-
|
246
|
-
each do |key, value|
|
247
|
-
_new_hash[key] = convert_value(value, for: :to_hash)
|
248
|
-
end
|
249
|
-
_new_hash
|
250
|
-
end
|
251
|
-
|
252
|
-
private
|
253
|
-
def convert_key(key) # :doc:
|
254
|
-
key.kind_of?(Symbol) ? key.to_s : key
|
255
|
-
end
|
256
|
-
|
257
|
-
def convert_value(value, options = {}) # :doc:
|
258
|
-
if value.is_a? Hash
|
259
|
-
if options[:for] == :to_hash
|
260
|
-
value.to_hash
|
261
|
-
else
|
262
|
-
value.class == Hash ? HashWithIndifferentAccess.new(value) : value
|
263
|
-
end
|
264
|
-
elsif value.is_a?(Array)
|
265
|
-
if options[:for] != :assignment || value.frozen?
|
266
|
-
value = value.dup
|
267
|
-
end
|
268
|
-
value.map! { |e| convert_value(e, options) }
|
269
|
-
else
|
270
|
-
value
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def set_defaults(target) # :doc:
|
275
|
-
if default_proc
|
276
|
-
target.default_proc = default_proc.dup
|
277
|
-
else
|
278
|
-
target.default = default
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
data/lib/overload/inflections.rb
DELETED
@@ -1,199 +0,0 @@
|
|
1
|
-
# # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb
|
2
|
-
|
3
|
-
# class String
|
4
|
-
# def pluralize(locale = :en)
|
5
|
-
# word = self
|
6
|
-
# apply_inflections(word, inflections(locale).plurals)
|
7
|
-
# end
|
8
|
-
|
9
|
-
# def singularize(locale = :en)
|
10
|
-
# word = self
|
11
|
-
# apply_inflections(word, inflections(locale).singulars)
|
12
|
-
# end
|
13
|
-
|
14
|
-
# def camelize(uppercase_first_letter = true)
|
15
|
-
# term = self
|
16
|
-
# string = term.to_s
|
17
|
-
# if uppercase_first_letter
|
18
|
-
# string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize }
|
19
|
-
# else
|
20
|
-
# string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
|
21
|
-
# end
|
22
|
-
# string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
23
|
-
# string.gsub!("/".freeze, "::".freeze)
|
24
|
-
# string
|
25
|
-
# end
|
26
|
-
|
27
|
-
# def underscore
|
28
|
-
# camel_cased_word = self
|
29
|
-
# return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
30
|
-
# word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze)
|
31
|
-
# word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'.freeze }#{$2.downcase}" }
|
32
|
-
# word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
|
33
|
-
# word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
|
34
|
-
# word.tr!("-".freeze, "_".freeze)
|
35
|
-
# word.downcase!
|
36
|
-
# word
|
37
|
-
# end
|
38
|
-
|
39
|
-
# def humanize(options = {})
|
40
|
-
# result = self.to_s.dup
|
41
|
-
|
42
|
-
# inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
43
|
-
|
44
|
-
# result.sub!(/\A_+/, "".freeze)
|
45
|
-
# result.sub!(/_id\z/, "".freeze)
|
46
|
-
# result.tr!("_".freeze, " ".freeze)
|
47
|
-
|
48
|
-
# result.gsub!(/([a-z\d]*)/i) do |match|
|
49
|
-
# "#{inflections.acronyms[match] || match.downcase}"
|
50
|
-
# end
|
51
|
-
|
52
|
-
# if options.fetch(:capitalize, true)
|
53
|
-
# result.sub!(/\A\w/) { |match| match.upcase }
|
54
|
-
# end
|
55
|
-
|
56
|
-
# result
|
57
|
-
# end
|
58
|
-
|
59
|
-
# def upcase_first
|
60
|
-
# string = self
|
61
|
-
# string.length > 0 ? string[0].upcase.concat(string[1..-1]) : ""
|
62
|
-
# end
|
63
|
-
|
64
|
-
# def titleize
|
65
|
-
# word = self
|
66
|
-
# humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { |match| match.capitalize }
|
67
|
-
# end
|
68
|
-
|
69
|
-
# def tableize
|
70
|
-
# class_name = self
|
71
|
-
# pluralize(underscore(class_name))
|
72
|
-
# end
|
73
|
-
|
74
|
-
# def classify
|
75
|
-
# table_name = self.dup
|
76
|
-
# table_name.to_s.sub(/.*\./, "").freeze.singularize.camelize
|
77
|
-
# end
|
78
|
-
|
79
|
-
# def dasherize
|
80
|
-
# underscored_word = self
|
81
|
-
# underscored_word.tr("_".freeze, "-".freeze)
|
82
|
-
# end
|
83
|
-
|
84
|
-
# def demodulize()
|
85
|
-
# path = self.to_s
|
86
|
-
# if i = path.rindex("::")
|
87
|
-
# path[(i + 2)..-1]
|
88
|
-
# else
|
89
|
-
# path
|
90
|
-
# end
|
91
|
-
# end
|
92
|
-
|
93
|
-
# def deconstantize
|
94
|
-
# path = self.to_s
|
95
|
-
# path.to_s[0, path.rindex("::") || 0] # implementation based on the one in facets' Module#spacename
|
96
|
-
# end
|
97
|
-
|
98
|
-
# def foreign_key(separate_class_name_and_id_with_underscore = true)
|
99
|
-
# class_name = self
|
100
|
-
# underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
|
101
|
-
# end
|
102
|
-
|
103
|
-
# def constantize
|
104
|
-
# camel_cased_word = self
|
105
|
-
# names = camel_cased_word.split("::".freeze)
|
106
|
-
|
107
|
-
# # Trigger a built-in NameError exception including the ill-formed constant in the message.
|
108
|
-
# Object.const_get(camel_cased_word) if names.blank?
|
109
|
-
|
110
|
-
# # Remove the first blank element in case of '::ClassName' notation.
|
111
|
-
# names.shift if names.size > 1 && names.first.blank?
|
112
|
-
|
113
|
-
# names.inject(Object) do |constant, name|
|
114
|
-
# if constant == Object
|
115
|
-
# constant.const_get(name)
|
116
|
-
# else
|
117
|
-
# candidate = constant.const_get(name)
|
118
|
-
# next candidate if constant.const_defined?(name, false)
|
119
|
-
# next candidate unless Object.const_defined?(name)
|
120
|
-
|
121
|
-
# # Go down the ancestors to check if it is owned directly. The check
|
122
|
-
# # stops when we reach Object or the end of ancestors tree.
|
123
|
-
# constant = constant.ancestors.inject do |const, ancestor|
|
124
|
-
# break const if ancestor == Object
|
125
|
-
# break ancestor if ancestor.const_defined?(name, false)
|
126
|
-
# const
|
127
|
-
# end
|
128
|
-
|
129
|
-
# # owner is in Object, so raise
|
130
|
-
# constant.const_get(name, false)
|
131
|
-
# end
|
132
|
-
# end
|
133
|
-
# end
|
134
|
-
|
135
|
-
# def safe_constantize
|
136
|
-
# camel_cased_word = self
|
137
|
-
# constantize(camel_cased_word)
|
138
|
-
# rescue NameError => e
|
139
|
-
# raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
|
140
|
-
# e.name.to_s == camel_cased_word.to_s)
|
141
|
-
# rescue ArgumentError => e
|
142
|
-
# raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
|
143
|
-
# end
|
144
|
-
|
145
|
-
# def ordinal
|
146
|
-
# number = self
|
147
|
-
# abs_number = number.to_i.abs
|
148
|
-
|
149
|
-
# if (11..13).include?(abs_number % 100)
|
150
|
-
# "th"
|
151
|
-
# else
|
152
|
-
# case abs_number % 10
|
153
|
-
# when 1; "st"
|
154
|
-
# when 2; "nd"
|
155
|
-
# when 3; "rd"
|
156
|
-
# else "th"
|
157
|
-
# end
|
158
|
-
# end
|
159
|
-
# end
|
160
|
-
|
161
|
-
# def ordinalize
|
162
|
-
# number = self
|
163
|
-
# "#{number}#{ordinal(number)}"
|
164
|
-
# end
|
165
|
-
|
166
|
-
# private
|
167
|
-
|
168
|
-
# # Mounts a regular expression, returned as a string to ease interpolation,
|
169
|
-
# # that will match part by part the given constant.
|
170
|
-
# #
|
171
|
-
# # const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
|
172
|
-
# # const_regexp("::") # => "::"
|
173
|
-
# def const_regexp(camel_cased_word) #:nodoc:
|
174
|
-
# parts = camel_cased_word.split("::".freeze)
|
175
|
-
|
176
|
-
# return Regexp.escape(camel_cased_word) if parts.blank?
|
177
|
-
|
178
|
-
# last = parts.pop
|
179
|
-
|
180
|
-
# parts.reverse.inject(last) do |acc, part|
|
181
|
-
# part.blank? ? acc : "#{part}(::#{acc})?"
|
182
|
-
# end
|
183
|
-
# end
|
184
|
-
|
185
|
-
# # Applies inflection rules for +singularize+ and +pluralize+.
|
186
|
-
# #
|
187
|
-
# # apply_inflections('post', inflections.plurals) # => "posts"
|
188
|
-
# # apply_inflections('posts', inflections.singulars) # => "post"
|
189
|
-
# def apply_inflections(word, rules)
|
190
|
-
# result = word.to_s.dup
|
191
|
-
|
192
|
-
# if word.blank? || inflections.uncountables.uncountable?(result)
|
193
|
-
# result
|
194
|
-
# else
|
195
|
-
# rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
196
|
-
# result
|
197
|
-
# end
|
198
|
-
# end
|
199
|
-
# end
|
@@ -1,167 +0,0 @@
|
|
1
|
-
class MiniAsset::Base
|
2
|
-
attr_reader :error
|
3
|
-
|
4
|
-
def initialize source, opts={}
|
5
|
-
@source = source
|
6
|
-
@opts = opts
|
7
|
-
|
8
|
-
raise 'Bad source: %s' % source unless File.exist?(local_file)
|
9
|
-
end
|
10
|
-
|
11
|
-
def run! what
|
12
|
-
puts what.yellow
|
13
|
-
|
14
|
-
stdin, stdout, stderr, wait_thread = Open3.popen3(what)
|
15
|
-
|
16
|
-
error = stderr.gets
|
17
|
-
while line = stderr.gets do
|
18
|
-
error += line
|
19
|
-
end
|
20
|
-
|
21
|
-
# node-sass prints to stderror on complete
|
22
|
-
error = nil if error && error.index('Rendering Complete, saving .css file...')
|
23
|
-
|
24
|
-
if error
|
25
|
-
File.unlink(cache_file) if File.exists?(cache_file)
|
26
|
-
@error = error
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def production?
|
31
|
-
!!@opts[:production]
|
32
|
-
end
|
33
|
-
|
34
|
-
def create file, opts=nil
|
35
|
-
MiniAsset.create file, opts || @opts
|
36
|
-
end
|
37
|
-
|
38
|
-
def content
|
39
|
-
File.read local_file
|
40
|
-
end
|
41
|
-
|
42
|
-
def ext
|
43
|
-
@source.split('.').last.to_sym
|
44
|
-
end
|
45
|
-
|
46
|
-
def asset_join_string
|
47
|
-
"\n"
|
48
|
-
end
|
49
|
-
|
50
|
-
def local_file
|
51
|
-
'app/assets/%s' % @source
|
52
|
-
end
|
53
|
-
|
54
|
-
def production_file
|
55
|
-
file = MiniAsset.manifest['files'][@source] || raise('Production file not found')
|
56
|
-
|
57
|
-
'public%s' % file
|
58
|
-
end
|
59
|
-
|
60
|
-
def cache_file
|
61
|
-
'tmp/assets/%s' % @source.gsub('/', '-')
|
62
|
-
end
|
63
|
-
|
64
|
-
def base_dir
|
65
|
-
list = @source.split('/')
|
66
|
-
list.pop
|
67
|
-
'app/assets/' + list.join('/')
|
68
|
-
end
|
69
|
-
|
70
|
-
def resolve_file files
|
71
|
-
files = files.sub(/^\.\//,'')
|
72
|
-
files += '/*' unless files.include?('*')
|
73
|
-
|
74
|
-
path = '%s/%s' % [base_dir, files]
|
75
|
-
@files += Dir[path].sort.map{ |f| f.split('app/assets/', 2).last }
|
76
|
-
end
|
77
|
-
|
78
|
-
def files
|
79
|
-
return @files if @files
|
80
|
-
|
81
|
-
@files = []
|
82
|
-
|
83
|
-
for line in content.split($/)
|
84
|
-
test = line.split(/^[\/\/#]=\s*req\w*\s+/)
|
85
|
-
resolve_file test[1] if test[1]
|
86
|
-
end
|
87
|
-
|
88
|
-
@files.push @source
|
89
|
-
@files
|
90
|
-
end
|
91
|
-
|
92
|
-
def path_for_comment
|
93
|
-
'/* Source: %s */' % @source
|
94
|
-
end
|
95
|
-
|
96
|
-
def do_compile?
|
97
|
-
return true unless File.exists?(cache_file)
|
98
|
-
return true if File.mtime(cache_file).to_i <= File.mtime(local_file).to_i
|
99
|
-
false
|
100
|
-
end
|
101
|
-
|
102
|
-
# compiles all the files, allways for production
|
103
|
-
def compile args=[]
|
104
|
-
data = []
|
105
|
-
|
106
|
-
for file in files
|
107
|
-
asset = create file, production: true
|
108
|
-
data.push asset.path_for_comment
|
109
|
-
data.push asset.compiled_data
|
110
|
-
end
|
111
|
-
|
112
|
-
data = data.join(asset_join_string)
|
113
|
-
pfile = update_manifest(data)
|
114
|
-
|
115
|
-
unless File.exists? pfile
|
116
|
-
File.write(pfile, data)
|
117
|
-
minify!
|
118
|
-
end
|
119
|
-
|
120
|
-
if args.include?('gzip')
|
121
|
-
gzip!
|
122
|
-
else
|
123
|
-
gzip_file = '%s.gz' % pfile
|
124
|
-
File.unlink gzip_file if File.exists?(gzip_file)
|
125
|
-
end
|
126
|
-
|
127
|
-
fix_created_times!
|
128
|
-
|
129
|
-
pfile
|
130
|
-
end
|
131
|
-
|
132
|
-
# compiles single current file
|
133
|
-
def compiled_data
|
134
|
-
content
|
135
|
-
end
|
136
|
-
|
137
|
-
def minify!
|
138
|
-
true
|
139
|
-
end
|
140
|
-
|
141
|
-
def gzip!
|
142
|
-
f = production_file
|
143
|
-
run! "gzip -f -c -1 '%{f}' > '%{f}.gz'" % { f: f } unless File.exists?('%s.gz' % f)
|
144
|
-
end
|
145
|
-
|
146
|
-
def fix_created_times!
|
147
|
-
touch_file = 'public/touch.ref'
|
148
|
-
`touch '#{touch_file}'` unless File.exists?(touch_file)
|
149
|
-
|
150
|
-
# touch and fix reference
|
151
|
-
`touch -r '#{touch_file}' #{production_file}`
|
152
|
-
`touch -r '#{touch_file}' #{production_file}.gz` if File.exists?("#{production_file}.gz")
|
153
|
-
end
|
154
|
-
|
155
|
-
def update_manifest data
|
156
|
-
digest = Digest::SHA1.hexdigest(data.to_s)
|
157
|
-
json = MiniAsset.manifest
|
158
|
-
|
159
|
-
pfile = cache_file.sub('tmp/assets/', 'public/assets/')
|
160
|
-
pfile = pfile.sub(/\.(\w+)/, "-#{digest}.\\1")
|
161
|
-
|
162
|
-
json['files'][@source] = pfile.sub('public/', '/')
|
163
|
-
MiniAsset.manifest json
|
164
|
-
pfile
|
165
|
-
end
|
166
|
-
|
167
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
class MiniAsset::Css < MiniAsset::Base
|
2
|
-
|
3
|
-
def content_type
|
4
|
-
'text/css'
|
5
|
-
end
|
6
|
-
|
7
|
-
def cache_file
|
8
|
-
super.sub(/\.(\w+)/, "#{production? ? '-p' : ''}.\\1").sub('.scss', '.css')
|
9
|
-
end
|
10
|
-
|
11
|
-
def update_cache
|
12
|
-
node_sass = './node_modules/node-sass/bin/node-sass'
|
13
|
-
node_opts = production? ? '--output-style compressed' : '--source-comments'
|
14
|
-
run! "#{node_sass} #{node_opts} '#{local_file}' '#{cache_file}'"
|
15
|
-
end
|
16
|
-
|
17
|
-
def compiled_data
|
18
|
-
if do_compile?
|
19
|
-
update_cache
|
20
|
-
else
|
21
|
-
# extract linked files from css cache and compile if needed
|
22
|
-
data = File.read cache_file
|
23
|
-
files = []
|
24
|
-
data.gsub(%r{(app/assets/[\w\-\./]+)}) { files.push($1) unless files.include?($1) }
|
25
|
-
|
26
|
-
final_check = false
|
27
|
-
cache_time = File.mtime(cache_file).to_i
|
28
|
-
for file in files
|
29
|
-
final_check ||= true if cache_time <= File.mtime(file).to_i
|
30
|
-
end
|
31
|
-
|
32
|
-
update_cache if final_check
|
33
|
-
end
|
34
|
-
|
35
|
-
File.read cache_file
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|