aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bundler/retry.rb
diff options
context:
space:
mode:
authorschneems <richard.schneeman@gmail.com>2013-08-15 22:47:13 -0500
committerschneems <richard.schneeman@gmail.com>2013-09-28 14:16:21 -0500
commitdc7dd9a222cf45732b61604529a11483b7e91ce8 (patch)
treeb80ada07f6b58d1f3a646dd64e0c022ca39b8b53 /lib/bundler/retry.rb
parent1f6805e60b0f655fb0b1907133f63b38778d7a44 (diff)
downloadbundler-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.rb48
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