Module: Smash::CloudPowers::Helper
- Included in:
- Smash::CloudPowers, AwsResources, Context, Delegator, Node, SelfAwareness, Synapse::Broadcast, Synapse::Pipe, Synapse::Queue, Synapse::Queue::Board, Zenv
- Defined in:
- lib/cloud_powers/helper.rb
Instance Method Summary collapse
-
#attr_map!(keys) ⇒ Object
Sets an Array of instance variables, individually to a value that a user given block returns.
-
#available_resources ⇒ Object
This is a way to find out if you are trying to work with a resource available to CloudPowers.
-
#called_from ⇒ Object
Does its best job at guessing where this method was called from, in terms of where it is located on the file system.
-
#create_logger(log_to = STDOUT) ⇒ Object
creates a default logger.
-
#deep_modify_keys_with(params) ⇒ Object
Allows you to modify all keys, including nested, with a block that you pass.
-
#format_error_message(error) ⇒ Object
Join the message and backtrace into a String with line breaks.
-
#log_file ⇒ Object
Gets the path from the environment and sets @log_file using the path.
-
#logger ⇒ Object
Returns An instance of Logger, cached as @logger@log_file path
. -
#modify_keys_with(params) ⇒ Object
Allows you to modify all first-level keys with a block that you pass.
-
#smart_retry(test, allowed_attempts = Float::INFINITY) ⇒ Object
Lets you retry a piece of logic with 1 second sleep in between attempts until another bit of logic does what it's supposed to, kind of like continuing to poll something and doing something when a package is ready to be taken and processed.
-
#task_exist?(file) ⇒ Boolean
Check if the task file exists in the task directory.
-
#task_home ⇒ Object
Gives a common home for tasks to live so they can be easily grouped and found.
-
#task_path(file = '') ⇒ Object
Gives the path from the project root to lib/tasks.
-
#task_require_path(file_name = '') ⇒ Object
Gives the path from the project root to lib/tasks.
-
#to_camel(var) ⇒ Object
Change strings into camelCase.
-
#to_hyph(var) ⇒ Object
Change strings into a hyphen delimited phrase.
-
#to_i_var(var) ⇒ Object
Change strings into an i-var format.
-
#to_pascal(var) ⇒ Object
Change strings into PascalCase.
-
#to_ruby_file_name(name) ⇒ Object
Change strings into a ruby_file_name with extension.
-
#to_snake(var) ⇒ Object
Change strings into PascalCase.
-
#update_message_body(opts = {}) ⇒ Object
This method provides a default overrideable message body for things like basic status updates.
-
#valid_json?(json) ⇒ Boolean
Predicate method to check if a String is parsable, as JSON.
-
#valid_url?(url) ⇒ Boolean
Predicate method to check if a String is a valid URL.
Instance Method Details
#attr_map!(keys) ⇒ Object
Sets an Array of instance variables, individually to a value that a user given block returns.
Parameters
-
keys
Array -
- each object will be used as the name for the instance variable that
your block returns
block(optional) - this block is called for each object in the Array and is used as the value for the instance variable that is being named and created for each key Returns Array
- each object will either be the result of
#instance_variable_set(key, value)or instance_variable_get(key) Example keys = ['foo', 'bar', 'yo']
attr_map!(keys) { |key| sleep 1; "#key:#Time.now.to_i" }
=> ['foo:1475434058', 'bar:1475434059', 'yo:1475434060']
puts @bar
=> 'bar:1475434059'
- each object will be used as the name for the instance variable that
your block returns
34 35 36 37 38 39 40 |
# File 'lib/cloud_powers/helper.rb', line 34 def attr_map!(keys) keys.map do |key| new_i_var = to_i_var(key) value = yield key if block_given? instance_variable_set(new_i_var, value) unless instance_variable_get(new_i_var) end end |
#available_resources ⇒ Object
This is a way to find out if you are trying to work with a resource available to CloudPowers
Returns .constants to find all the modules and classes available.
Notes
- TODO: make this smartly pick up all the objects, within reason and considering need, that we have access to
51 52 53 |
# File 'lib/cloud_powers/helper.rb', line 51 def available_resources [:Task].concat(Smash::CloudPowers.constants) end |
#called_from ⇒ Object
Does its best job at guessing where this method was called from, in terms of where it is located on the file system. It helps track down where a project root is etc.
Returns
String
Notes
- Uses
$0to figure out what the current file is
64 65 66 |
# File 'lib/cloud_powers/helper.rb', line 64 def called_from File.(File.dirname($0)) end |
#create_logger(log_to = STDOUT) ⇒ Object
creates a default logger
Parameters
- log_to
String(optional) - location to send logging information to; default is STDOUT
Returns
Logger
Notes
- TODO: at least make this have overridable defaults
78 79 80 81 82 |
# File 'lib/cloud_powers/helper.rb', line 78 def create_logger(log_to = STDOUT) logger = Logger.new(log_to) logger.datetime_format = '%Y-%m-%d %H:%M:%S' logger end |
#deep_modify_keys_with(params) ⇒ Object
Allows you to modify all keys, including nested, with a block that you pass. If no block is passed, a copy is returned.
Parameters
- params +Hash+|+Array+ - hash to be modified
block(optional) - a block to be used to modify each key should modify the key and return that value so it can be used in the copy
Returns +Hash+|+Array+ - a copy of the given Array or Hash, with all Hash keys modified
Example hash = { 'foo' => 'v1', 'bar' => { fleep: { 'florp' => 'yo' } } } modify_keys_with(hash) { |key| key.to_sym }
=> { foo: 'v1', bar: { fleep: { florp: 'yo' } } }
Notes
- see
#modify_keys_with()for handling first-level keys - see
#pass_the_buck()for the way nested structures are handled - case for different types taken from MultiXML (multi_xml.rb)
- TODO: look at optimization
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/cloud_powers/helper.rb', line 105 def deep_modify_keys_with(params) case params when Hash params.inject({}) do |carry, (k, v)| carry.tap do |h| if block_given? key = yield k value = if v.kind_of?(Hash) deep_modify_keys_with(v) { |new_key| Proc.new.call(new_key) } else v end h[key] = value else h[k] = v end end end when Array params.map{ |value| symbolize_keys(value) } else params end end |
#format_error_message(error) ⇒ Object
Join the message and backtrace into a String with line breaks
Parameters
- error
Exception
Returns
String
139 140 141 142 143 144 145 146 |
# File 'lib/cloud_powers/helper.rb', line 139 def (error) begin [error., error.backtrace.join("\n")].join("\n") rescue Exception => e # if the formatting won't work, return the original exception error end end |
#log_file ⇒ Object
Gets the path from the environment and sets @log_file using the path
Returns Notes
- See
#zfind()
155 156 157 |
# File 'lib/cloud_powers/helper.rb', line 155 def log_file @log_file ||= zfind('LOG_FILE') end |
#logger ⇒ Object
Returns An instance of Logger, cached as @logger@log_file path
Returns
Logger
Notes
- See
#create_logger
166 167 168 |
# File 'lib/cloud_powers/helper.rb', line 166 def logger @logger ||= create_logger end |
#modify_keys_with(params) ⇒ Object
Allows you to modify all first-level keys with a block that you pass. If no block is passed, a copy is returned.
Parameters
- params +Hash+|+Array+
- block (optional) - should modify the key and return that value so it can be used in the copy
Returns +Hash+|+Array+ - a copy of the given Array or Hash, with all Hash keys modified
Example hash = { 'foo' => 'v1', 'bar' => { fleep: { 'florp' => 'yo' } } } modify_keys_with(hash) { |k| k.to_sym }
=> { :foo => 'v1', :bar => { fleep: { 'florp' => 'yo' } } }
Notes
- see
#deep_modify_keys_with()for handling nested keys - case for different types taken from MultiXML (multi_xml.rb)
188 189 190 191 192 193 194 195 |
# File 'lib/cloud_powers/helper.rb', line 188 def modify_keys_with(params) params.inject({}) do |carry, (k, v)| carry.tap do |h| key = block_given? ? (yield k) : k h[key] = v end end end |
#smart_retry(test, allowed_attempts = Float::INFINITY) ⇒ Object
Lets you retry a piece of logic with 1 second sleep in between attempts until another bit of logic does what it's supposed to, kind of like continuing to poll something and doing something when a package is ready to be taken and processed.
Parameters
- allowed_attempts +Number+|+Infinity(default)+ - The number of times the loop should be allowed to...well, loop, before a failed retry occurs.
- &test
Block- A predicate method or block of code that is callable is used to test if the block being retried is successful yet. - []
Example check_stuff = lambda { |params| return true } smart_retry(3, check_stuff(params)) { do_stuff_that_needs_to_be_checked }
212 213 214 215 216 217 218 219 220 |
# File 'lib/cloud_powers/helper.rb', line 212 def smart_retry(test, allowed_attempts = Float::INFINITY) result = yield if block_given? tries = 1 until test.call(result) || tries >= allowed_attempts result = yield if block_given? tries += 1 sleep 1 end end |
#task_exist?(file) ⇒ Boolean
Check if the task file exists in the task directory
Parameters
- file
String
Returns
Boolean
Notes
- See
#task_home()
271 272 273 274 275 276 277 278 |
# File 'lib/cloud_powers/helper.rb', line 271 def task_exist?(file) begin File.new("#{task_home}/#{file}") true rescue Errno::ENOENT => e false end end |
#task_home ⇒ Object
Gives a common home for tasks to live so they can be easily grouped and found. This method will create nested directories, based on the #project_root() method and an additional 'lib/tasks' directory. If no project root has been set by the time this method is called, a new directory will be created relative to the gem's project root.
Returns
String
Notes
-
If no project root has been set by the time this method is called, a new
directory will be created relative to the gem's project root. This might have deeper implications than you want to deal with so it's always a good idea to set your project root as soon as you can. - TODO: find a way to have this method figure out the actual project's root, as opposed to just making common "good" assumptions.
238 239 240 241 |
# File 'lib/cloud_powers/helper.rb', line 238 def task_home string_th = FileUtils.mkdir_p("#{project_root}/lib/tasks/").first @task_home ||= Pathname.new(string_th).realpath.to_s end |
#task_path(file = '') ⇒ Object
Gives the path from the project root to lib/tasks
Parameters
- file
String(optional) (default is '') - name of a file
Returns
- path/file
Stringiffileparameter is given. return has '.rb' extension included - file
Stringiffileparameter is not given it will return the #task_require_path()
Notes
- See #task_home
255 256 257 258 |
# File 'lib/cloud_powers/helper.rb', line 255 def task_path(file = '') return task_home if file.empty? Pathname.new("#{task_home}/#{file}").to_s end |
#task_require_path(file_name = '') ⇒ Object
Gives the path from the project root to lib/tasks
Parameters String (optional)
- file_name name of a file
Returns
- path/file
Stringiffile_namewas given - path to task_directory if
file_namewas not given
Notes
- Neither path nor file will have a file extension
- See #task_home
292 293 294 295 296 297 298 299 |
# File 'lib/cloud_powers/helper.rb', line 292 def task_require_path(file_name = '') begin file_sans_extension = File.basename(file_name, '.*') (Pathname.new(task_home) + file_sans_extension).to_s rescue Errno::ENOENT => e nil end end |
#to_camel(var) ⇒ Object
Change strings into camelCase
Parameters
- var
String
Returns
String
308 309 310 311 312 313 |
# File 'lib/cloud_powers/helper.rb', line 308 def to_camel(var) var = var.to_s unless var.kind_of? String step_one = to_snake(var) step_two = to_pascal(step_one) step_two[0, 1].downcase + step_two[1..-1] end |
#to_hyph(var) ⇒ Object
Change strings into a hyphen delimited phrase
Parameters
- var
String
Returns
String
322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/cloud_powers/helper.rb', line 322 def to_hyph(var) var = var.to_s unless var.kind_of? String var.gsub(/:{2}|\//, '-'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). gsub(/\s+/, '-'). tr("_", "-"). gsub(/^\W/, ''). downcase end |
#to_i_var(var) ⇒ Object
Change strings into an i-var format
Parameters
- var
String
Returns
String
341 342 343 344 |
# File 'lib/cloud_powers/helper.rb', line 341 def to_i_var(var) var = var.to_s unless var.kind_of? String /^\W*@\w+/ =~ var ? to_snake(var) : "@#{to_snake(var)}" end |
#to_pascal(var) ⇒ Object
Change strings into PascalCase
Parameters
- var
String
Returns
String
353 354 355 356 |
# File 'lib/cloud_powers/helper.rb', line 353 def to_pascal(var) var = var.to_s unless var.kind_of? String var.gsub(/^(.{1})|\W.{1}|\_.{1}/) { |s| s.gsub(/[^a-z0-9]+/i, '').capitalize } end |
#to_ruby_file_name(name) ⇒ Object
Change strings into a ruby_file_name with extension
Parameters
- var
String
Returns
String
Notes
- given_string.rb
- includes ruby file extension
- see #to_snake()
370 371 372 |
# File 'lib/cloud_powers/helper.rb', line 370 def to_ruby_file_name(name) name[/\.rb$/].nil? ? "#{to_snake(name)}.rb" : "#{to_snake(name)}" end |
#to_snake(var) ⇒ Object
Change strings into PascalCase
Parameters
- var
String
Returns
String
Notes
- given_string
- will not have file extensions
- see #to_ruby_file_name()
386 387 388 389 390 391 392 393 394 395 |
# File 'lib/cloud_powers/helper.rb', line 386 def to_snake(var) var = var.to_s unless var.kind_of? String var.gsub(/:{2}|\//, '_'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). gsub(/\s+/, '_'). tr("-", "_"). downcase end |
#update_message_body(opts = {}) ⇒ Object
This method provides a default overrideable message body for things like basic status updates.
Parameters
- instanceId
Hash
Notes
- camel casing is used on the keys because most other languages prefer
that and it's not a huge problem in ruby. Besides, there's some other
handy methods in this module to get you through those issues, like
#to_snake()and or#modify_keys_with()
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'lib/cloud_powers/helper.rb', line 408 def (opts = {}) # TODO: Better implementation of merging message bodies and config needed unless opts.kind_of? Hash update = opts.to_s opts = {} opts[:extraInfo] = { message: update } end updated_extra_info = opts.delete(:extraInfo) || {} { instanceId: @instance_id || 'none-aquired', type: 'status-update', content: 'running', extraInfo: updated_extra_info }.merge(opts) end |
#valid_json?(json) ⇒ Boolean
Predicate method to check if a String is parsable, as JSON
Parameters
- json
String
Returns
Boolean
432 433 434 435 436 437 438 439 |
# File 'lib/cloud_powers/helper.rb', line 432 def valid_json?(json) begin JSON.parse(json) true rescue Exception => e false end end |
#valid_url?(url) ⇒ Boolean
Predicate method to check if a String is a valid URL
Parameters
- url
String
Returns
Boolean
448 449 450 |
# File 'lib/cloud_powers/helper.rb', line 448 def valid_url?(url) url =~ /\A#{URI::regexp}\z/ end |