diff options
author | schneems <richard.schneeman@gmail.com> | 2013-08-15 22:47:13 -0500 |
---|---|---|
committer | schneems <richard.schneeman@gmail.com> | 2013-09-28 14:16:21 -0500 |
commit | dc7dd9a222cf45732b61604529a11483b7e91ce8 (patch) | |
tree | b80ada07f6b58d1f3a646dd64e0c022ca39b8b53 /lib/bundler/retry.rb | |
parent | 1f6805e60b0f655fb0b1907133f63b38778d7a44 (diff) | |
download | bundler-dc7dd9a222cf45732b61604529a11483b7e91ce8.tar.gz |
Retry fetch specs with `--retry`
This PR adds a general purpose Retry class that can be re-used where-ever retry code is needed!
It also allows you to call `bundle install --retry 3` which will attempt to connect to ruby gems 3 times before failing, and emit a warning message each time
Diffstat (limited to 'lib/bundler/retry.rb')
-rw-r--r-- | lib/bundler/retry.rb | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/bundler/retry.rb b/lib/bundler/retry.rb new file mode 100644 index 00000000..ff53ff54 --- /dev/null +++ b/lib/bundler/retry.rb @@ -0,0 +1,48 @@ +module Bundler + # General purpose class for retrying code that may fail + class Retry + attr_accessor :name, :max_attempts, :current_attempt + + def initialize(name, max_attempts = 1) + @name = name + @max_attempts = max_attempts + end + + def attempt(&block) + @current_attempt = 0 + @failed = false + @error = nil + while keep_trying? do + run(&block) + end + @result + end + alias :attempts :attempt + + private + def run(&block) + @failed = false + @current_attempt += 1 + @result = block.call + rescue => e + fail(e) + end + + def fail(e) + @failed = true + raise e if last_attempt? + return true unless name + Bundler.ui.warn "Retrying #{name} due to error (#{current_attempt.next}/#{max_attempts}): #{e.message}" + end + + def keep_trying? + return true if current_attempt.zero? + return false if last_attempt? + return true if @failed + end + + def last_attempt? + current_attempt >= max_attempts + end + end +end |