Attempt a series of dependent nested tasks and cleanly handle errors.
@api private
@!attribute [r] status
@return [Symbol] The status of this task
# File lib/r10k/util/attempt.rb, line 21 def initialize(initial, opts = {}) @initial = initial @tries = [] @status = :notrun setopts(opts, {:trace => :self}) end
# File lib/r10k/util/attempt.rb, line 52 def ok? @status == :ok end
Run this attempt to completion.
@todo determine the structure of the ret @return [Object] The aggregate result of all work performed.
# File lib/r10k/util/attempt.rb, line 32 def run @status = :running result = apply(@initial, @tries) @status = :ok if @status == :running result end
Add another action to take for this attempt
@yieldparam [Object] The result of the previous action. @yieldreturn [Object, Array<Object>, NilClass] The result of this action.
If the value is an object, it will be passed to the next attempt. If the value is an Array then each element will be individually passed to the next try. If the value is false or nil then no further action will be taken.
# File lib/r10k/util/attempt.rb, line 47 def try(&block) @tries << block self end
# File lib/r10k/util/attempt.rb, line 58 def apply(input, tries) return input if tries.empty? case input when Array apply_all(input, tries) when NilClass, FalseClass input else apply_one(input, tries) end end
# File lib/r10k/util/attempt.rb, line 71 def apply_all(values, tries) values.map { |v| apply_one(v, tries) } end
# File lib/r10k/util/attempt.rb, line 75 def apply_one(value, tries) apply(tries.first.call(value), tries.drop(1)) rescue => e @status = :failed logger.error R10K::Errors::Formatting.format_exception(e, @trace) e end