Module: Smash::CloudPowers::Helper

Instance Method Summary collapse

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'



33
34
35
36
37
38
39
# File 'lib/cloud_powers/helper.rb', line 33

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

  • Use .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


48
49
50
# File 'lib/cloud_powers/helper.rb', line 48

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.



55
56
57
# File 'lib/cloud_powers/helper.rb', line 55

def called_from
  File.expand_path(File.dirname($0))
end

#create_logger ⇒ Object

creates a default logger Notes:

* TODO: at least make this have overridable defaults


62
63
64
65
66
# File 'lib/cloud_powers/helper.rb', line 62

def create_logger
  logger = Logger.new(STDOUT)
  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

@&block (optional)

  • should modify the key and return that value so it can be used in the copy Returns
  • a copy of the given Array or Hash, with all Hash keys modified

Sample use:

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


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/cloud_powers/helper.rb', line 85

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



113
114
115
116
117
118
119
120
# File 'lib/cloud_powers/helper.rb', line 113

def format_error_message(error)
  begin
    [error.message, 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 @log_file path



124
125
126
# File 'lib/cloud_powers/helper.rb', line 124

def log_file
  @log_file ||= zfind('LOG_FILE')
end

#logger ⇒ Object

Returns An instance of Logger, cached as @logger



129
130
131
# File 'lib/cloud_powers/helper.rb', line 129

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
  • a copy of the given Array or Hash, with all Hash keys modified

Sample use:

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)


148
149
150
151
152
153
154
155
# File 'lib/cloud_powers/helper.rb', line 148

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] or Infinity(default) : The number of times the loop should be allowed to...well, loop, before a failed retry occurs.
  • &test : A predicate method or block of code that is callable is used to test if the block being retried is successful yet.
  • [] Sample usage:

check_stuff = lambda { |params| return true } smart_retry(3, check_stuff(params)) { do_stuff_that_needs_to_be_checked }



170
171
172
173
174
175
176
177
178
# File 'lib/cloud_powers/helper.rb', line 170

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_path(file = '') ⇒ Object

Gives the path from the project root to lib/tasks Parameters

  • [file] : name of a file Returns
  • path
  • If a file is given, it will have a '.rb' file extension
  • If no file is given, it will return the #task_require_path


187
188
189
190
# File 'lib/cloud_powers/helper.rb', line 187

def task_path(file = '')
  return task_require_path if file.empty?
  Pathname(__FILE__).parent.dirname + 'tasks' + to_ruby_file_name(file)
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] String
* Neither path nor file will have a file extension


198
199
200
201
# File 'lib/cloud_powers/helper.rb', line 198

def task_require_path(file_name = '')
  file = File.basename(file_name, File.extname(file_name))
  Pathname(__FILE__).parent.dirname + 'tasks' + file
end

#to_camel(var) ⇒ Object

Change strings into camelCase Parameters var String Returns String * givenString



207
208
209
210
211
212
# File 'lib/cloud_powers/helper.rb', line 207

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 hyphen-delimited-string Parameters var String Returns String * given-string



218
219
220
221
222
223
224
225
226
227
228
# File 'lib/cloud_powers/helper.rb', line 218

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 snake_case and add '@' at the front Parameters var String Returns String * @given_string



234
235
236
237
# File 'lib/cloud_powers/helper.rb', line 234

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 * givenString



243
244
245
246
# File 'lib/cloud_powers/helper.rb', line 243

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 * given_string.rb * includes ruby file extension * see #to_snake()



254
255
256
# File 'lib/cloud_powers/helper.rb', line 254

def to_ruby_file_name(name)
  name[/\.rb$/].nil? ? "#{to_snake(name)}.rb" : "#{to_snake(name)}"
end

#to_snake(var) ⇒ Object

Change strings into snake_case Parameters var String Returns String * given_string * will not have file extensions * see #to_ruby_file_name()



264
265
266
267
268
269
270
271
272
273
# File 'lib/cloud_powers/helper.rb', line 264

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 Hash

  • instanceId: 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 #symbolize_keys_with()


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/cloud_powers/helper.rb', line 284

def update_message_body(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

Returns:

  • (Boolean)


301
302
303
304
305
306
307
308
# File 'lib/cloud_powers/helper.rb', line 301

def valid_json?(json)
  begin
    JSON.parse(json)
    true
  rescue Exception => e
    false
  end
end

#valid_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


310
311
312
# File 'lib/cloud_powers/helper.rb', line 310

def valid_url?(url)
  url =~ /\A#{URI::regexp}\z/
end