garcun 0.0.2
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.
- checksums.yaml +7 -0
- data/.gitattributes +17 -0
- data/.gitignore +197 -0
- data/.rspec +2 -0
- data/Gemfile +22 -0
- data/LICENSE +201 -0
- data/README.md +521 -0
- data/Rakefile +47 -0
- data/garcun.gemspec +83 -0
- data/lib/garcon.rb +290 -0
- data/lib/garcon/chef/chef_helpers.rb +343 -0
- data/lib/garcon/chef/coerce/coercer.rb +134 -0
- data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
- data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
- data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
- data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
- data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
- data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
- data/lib/garcon/chef/handler/devreporter.rb +127 -0
- data/lib/garcon/chef/log.rb +64 -0
- data/lib/garcon/chef/node.rb +100 -0
- data/lib/garcon/chef/provider/civilize.rb +209 -0
- data/lib/garcon/chef/provider/development.rb +159 -0
- data/lib/garcon/chef/provider/download.rb +420 -0
- data/lib/garcon/chef/provider/house_keeping.rb +265 -0
- data/lib/garcon/chef/provider/node_cache.rb +31 -0
- data/lib/garcon/chef/provider/partial.rb +183 -0
- data/lib/garcon/chef/provider/recovery.rb +80 -0
- data/lib/garcon/chef/provider/zip_file.rb +271 -0
- data/lib/garcon/chef/resource/attribute.rb +52 -0
- data/lib/garcon/chef/resource/base_dsl.rb +174 -0
- data/lib/garcon/chef/resource/blender.rb +140 -0
- data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
- data/lib/garcon/chef/resource/resource_name.rb +109 -0
- data/lib/garcon/chef/secret_bag.rb +204 -0
- data/lib/garcon/chef/validations.rb +76 -0
- data/lib/garcon/chef_inclusions.rb +151 -0
- data/lib/garcon/configuration.rb +138 -0
- data/lib/garcon/core_ext.rb +39 -0
- data/lib/garcon/core_ext/array.rb +27 -0
- data/lib/garcon/core_ext/binding.rb +64 -0
- data/lib/garcon/core_ext/boolean.rb +66 -0
- data/lib/garcon/core_ext/duration.rb +271 -0
- data/lib/garcon/core_ext/enumerable.rb +34 -0
- data/lib/garcon/core_ext/file.rb +127 -0
- data/lib/garcon/core_ext/filetest.rb +62 -0
- data/lib/garcon/core_ext/hash.rb +279 -0
- data/lib/garcon/core_ext/kernel.rb +159 -0
- data/lib/garcon/core_ext/lazy.rb +222 -0
- data/lib/garcon/core_ext/method_access.rb +243 -0
- data/lib/garcon/core_ext/module.rb +92 -0
- data/lib/garcon/core_ext/nil.rb +53 -0
- data/lib/garcon/core_ext/numeric.rb +44 -0
- data/lib/garcon/core_ext/object.rb +342 -0
- data/lib/garcon/core_ext/pathname.rb +152 -0
- data/lib/garcon/core_ext/process.rb +41 -0
- data/lib/garcon/core_ext/random.rb +497 -0
- data/lib/garcon/core_ext/string.rb +312 -0
- data/lib/garcon/core_ext/struct.rb +49 -0
- data/lib/garcon/core_ext/symbol.rb +170 -0
- data/lib/garcon/core_ext/time.rb +234 -0
- data/lib/garcon/exceptions.rb +101 -0
- data/lib/garcon/inflections.rb +237 -0
- data/lib/garcon/inflections/defaults.rb +79 -0
- data/lib/garcon/inflections/inflections.rb +182 -0
- data/lib/garcon/inflections/rules_collection.rb +37 -0
- data/lib/garcon/secret.rb +271 -0
- data/lib/garcon/stash/format.rb +114 -0
- data/lib/garcon/stash/journal.rb +226 -0
- data/lib/garcon/stash/queue.rb +83 -0
- data/lib/garcon/stash/serializer.rb +86 -0
- data/lib/garcon/stash/store.rb +435 -0
- data/lib/garcon/task.rb +31 -0
- data/lib/garcon/task/atomic.rb +151 -0
- data/lib/garcon/task/atomic_boolean.rb +127 -0
- data/lib/garcon/task/condition.rb +99 -0
- data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
- data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
- data/lib/garcon/task/count_down_latch.rb +92 -0
- data/lib/garcon/task/delay.rb +196 -0
- data/lib/garcon/task/dereferenceable.rb +144 -0
- data/lib/garcon/task/event.rb +119 -0
- data/lib/garcon/task/executor.rb +275 -0
- data/lib/garcon/task/executor_options.rb +59 -0
- data/lib/garcon/task/future.rb +107 -0
- data/lib/garcon/task/immediate_executor.rb +84 -0
- data/lib/garcon/task/ivar.rb +171 -0
- data/lib/garcon/task/lazy_reference.rb +74 -0
- data/lib/garcon/task/monotonic_time.rb +69 -0
- data/lib/garcon/task/obligation.rb +256 -0
- data/lib/garcon/task/observable.rb +101 -0
- data/lib/garcon/task/priority_queue.rb +234 -0
- data/lib/garcon/task/processor_count.rb +128 -0
- data/lib/garcon/task/read_write_lock.rb +304 -0
- data/lib/garcon/task/safe_task_executor.rb +58 -0
- data/lib/garcon/task/single_thread_executor.rb +97 -0
- data/lib/garcon/task/thread_pool/cached.rb +71 -0
- data/lib/garcon/task/thread_pool/executor.rb +294 -0
- data/lib/garcon/task/thread_pool/fixed.rb +61 -0
- data/lib/garcon/task/thread_pool/worker.rb +90 -0
- data/lib/garcon/task/timer.rb +44 -0
- data/lib/garcon/task/timer_set.rb +194 -0
- data/lib/garcon/task/timer_task.rb +377 -0
- data/lib/garcon/task/waitable_list.rb +58 -0
- data/lib/garcon/utility/ansi.rb +199 -0
- data/lib/garcon/utility/at_random.rb +77 -0
- data/lib/garcon/utility/crypto.rb +292 -0
- data/lib/garcon/utility/equalizer.rb +146 -0
- data/lib/garcon/utility/faker/extensions/array.rb +22 -0
- data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
- data/lib/garcon/utility/faker/faker.rb +164 -0
- data/lib/garcon/utility/faker/faker/company.rb +17 -0
- data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
- data/lib/garcon/utility/faker/faker/version.rb +3 -0
- data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
- data/lib/garcon/utility/faker/locales/en.yml +21 -0
- data/lib/garcon/utility/file_helper.rb +170 -0
- data/lib/garcon/utility/hookers.rb +178 -0
- data/lib/garcon/utility/interpolation.rb +90 -0
- data/lib/garcon/utility/memstash.rb +364 -0
- data/lib/garcon/utility/misc.rb +54 -0
- data/lib/garcon/utility/msg_from_god.rb +62 -0
- data/lib/garcon/utility/retry.rb +238 -0
- data/lib/garcon/utility/timeout.rb +58 -0
- data/lib/garcon/utility/uber/builder.rb +91 -0
- data/lib/garcon/utility/uber/callable.rb +7 -0
- data/lib/garcon/utility/uber/delegates.rb +13 -0
- data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
- data/lib/garcon/utility/uber/options.rb +101 -0
- data/lib/garcon/utility/uber/uber_version.rb +3 -0
- data/lib/garcon/utility/uber/version.rb +33 -0
- data/lib/garcon/utility/url_helper.rb +100 -0
- data/lib/garcon/utils.rb +29 -0
- data/lib/garcon/version.rb +62 -0
- data/lib/garcun.rb +24 -0
- metadata +680 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
|
4
|
+
# License: Apache License, Version 2.0
|
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
# Adds `#contains?`, `#blank?` and `#shatter` methods to strings
|
|
21
|
+
#
|
|
22
|
+
class String
|
|
23
|
+
|
|
24
|
+
# Get or set state of object. You can think of #object_state as an in-code
|
|
25
|
+
# form of marshalling.
|
|
26
|
+
#
|
|
27
|
+
def object_state(data=nil)
|
|
28
|
+
data ? replace(data) : dup
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Common Unix cryptography method.
|
|
32
|
+
# This adds a default salt to the built-in crypt method.
|
|
33
|
+
#
|
|
34
|
+
def crypt(salt=nil)
|
|
35
|
+
salt ||= ((SecureRandom.random_number(26) +
|
|
36
|
+
(SecureRandom.random_number(2) == 0 ? 65 : 97)).chr +
|
|
37
|
+
(SecureRandom.random_number(26) +
|
|
38
|
+
(SecureRandom.random_number(2) == 0 ? 65 : 97)).chr)
|
|
39
|
+
_crypt(salt)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Search a text file for a matching string
|
|
43
|
+
#
|
|
44
|
+
# @return [Boolean]
|
|
45
|
+
# True if the file is present and a match was found, otherwise returns
|
|
46
|
+
# false if file does not exist and/or does not contain a match
|
|
47
|
+
#
|
|
48
|
+
# @api public
|
|
49
|
+
def contains?(str)
|
|
50
|
+
return false unless ::File.exist?(self)
|
|
51
|
+
::File.open(self, &:readlines).collect { |l| return true if l.match(str) }
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Turns a string into a regular expression.
|
|
56
|
+
#
|
|
57
|
+
# "a?".to_re #=> /a?/
|
|
58
|
+
#
|
|
59
|
+
def to_re(esc=false)
|
|
60
|
+
Regexp.new((esc ? Regexp.escape(self) : self))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Turns a string into a regular expression.
|
|
64
|
+
# By default it will escape all characters.
|
|
65
|
+
# Use <tt>false</tt> argument to turn off escaping.
|
|
66
|
+
#
|
|
67
|
+
# "[".to_rx #=> /\[/
|
|
68
|
+
#
|
|
69
|
+
def to_rx(esc=true)
|
|
70
|
+
Regexp.new((esc ? Regexp.escape(self) : self))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Strips out whitespace then tests if the string is empty.
|
|
74
|
+
#
|
|
75
|
+
# @example
|
|
76
|
+
# "".blank? # => true
|
|
77
|
+
# " ".blank? # => true
|
|
78
|
+
# " sup? ".blank? # => false
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean]
|
|
81
|
+
# True if blank, else false.
|
|
82
|
+
#
|
|
83
|
+
# @api public
|
|
84
|
+
def blank?
|
|
85
|
+
strip.empty?
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Breaks a string up into an array based on a regular expression.
|
|
89
|
+
# Similar to scan, but includes the matches.
|
|
90
|
+
#
|
|
91
|
+
# @example
|
|
92
|
+
# s = "<p>This<b>is</b>a test.</p>"
|
|
93
|
+
# s.shatter(/\<.*?\>/)
|
|
94
|
+
# => [
|
|
95
|
+
# [0] "<p>",
|
|
96
|
+
# [1] "This",
|
|
97
|
+
# [2] "<b>",
|
|
98
|
+
# [3] "is",
|
|
99
|
+
# [4] "</b>",
|
|
100
|
+
# [5] "a test.",
|
|
101
|
+
# [6] "</p>"
|
|
102
|
+
# ]
|
|
103
|
+
#
|
|
104
|
+
# @param [Regexp] regex
|
|
105
|
+
# Regular expression for breaking string into array.
|
|
106
|
+
#
|
|
107
|
+
# @return [String]
|
|
108
|
+
#
|
|
109
|
+
# @api public
|
|
110
|
+
def shatter(re)
|
|
111
|
+
r = self.gsub(re) { |s| "\1" + s + "\1" }
|
|
112
|
+
while r[ 0, 1] == "\1"; r[0] = ''; end
|
|
113
|
+
while r[-1, 1] == "\1"; r[-1] = ''; end
|
|
114
|
+
r.split("\1")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Left-flush a string based off of the number of whitespace characters on the
|
|
118
|
+
# first line. This is especially useful for heredocs when whitespace matters.
|
|
119
|
+
#
|
|
120
|
+
# @example Remove leading whitespace and flush
|
|
121
|
+
# <<-EOH.flush
|
|
122
|
+
# def method
|
|
123
|
+
# 'This is a string!'
|
|
124
|
+
# end
|
|
125
|
+
# EOH # =>"def method\n 'This is a string!'\nend"
|
|
126
|
+
#
|
|
127
|
+
# @return [String]
|
|
128
|
+
#
|
|
129
|
+
# @api public
|
|
130
|
+
def flush
|
|
131
|
+
gsub(/^#{self[/\A\s*/]}/, '').chomp
|
|
132
|
+
end unless method_defined?(:flush)
|
|
133
|
+
|
|
134
|
+
# Escape all regexp special characters.
|
|
135
|
+
#
|
|
136
|
+
# @example
|
|
137
|
+
# "*?{}.".escape_regexp # => "\\*\\?\\{\\}\\."
|
|
138
|
+
#
|
|
139
|
+
# @return [String]
|
|
140
|
+
# Receiver with all regexp special characters escaped.
|
|
141
|
+
#
|
|
142
|
+
# @api public
|
|
143
|
+
def escape_regexp
|
|
144
|
+
Regexp.escape self
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Unescape all regexp special characters.
|
|
148
|
+
#
|
|
149
|
+
# @example
|
|
150
|
+
# "\\*\\?\\{\\}\\.".unescape_regexp # => "*?{}."
|
|
151
|
+
#
|
|
152
|
+
# @return [String]
|
|
153
|
+
# Receiver with all regexp special characters unescaped.
|
|
154
|
+
#
|
|
155
|
+
# @api public
|
|
156
|
+
def unescape_regexp
|
|
157
|
+
self.gsub(/\\([\.\?\|\(\)\[\]\{\}\^\$\*\+\-])/, '\1')
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Convert a path string to a constant name.
|
|
161
|
+
#
|
|
162
|
+
# @example
|
|
163
|
+
# "chef/mixin/checksum".to_const_string # => "Chef::Mixin::Checksum"
|
|
164
|
+
#
|
|
165
|
+
# @return [String]
|
|
166
|
+
# Receiver converted to a constant name.
|
|
167
|
+
#
|
|
168
|
+
# @api public
|
|
169
|
+
def to_const_string
|
|
170
|
+
gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Convert a constant name to a path, assuming a conventional structure.
|
|
174
|
+
#
|
|
175
|
+
# @example
|
|
176
|
+
# "FooBar::Baz".to_const_path # => "foo_bar/baz"
|
|
177
|
+
#
|
|
178
|
+
# @return [String]
|
|
179
|
+
# Path to the file containing the constant named by receiver (constantized
|
|
180
|
+
# string), assuming a conventional structure.
|
|
181
|
+
#
|
|
182
|
+
# @api public
|
|
183
|
+
def to_const_path
|
|
184
|
+
snake_case.gsub(/::/, "/")
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Join with _o_ as a file path.
|
|
188
|
+
#
|
|
189
|
+
# @example
|
|
190
|
+
# 'usr'/'local' # => 'usr/local'
|
|
191
|
+
#
|
|
192
|
+
# @param [String] other
|
|
193
|
+
# Path component(s) to join with receiver.
|
|
194
|
+
#
|
|
195
|
+
# @return [String]
|
|
196
|
+
# Receiver joined with other as a file path.
|
|
197
|
+
#
|
|
198
|
+
# @api public
|
|
199
|
+
def /(other)
|
|
200
|
+
File.join(self, other.to_s)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Calculate a relative path *from* _other_.
|
|
204
|
+
#
|
|
205
|
+
# @example
|
|
206
|
+
# '/opt/chefdk/'.relative_path_from '/opt/chefdk/embedded/bin' # => '../..'
|
|
207
|
+
#
|
|
208
|
+
# @param [String] other
|
|
209
|
+
# Base path to calculate *from*.
|
|
210
|
+
#
|
|
211
|
+
# @return [String]
|
|
212
|
+
# Relative path from _other_ to receiver.
|
|
213
|
+
#
|
|
214
|
+
# @api public
|
|
215
|
+
def relative_path_from(other)
|
|
216
|
+
Pathname.new(self).relative_path_from(Pathname.new(other)).to_s
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Replace sequences of whitespace (including newlines) with either
|
|
220
|
+
# a single space or remove them entirely (according to param _spaced_)
|
|
221
|
+
#
|
|
222
|
+
# @example
|
|
223
|
+
# <<QUERY.compress_lines
|
|
224
|
+
# SELECT name
|
|
225
|
+
# FROM users
|
|
226
|
+
# QUERY => 'SELECT name FROM users'
|
|
227
|
+
#
|
|
228
|
+
# @param [Boolean] spaced (default=true)
|
|
229
|
+
# Determines whether returned string has whitespace collapsed or removed
|
|
230
|
+
#
|
|
231
|
+
# @return [String]
|
|
232
|
+
# Receiver with whitespace (including newlines) replaced
|
|
233
|
+
#
|
|
234
|
+
# @api public
|
|
235
|
+
def compress_lines(spaced = true)
|
|
236
|
+
split($/).map { |line| line.strip }.join(spaced ? ' ' : '')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Remove whitespace margin.
|
|
240
|
+
#
|
|
241
|
+
# @return [String]
|
|
242
|
+
# Receiver with whitespace margin removed.
|
|
243
|
+
#
|
|
244
|
+
# @api public
|
|
245
|
+
def margin(indicator = nil)
|
|
246
|
+
lines = self.dup.split($/)
|
|
247
|
+
|
|
248
|
+
min_margin = 0
|
|
249
|
+
lines.each do |line|
|
|
250
|
+
if line =~ /^(\s+)/ && (min_margin == 0 || $1.size < min_margin)
|
|
251
|
+
min_margin = $1.size
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
lines.map { |line| line.sub(/^\s{#{min_margin}}/, '') }.join($/)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Formats String for easy translation. Replaces an arbitrary number of
|
|
258
|
+
# values using numeric identifier replacement.
|
|
259
|
+
#
|
|
260
|
+
# @example
|
|
261
|
+
# "%s %s %s" % %w(one two three) # => 'one two three'
|
|
262
|
+
# "%3$s %2$s %1$s" % %w(one two three) # => 'three two one'
|
|
263
|
+
#
|
|
264
|
+
# @param [#to_s] values
|
|
265
|
+
# A list of values to translate and interpolate into receiver
|
|
266
|
+
#
|
|
267
|
+
# @return [String]
|
|
268
|
+
# Receiver translated with values translated and interpolated positionally
|
|
269
|
+
#
|
|
270
|
+
# @api public
|
|
271
|
+
def t(*values)
|
|
272
|
+
self.class::translate(self) % values.collect! do |value|
|
|
273
|
+
value.frozen? ? value : self.class::translate(value.to_s)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def clear; colorize(self, "\e[0m"); end
|
|
278
|
+
def erase_line; colorize(self, "\e[K"); end
|
|
279
|
+
def erase_char; colorize(self, "\e[P"); end
|
|
280
|
+
def bold; colorize(self, "\e[1m"); end
|
|
281
|
+
def dark; colorize(self, "\e[2m"); end
|
|
282
|
+
def underline; colorize(self, "\e[4m"); end
|
|
283
|
+
def blink; colorize(self, "\e[5m"); end
|
|
284
|
+
def reverse; colorize(self, "\e[7m"); end
|
|
285
|
+
def concealed; colorize(self, "\e[8m"); end
|
|
286
|
+
def black; colorize(self, "\e[0;30m"); end
|
|
287
|
+
def gray; colorize(self, "\e[1;30m"); end
|
|
288
|
+
def red; colorize(self, "\e[0;31m"); end
|
|
289
|
+
def magenta; colorize(self, "\e[1;31m"); end
|
|
290
|
+
def green; colorize(self, "\e[0;32m"); end
|
|
291
|
+
def olive; colorize(self, "\e[1;32m"); end
|
|
292
|
+
def yellow; colorize(self, "\e[0;33m"); end
|
|
293
|
+
def cream; colorize(self, "\e[1;33m"); end
|
|
294
|
+
def blue; colorize(self, "\e[0;34m"); end
|
|
295
|
+
def purple; colorize(self, "\e[1;34m"); end
|
|
296
|
+
def orange; colorize(self, "\e[0;35m"); end
|
|
297
|
+
def mustard; colorize(self, "\e[1;35m"); end
|
|
298
|
+
def cyan; colorize(self, "\e[0;36m"); end
|
|
299
|
+
def cyan2; colorize(self, "\e[1;36m"); end
|
|
300
|
+
def light_gray; colorize(self, "\e[2;37m"); end
|
|
301
|
+
def bright_red; colorize(self, "\e[1;41m"); end
|
|
302
|
+
def white; colorize(self, "\e[0;97m"); end
|
|
303
|
+
def on_black; colorize(self, "\e[40m"); end
|
|
304
|
+
def on_red; colorize(self, "\e[41m"); end
|
|
305
|
+
def on_green; colorize(self, "\e[42m"); end
|
|
306
|
+
def on_yellow; colorize(self, "\e[43m"); end
|
|
307
|
+
def on_blue; colorize(self, "\e[44m"); end
|
|
308
|
+
def on_magenta; colorize(self, "\e[45m"); end
|
|
309
|
+
def on_cyan; colorize(self, "\e[46m"); end
|
|
310
|
+
def on_white; colorize(self, "\e[47m"); end
|
|
311
|
+
def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
|
|
312
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
|
4
|
+
# License: Apache License, Version 2.0
|
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
class Struct
|
|
21
|
+
|
|
22
|
+
# Get or set state of object. You can think of #object_state as an in-code
|
|
23
|
+
# form of marshalling.
|
|
24
|
+
#
|
|
25
|
+
def object_state(data=nil)
|
|
26
|
+
if data
|
|
27
|
+
data.each_pair {|k,v| send(k.to_s + "=", v)}
|
|
28
|
+
else
|
|
29
|
+
data = {}
|
|
30
|
+
each_pair{|k,v| data[k] = v}
|
|
31
|
+
data
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Get a hash with names and values of all instance variables.
|
|
36
|
+
#
|
|
37
|
+
# @example
|
|
38
|
+
# class Foo < Struct.new(:name, :age, :gender); end
|
|
39
|
+
# f = Foo.new("Jill", 50, :female)
|
|
40
|
+
# f.attributes # => {:name => "Jill", :age => 50, :gender => :female}
|
|
41
|
+
#
|
|
42
|
+
# @return [Hash]
|
|
43
|
+
# Hash of instance variables in receiver, keyed by ivar name
|
|
44
|
+
def attributes
|
|
45
|
+
h = {}
|
|
46
|
+
each_pair { |key, value| h[key] = value }
|
|
47
|
+
h
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
|
4
|
+
# License: Apache License, Version 2.0
|
|
5
|
+
# Copyright: (C) 2014-2015 Stefano Harding
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
class Symbol
|
|
21
|
+
|
|
22
|
+
# Override this in a child if it cannot be dup'ed
|
|
23
|
+
#
|
|
24
|
+
# @return [Object]
|
|
25
|
+
def try_dup
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Since Symbol is immutable it cannot be duplicated.
|
|
30
|
+
# For this reason #try_dup returns +self+.
|
|
31
|
+
#
|
|
32
|
+
# :a.dup! #=> :a
|
|
33
|
+
#
|
|
34
|
+
def dup! ; self ; end
|
|
35
|
+
def dup? ; false ; end
|
|
36
|
+
def clone? ; false ; end
|
|
37
|
+
|
|
38
|
+
# Join with _o_ as a file path.
|
|
39
|
+
#
|
|
40
|
+
# @example
|
|
41
|
+
# :chef/'provider' # => 'chef/provider'
|
|
42
|
+
# :chef/ :provider # => 'chef/provider'
|
|
43
|
+
#
|
|
44
|
+
# @param [#to_s] other
|
|
45
|
+
# Path component(s) to join with receiver.
|
|
46
|
+
#
|
|
47
|
+
# @return [String]
|
|
48
|
+
# Receiver joined with other as a file path.
|
|
49
|
+
#
|
|
50
|
+
# @api public
|
|
51
|
+
def /(other)
|
|
52
|
+
File.join(self.to_s, other.to_s)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Symbol does not end in `!`, `=`, or `?`.
|
|
56
|
+
#
|
|
57
|
+
# :a.plain? #=> true
|
|
58
|
+
# :a?.plain? #=> false
|
|
59
|
+
# :a!.plain? #=> false
|
|
60
|
+
# :a=.plain? #=> false
|
|
61
|
+
#
|
|
62
|
+
def plain?
|
|
63
|
+
c = to_s[-1,1]
|
|
64
|
+
!(c == '=' || c == '?' || c == '!')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Alias for `#plain?` method. Likely this should have been the original
|
|
68
|
+
# and only name, but such is life.
|
|
69
|
+
alias_method :reader?, :plain?
|
|
70
|
+
|
|
71
|
+
# Symbol ends in `=`.
|
|
72
|
+
#
|
|
73
|
+
# :a=.setter? #=> true
|
|
74
|
+
# :a.setter? #=> false
|
|
75
|
+
#
|
|
76
|
+
def setter?
|
|
77
|
+
to_s[-1,1] == '='
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Alias for `#setter?` method. Likely this should have been the original
|
|
81
|
+
# and only name, but such is life.
|
|
82
|
+
alias_method :writer?, :setter?
|
|
83
|
+
|
|
84
|
+
# Symbol ends in `?`.
|
|
85
|
+
#
|
|
86
|
+
# :a?.query? #=> true
|
|
87
|
+
# :a.query? #=> false
|
|
88
|
+
#
|
|
89
|
+
def query?
|
|
90
|
+
to_s[-1,1] == '?'
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Symbol ends in `!`.
|
|
94
|
+
#
|
|
95
|
+
# :a!.bang? #=> true
|
|
96
|
+
# :a.bang? #=> false
|
|
97
|
+
#
|
|
98
|
+
def bang?
|
|
99
|
+
to_s[-1,1] == '!'
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Does a symbol have a "not" sign?
|
|
103
|
+
#
|
|
104
|
+
# "friend".to_sym.not? #=> false
|
|
105
|
+
# "~friend".to_sym.not? #=> true
|
|
106
|
+
#
|
|
107
|
+
def not?
|
|
108
|
+
self.to_s.slice(0,1) == '~'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Add a "not" sign to the front of a symbol.
|
|
112
|
+
#
|
|
113
|
+
# (~:friend) #=> :"~friend"
|
|
114
|
+
#
|
|
115
|
+
def ~@
|
|
116
|
+
if self.to_s.slice(0,1) == '~'
|
|
117
|
+
"#{self.to_s[1..-1]}".to_sym
|
|
118
|
+
else
|
|
119
|
+
"~#{self}".to_sym
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Generate a unique symbol.
|
|
124
|
+
#
|
|
125
|
+
# Symbol.generate #=> :"-1"
|
|
126
|
+
#
|
|
127
|
+
# If +key+ is given the new symbol will be prefixed with it.
|
|
128
|
+
#
|
|
129
|
+
# Symbol.generate(:foo) #=> :"foo-1"
|
|
130
|
+
#
|
|
131
|
+
def self.generate(key = nil)
|
|
132
|
+
key = key.to_sym if key
|
|
133
|
+
@symbol_generate_counter ||= {}
|
|
134
|
+
@symbol_generate_counter[key] ||= 0
|
|
135
|
+
num = @symbol_generate_counter[key] += 1
|
|
136
|
+
("#{key}-%X" % num).to_sym
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# This allows us to call obj(&:method) instead of obj { |i| i.method }
|
|
140
|
+
unless method_defined?(:to_proc)
|
|
141
|
+
def to_proc
|
|
142
|
+
proc { |obj, args| obj.send(self, *args) }
|
|
143
|
+
# lambda { |obj, args=nil| obj.send(self, *args) }
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Useful extension for &:symbol which makes it possible
|
|
148
|
+
# to pass arguments for method in block
|
|
149
|
+
#
|
|
150
|
+
# ['abc','','','def','ghi'].tap(&:delete.(''))
|
|
151
|
+
# #=> ['abc','def','ghi']
|
|
152
|
+
#
|
|
153
|
+
# [1,2,3].map(&:to_s.(2))
|
|
154
|
+
# #=> ['1','10','11']
|
|
155
|
+
#
|
|
156
|
+
# ['abc','cdef','xy','z','wwww'].select(&:size.() == 4)
|
|
157
|
+
# #=> ['cdef', 'wwww']
|
|
158
|
+
#
|
|
159
|
+
# ['abc','aaA','AaA','z'].count(&:upcase.().succ == 'AAB')
|
|
160
|
+
# #=> 2
|
|
161
|
+
#
|
|
162
|
+
# [%w{1 2 3 4 5},%w{6 7 8 9}].map(&:join.().length)
|
|
163
|
+
# #=> [5,4]
|
|
164
|
+
#
|
|
165
|
+
def call(*args, &block)
|
|
166
|
+
proc do |recv|
|
|
167
|
+
recv.__send__(self, *args, &block)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|