ruby-progressbar 0.11.0 → 1.0.0rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +42 -0
  7. data/Guardfile +6 -0
  8. data/LICENSE +22 -0
  9. data/README.md +229 -63
  10. data/lib/progress_bar/base.rb +166 -0
  11. data/lib/progress_bar/components.rb +5 -0
  12. data/lib/progress_bar/components/bar.rb +44 -0
  13. data/lib/progress_bar/components/elapsed_timer.rb +20 -0
  14. data/lib/progress_bar/components/estimated_timer.rb +88 -0
  15. data/lib/progress_bar/components/progressable.rb +92 -0
  16. data/lib/progress_bar/components/timer.rb +64 -0
  17. data/lib/progress_bar/depreciable.rb +121 -0
  18. data/lib/progress_bar/format.rb +2 -0
  19. data/lib/progress_bar/format/base.rb +30 -0
  20. data/lib/progress_bar/format/molecule.rb +37 -0
  21. data/lib/progress_bar/formatter.rb +109 -0
  22. data/lib/progress_bar/length_calculator.rb +53 -0
  23. data/lib/progress_bar/running_average_calculator.rb +7 -0
  24. data/lib/progress_bar/time.rb +22 -0
  25. data/lib/progress_bar/version.rb +3 -0
  26. data/lib/progressbar.rb +8 -295
  27. data/lib/ruby-progressbar.rb +19 -0
  28. data/ruby-progressbar.gemspec +44 -0
  29. data/spec/progress_bar/base_spec.rb +434 -0
  30. data/spec/progress_bar/components/bar_spec.rb +198 -0
  31. data/spec/progress_bar/components/elapsed_timer_spec.rb +79 -0
  32. data/spec/progress_bar/components/estimated_timer_spec.rb +173 -0
  33. data/spec/progress_bar/components/progressable_spec.rb +30 -0
  34. data/spec/progress_bar/format/molecule_spec.rb +22 -0
  35. data/spec/progress_bar/running_average_calculator_spec.rb +11 -0
  36. data/spec/progress_bar/time_spec.rb +51 -0
  37. data/spec/spec_helper.rb +13 -0
  38. data/spec/support/focused.rb +7 -0
  39. data/spec/support/timecop.rb +19 -0
  40. metadata +170 -19
  41. data/GPL_LICENSE +0 -340
  42. data/RUBY_LICENSE +0 -53
  43. data/test.rb +0 -247
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ source/Gemfile.temp
5
+ coverage
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.3-p125@progressbar
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode # JRuby in 1.8 mode
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ruby-progressbar (1.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ ffi (1.0.11)
11
+ guard (1.0.0)
12
+ ffi (>= 0.5.0)
13
+ thor (~> 0.14.6)
14
+ guard-rspec (0.6.0)
15
+ guard (>= 0.10.0)
16
+ multi_json (1.0.4)
17
+ rspec (2.8.0)
18
+ rspec-core (~> 2.8.0)
19
+ rspec-expectations (~> 2.8.0)
20
+ rspec-mocks (~> 2.8.0)
21
+ rspec-core (2.8.0)
22
+ rspec-expectations (2.8.0)
23
+ diff-lcs (~> 1.1.2)
24
+ rspec-mocks (2.8.0)
25
+ simplecov (0.5.4)
26
+ multi_json (~> 1.0.3)
27
+ simplecov-html (~> 0.5.3)
28
+ simplecov-html (0.5.3)
29
+ thor (0.14.6)
30
+ timecop (0.3.5)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ bundler (~> 1.0)
37
+ guard (~> 1.0)
38
+ guard-rspec (~> 0.6)
39
+ rspec (~> 2.8)
40
+ ruby-progressbar!
41
+ simplecov (~> 0.5)
42
+ timecop (~> 0.3.5)
@@ -0,0 +1,6 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { 'spec' }
4
+ watch('spec/spec_helper.rb') { 'spec' }
5
+ end
6
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2011 The Kompanee - Jeff Felchner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,91 +1,257 @@
1
- # Ruby/ProgressBar: A Text Progress Bar Library for Ruby
1
+ Ruby/ProgressBar: A Text Progress Bar Library for Ruby
2
+ ================================
2
3
 
3
- Ruby/ProgressBar is a text progress bar library for Ruby.
4
- It can indicate progress with percentage, a progress bar,
5
- and estimated remaining time.
4
+ The **ultimate** text progress bar library for Ruby! It'll **SMASH YOU OVER THE HEAD** with a **PURE RUSH** of progress bar excitement!
6
5
 
7
- ## Examples
6
+ Don't miss out on what all the kids are talking about! If you want everyone to know that your gem or app can survive _in the cage_ then YOU WANT **RUBY-PROGRESSBAR**!
8
7
 
9
- % irb --simple-prompt -r progressbar
10
- >> pbar = ProgressBar.new("test", 100)
11
- => (ProgressBar: 0/100)
12
- >> 100.times {sleep(0.1); pbar.inc}; pbar.finish
13
- test: 100% |oooooooooooooooooooooooooooooooooooooooo| Time: 00:00:10
14
- => nil
8
+ ![The Cage](http://www.thekompanee.com/public_files/the-cage.png)
15
9
 
16
- >> pbar = ProgressBar.new("test", 100)
17
- => (ProgressBar: 0/100)
18
- >> (1..100).each{|x| sleep(0.1); pbar.set(x)}; pbar.finish
19
- test: 67% |oooooooooooooooooooooooooo | ETA: 00:00:03
10
+ Supported Rubies
11
+ --------------------------------
12
+ * MRI Ruby 1.8.7
13
+ * MRI Ruby 1.9.2
14
+ * MRI Ruby 1.9.3
15
+ * JRuby (in 1.8 compat mode)
16
+ * JRuby (in 1.9 compat mode)
20
17
 
21
- ## API
18
+ It's Better Than The Other 186,312 Progress Bar Libraries Because...
19
+ --------------------------------
20
+ * Full test suite [![Build Status](https://secure.travis-ci.org/jfelchner/ruby-progressbar.png?branch=master)](http://travis-ci.org/jfelchner/ruby-progressbar)
21
+ * Used by tons of other open source projects (which means we find out about bugs quickly)
22
+ * It's pretty [freakin' sweet](https://www.youtube.com/watch?v=On3IoVhf_GM)
23
+ * We have a road map of new features to make it even better
24
+ * And most importantly... our awesome [contributors](#contributors)
22
25
 
23
- - `ProgressBar#new(title, total, out = STDERR)`
26
+ Installation
27
+ --------------------------------
24
28
 
25
- Display the initial progress bar and return a
26
- ProgressBar object. _title_ specifies the title,
27
- and _total_ specifies the total cost of processing.
28
- Optional parameter _out_ specifies the output IO.
29
+ First:
29
30
 
30
- The display of the progress bar is updated when one or
31
- more percent is proceeded or one or more seconds are
32
- elapsed from the previous display.
31
+ gem install ruby-progressbar
33
32
 
34
- - `ProgressBar#inc(step = 1)`
33
+ Then in your script:
35
34
 
36
- Increase the internal counter by _step_ and update
37
- the display of the progress bar. Display the estimated
38
- remaining time on the right side of the bar. The counter
39
- does not go beyond the _total_.
35
+ require 'ruby-progressbar'
40
36
 
41
- - `ProgressBar#set(count)`
37
+ or in your Gemfile
42
38
 
43
- Set the internal counter to _count_ and update the
44
- display of the progress bar. Display the estimated
45
- remaining time on the right side of the bar. Raise if
46
- _count_ is a negative number or a number more than
47
- the _total_.
39
+ gem 'ruby-progressbar'
48
40
 
49
- - `ProgressBar#finish`
41
+ or from IRB
50
42
 
51
- Stop the progress bar and update the display of progress
52
- bar. Display the elapsed time on the right side of the bar.
53
- The progress bar always stops at 100% by the method.
43
+ irb -r 'ruby-progressbar'
54
44
 
55
- - `ProgressBar#halt`
45
+ Basic Usage
46
+ --------------------------------
56
47
 
57
- Stop the progress bar and update the display of progress
58
- bar. Display the elapsed time on the right side of the bar.
59
- The progress bar stops at the current percentage by the method.
48
+ ### Creation
60
49
 
61
- - `ProgressBar#format=`
50
+ It's simple to get started:
62
51
 
63
- Set the format for displaying a progress bar.
64
- Default: `"%-14s %3d%% %s %s"`.
52
+ ProgressBar.create
65
53
 
66
- - `ProgressBar#format_arguments=`
54
+ Creates a basic progress bar beginning at `0`, a total capacity of `100` and tells it to start.
67
55
 
68
- Set the methods for displaying a progress bar.
69
- Default: `[:title, :percentage, :bar, :stat]`.
56
+ Progress: | |
70
57
 
71
- - `ProgressBar#file_transfer_mode`
58
+ ### Marking Progress
72
59
 
73
- Use `:stat_for_file_transfer` instead of `:stat` to display
74
- transfered bytes and transfer rate.
60
+ Every call to `#increment` will advance the bar by `1`. Therefore:
75
61
 
62
+ 50.times { progressbar.increment }
76
63
 
77
- ReverseProgressBar class is also available. The
78
- functionality is identical to ProgressBar but the direction
79
- of the progress bar is just opposite.
64
+ Would output an advancing line which would end up here:
80
65
 
81
- ## Limitations
66
+ Progress: |=================================== |
82
67
 
83
- Since the progress is calculated by the proportion to the
84
- total cost of processing, Ruby/ProgressBar cannot be used if
85
- the total cost of processing is unknown in advance.
86
- Moreover, the estimation of remaining time cannot be
87
- accurately performed if the progress does not flow uniformly.
68
+ Advanced Usage
69
+ --------------------------------
88
70
 
89
- ---
71
+ ### Options
90
72
 
91
- [Satoru Takabayashi](http://namazu.org/~satoru/)
73
+ If you would like to customize your prompt, you can pass options when you call `.create`.
74
+
75
+ ProgressBar.create(:title => "Items", :starting_at => 20, :total => 200)
76
+
77
+ Will output:
78
+
79
+ Items: |======= |
80
+
81
+ The following are the list of options you can use:
82
+
83
+ * `:title` - _(Defaults to `Progress`)_ - The title of the progress bar.
84
+ * `:total` - _(Defaults to `100`)_ The total number of the items that can be completed.
85
+ * `:starting_at` - _(Defaults to `0`)_ The number of items that should be considered completed when the bar first starts. This is also the default number that the bar will be set to if `#reset` is called.
86
+ * `:progress_mark` - _(Defaults to `=`)_ The mark which indicates the amount of progress that has been made.
87
+ * `:format` - _(Defaults to `%t: |%B|`)_ The format string which determines how the bar is displayed. See [**Formatting**](#formatting) below.
88
+ * `:length` - _(Defaults to full width if possible, otherwise `80`)_ The preferred width of the entire progress bar including any format options.
89
+ * `:output` - _(Defaults to `STDOUT`)_ All output will be sent to this object. Can be any object which responds to `.print`.
90
+ * `:smoothing` - _(Defaults to `0.1`)_ See [**Smoothing Out Estimated Time Jitters**](#smoothing-out-estimated-time-jitters) below.
91
+
92
+ ### Changing Progress
93
+
94
+ * `#increment`: Will advance the bar's progress by `1` unit. This is the main way of progressing the bar.
95
+ * `#decrement`: Will retract the bar's progress by `1` unit.
96
+ * `#progress +=`: Will allow you to increment by a relative amount.
97
+ * `#progress -=`: Will allow you to decrement by a relative amount.
98
+ * `#progress=`: Will allow you to jump the amount of progress directly to whatever value you would like. _Note: This will almost always mess up your estimated time if you're using it._
99
+
100
+ ### Stopping
101
+
102
+ The bar can be stopped in four ways:
103
+
104
+ * `#finish`: Will stop the bar by completing it immediately. The current position will be advanced to the total.
105
+ * `#stop`: Will stop the bar by immediately cancelling it. The current position will remain where it is.
106
+ * `#pause`: Will stop the bar similar to `#stop` but will allow it to be restarted where it previously left off by calling `#resume`. _Note: Elapsed Time and Estimated Time will stop being affected while the bar is paused._
107
+ * `#reset`: Will stop the bar by resetting all information. The current position of the bar will be reset to where it began when it was created. _(eg if you passed `:starting_at => 5` when you created the bar, it would reset to `5` and not `0`)_
108
+
109
+ ### Finishing
110
+
111
+ * See `#finish` above.
112
+
113
+ _Note: The bar will be finished automatically if the current value ever becomes equal to the total._
114
+
115
+ ### Refreshing
116
+
117
+ * If you need to have the bar be redisplayed to give your users more of a "real-time" feel, you can call `#refresh` which will not affect the current position but will update the elapsed and estimated timers.
118
+
119
+ Formatting
120
+ --------------------------------
121
+
122
+ The format of the progress bar is extremely easy to customize. When you create the progress bar and pass the `:format` option, that string will be used to determine what the bar looks like.
123
+
124
+ The flags you can use in the format string are as follows:
125
+
126
+ * `%t`: Title
127
+ * `%a`: Elapsed (absolute) time
128
+ * `%e`: Estimated time (will fall back to `ETA: ??:??:??` when it exceeds `99:00:00`)
129
+ * `%E`: Estimated time (will fall back to `ETA: > 4 Days` when it exceeds `99:00:00`)
130
+ * `%f`: Force estimated time to be displayed even if it exceeds `99:00:00`
131
+ * `%p`: Percentage complete represented as a whole number (eg: `82`)
132
+ * `%P`: Percentage complete represented as a decimal number (eg: `82.33`)
133
+ * `%c`: Number of items currently completed
134
+ * `%C`: Total number of items to be completed
135
+ * `%B`: The full progress bar including 'incomplete' space (eg: `========== `)
136
+ * `%b`: Progress bar only (eg: `==========`)
137
+ * `%w`: Bar With Integrated Percentage (eg: `==== 75 ====`)
138
+ * `%i`: Display the incomplete space of the bar (this string will only contain whitespace eg: ` `)
139
+ * `%%`: A literal percent sign `%`
140
+
141
+ All values have an absolute length with the exception of the bar flags (eg `%B`, `%b`, etc) which will occupy any leftover space.
142
+ You can use as many bar flags as you'd like, but if you do weird things, weird things will happen; so be wary.
143
+
144
+ ### Example
145
+
146
+ If you would like a bar with the elapsed time on the left and the percentage complete followed by the title on the right, you'd do this:
147
+
148
+ ProgressBar.create(:format => '%a %B %p%% %t')
149
+
150
+ Which will output something like this:
151
+
152
+ Time: --:--:-- 0% Progress
153
+
154
+ Hard to see where the bar is? Just add your own end caps, whatever you'd like. Like so:
155
+
156
+ ProgressBar.create(:format => '%a <%B> %p%% %t')
157
+
158
+ Becomes:
159
+
160
+ Time: --:--:-- < > 0% Progress
161
+
162
+ Want to put an end cap on your bar? Nothing special, just use the bar flag `%b` combined with the incomplete space flag `%i` like so:
163
+
164
+ ProgressBar.create(:format => '%a |%b>>%i| %p%% %t', :starting_at => 10)
165
+
166
+ Becomes:
167
+
168
+ Time: --:--:-- |====>> | 10% Progress
169
+
170
+ Notice that the absolute length doesn't get any longer, the bar just shrinks to fill the remaining space.
171
+
172
+ ### Overriding the Length
173
+
174
+ By default, the progressbar will try to be as smart as possible about how wide it can be. Under most Unix systems, it should be as wide as the terminal will allow while still fitting on one line. If you wish to override this behavior, you can pass in the `:length` option when creating the bar like so:
175
+
176
+ ProgressBar.create(:length => 40)
177
+
178
+ Additionally, if you don't have access to the code calling the progressbar itself (say if you're using a gem like Fuubar), you can set the `RUBY_PROGRESS_BAR_LENGTH` environment variable and it will always override any other setting.
179
+
180
+ _Note: If the terminal width is less than 20 characters or ruby-progressbar is being used on a non-*nix system, the bar will default to an 80 character width._
181
+
182
+ ### Realtime Customization
183
+
184
+ The following items can be set at any time. Changes cause an immediate bar refresh so no other action is needed:
185
+
186
+ * `#progress_mark=`: Sets the string used to represent progress along the bar.
187
+ * `#title=`: Sets the string used to represent the items the bar is tracking (or I guess whatever else you want it to be).
188
+ * `#format(format_string)`: If you need to adjust the format that the bar uses when rendering itself, just pass in a string in the same format as describe [above](#formatting).
189
+
190
+ ## In The Weeds
191
+
192
+ This is some stuff that makes ruby-progressbar extra awesome, but for the most part it "Just Works" and you won't have to even know it's there, but if you're curious like us, here it is.
193
+
194
+ ### Times... They Are A Changin'
195
+
196
+ #### Smoothing Out Estimated Time Jitters
197
+
198
+ Sometimes when you're tracking progress, you could have some items which take significantly longer than others. When this is the case, the ETA gauge can vary wildly from increment to increment.
199
+
200
+ __RUBY PROGRESS BAR TO THE RESCUE!__
201
+
202
+ Thanks to [@L2G](https://github.com/L2G) and 'the maths' you can pass the `:smoothing` option when creating a new bar and it will use an exponentially smoothed average rather than a linear one. A value of `0.0` means no smoothing and is equivalent to the classic behavior. A value of `1.0` is the maximum amount of smoothing. Any values between those two are valid. `0.1` is the default.
203
+
204
+ ProgressBar.create(:smoothing => 0.6)
205
+
206
+ #### Time Mocking Support
207
+
208
+ When mocking time, the concept of when `now` is becomes distorted. You can imagine that because ruby-progressbar tracks elapsed and estimated times, if it used the mocked version of `now` the results would be very undesirable. Fortunately, if you use one of our supported Ruby time mocking libraries, your elapsed and estimated times will appear correctly no matter when your 'now' is. Currently supported are:
209
+
210
+ * [Timecop](https://github.com/jtrupiano/timecop)
211
+ * [Delorean](https://github.com/bebanjo/delorean)
212
+
213
+ Road Map
214
+ --------------------------------
215
+ We're planning on adding a bunch of really nice features to this gem over the next few weeks. We want to keep the simple usage simple but allow for powerful features if they're needed. Our `1.0` release is the first step in that direction.
216
+
217
+ Issues
218
+ --------------------------------
219
+
220
+ If you have problems, please create a [Github issue](https://github.com/nex3/ruby-progressbar/issues).
221
+
222
+ Credits
223
+ --------------------------------
224
+
225
+ ![thekompanee](http://www.thekompanee.com/public_files/kompanee-github-readme-logo.png)
226
+
227
+ ruby-progressbar is maintained by [The Kompanee, Ltd.](http://www.thekompanee.com)
228
+
229
+ The names and logos for The Kompanee are trademarks of The Kompanee, Ltd.
230
+
231
+ Contributors
232
+ --------------------------------
233
+ * [Lawrence Leonard "Larry" Gilbert](https://github.com/L2G)
234
+ * [Aleksei Gusev](https://github.com/hron)
235
+ * [Yves Senn](https://github.com/senny)
236
+ * [Nathan Weizenbaum](https://github.com/nex3)
237
+ * [Oleg Dashevskii](https://github.com/be9)
238
+ * [Chris Griego](https://github.com/cgriego)
239
+ * [Tim Harper](https://github.com/timcharper)
240
+ * [Chalo Fernandez](https://github.com/chalofa)
241
+ * [Laust Rud Jacobsen](https://github.com/rud)
242
+ * [Ryan Wood](https://github.com/ryanwood)
243
+ * [Jim Benton](https://github.com/jim)
244
+
245
+ Thanks
246
+ --------------------------------
247
+
248
+ Thanks to [@nex3](https://github.com/nex3) for giving us contributor access to the initial repo.
249
+ Thanks to Hiroyuki Iwatsuki for giving us access to the gem on [rubygems.org](http://rubygems.org) to allow us to push our new versions.
250
+
251
+ And a special thanks to [Satoru Takabayashi](http://namazu.org/~satoru/) who was the original author of the `progressbar` gem and who inspired us to do this rewrite.
252
+
253
+ License
254
+ --------------------------------
255
+
256
+ ruby-progressbar 1.0 is Copyright &copy; 2011-2012 The Kompanee. It is free software, and may be redistributed under the terms specified in the LICENSE file.
257
+ ruby-progressbar 0.9.0 is Copyright &copy; 2008 [Satoru Takabayashi](http://namazu.org/~satoru/)
@@ -0,0 +1,166 @@
1
+ class ProgressBar
2
+ class Base
3
+ include ProgressBar::LengthCalculator
4
+ include ProgressBar::Formatter
5
+ include ProgressBar::Depreciable
6
+
7
+ DEFAULT_OUTPUT_STREAM = STDOUT
8
+
9
+ def initialize(*args)
10
+ options = args.empty? ? {} : backwards_compatible_args_to_options_conversion(args)
11
+
12
+ self.output = options[:output] || DEFAULT_OUTPUT_STREAM
13
+
14
+ super(options)
15
+
16
+ @bar = Components::Bar.new(options)
17
+ @estimated_time = Components::EstimatedTimer.new(options)
18
+ @elapsed_time = Components::ElapsedTimer.new
19
+
20
+ start :at => options[:starting_at]
21
+ end
22
+
23
+ ###
24
+ # Starting The Bar
25
+ #
26
+ def start(options = {})
27
+ clear
28
+
29
+ with_update do
30
+ with_progressables(:start, options)
31
+ @elapsed_time.start
32
+ end
33
+ end
34
+
35
+ ###
36
+ # Updating The Bar's Progress
37
+ #
38
+ def decrement
39
+ with_update { with_progressables(:decrement) }
40
+ end
41
+
42
+ def increment
43
+ with_update { with_progressables(:increment) }
44
+ end
45
+
46
+ def progress=(new_progress)
47
+ with_update { with_progressables(:progress=, new_progress) }
48
+ end
49
+
50
+ ###
51
+ # Stopping The Bar
52
+ #
53
+ def finish
54
+ with_update { with_progressables(:finish) }
55
+ end
56
+
57
+ def pause
58
+ with_update { with_timers(:pause) }
59
+ end
60
+
61
+ def stop
62
+ with_update { with_timers(:stop) }
63
+ end
64
+
65
+ def resume
66
+ with_update { with_timers(:resume) }
67
+ end
68
+
69
+ def reset
70
+ with_update do
71
+ @bar.reset
72
+ with_timers(:reset)
73
+ end
74
+ end
75
+
76
+ def stopped?
77
+ @estimated_time.stopped? && @elapsed_time.stopped?
78
+ end
79
+
80
+ alias :paused? :stopped?
81
+
82
+ def finished?
83
+ @bar.progress == @bar.total
84
+ end
85
+
86
+ ###
87
+ # UI Updates
88
+ #
89
+ def progress_mark=(mark)
90
+ with_update { @bar.progress_mark = mark }
91
+ end
92
+
93
+ def title=(title)
94
+ with_update { super }
95
+ end
96
+
97
+ ###
98
+ # Output
99
+ #
100
+ def clear
101
+ output.print clear_string
102
+ end
103
+
104
+ def refresh
105
+ update
106
+ end
107
+
108
+ def to_s(format_string = nil)
109
+ format_string ||= @format_string
110
+
111
+ format(format_string)
112
+ end
113
+
114
+ def inspect
115
+ "#<ProgressBar:#{progress}/#{total}>"
116
+ end
117
+
118
+ private
119
+ attr_accessor :output
120
+
121
+ def clear_string
122
+ "#{" " * length}\r"
123
+ end
124
+
125
+ def with_progressables(action, *args)
126
+ if args.empty?
127
+ @bar.send(action)
128
+ @estimated_time.send(action)
129
+ else
130
+ @bar.send(action, *args)
131
+ @estimated_time.send(action, *args)
132
+ end
133
+ end
134
+
135
+ def with_timers(action, *args)
136
+ if args.empty?
137
+ @estimated_time.send(action)
138
+ @elapsed_time.send(action)
139
+ else
140
+ @estimated_time.send(action, *args)
141
+ @elapsed_time.send(action, *args)
142
+ end
143
+ end
144
+
145
+ def with_update
146
+ yield
147
+ update
148
+ end
149
+
150
+ def update
151
+ with_timers(:stop) if finished?
152
+
153
+ if length_changed?
154
+ clear
155
+ reset_length
156
+ end
157
+
158
+ output.print self.to_s + eol
159
+ output.flush
160
+ end
161
+
162
+ def eol
163
+ finished? || stopped? ? "\n" : "\r"
164
+ end
165
+ end
166
+ end