visionmedia-commander 2.4.6 → 2.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +6 -0
- data/Manifest +2 -1
- data/Rakefile +1 -1
- data/Todo.rdoc +7 -0
- data/bin/commander +2 -2
- data/commander.gemspec +3 -3
- data/lib/commander/command.rb +5 -5
- data/lib/commander/core_ext/string.rb +4 -3
- data/lib/commander/runner.rb +1 -1
- data/lib/commander/user_interaction.rb +93 -57
- data/lib/commander/version.rb +1 -4
- data/spec/core_ext/string_spec.rb +25 -0
- metadata +4 -3
- data/spec/core_ext_spec.rb +0 -9
data/History.rdoc
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
|
2
|
+
=== 2.5.5 / 2009-03-06
|
3
|
+
|
4
|
+
* Replaced Commander::VERSION::STRING with Commander::VERSION (for release gem)
|
5
|
+
* Refactored progress bar
|
6
|
+
* Fixed String#tokenize
|
7
|
+
|
2
8
|
=== 2.4.5 / 2009-03-03
|
3
9
|
|
4
10
|
* Fixed bug which was not allowing switch arguments which are strings
|
data/Manifest
CHANGED
@@ -22,13 +22,14 @@ Manifest
|
|
22
22
|
Rakefile
|
23
23
|
README.rdoc
|
24
24
|
spec/commander_spec.rb
|
25
|
-
spec/
|
25
|
+
spec/core_ext/string_spec.rb
|
26
26
|
spec/help_formatter_spec.rb
|
27
27
|
spec/spec_helper.rb
|
28
28
|
tasks/docs.rake
|
29
29
|
tasks/gemspec.rake
|
30
30
|
tasks/spec.rake
|
31
31
|
test/fileutils.rb
|
32
|
+
test/names.rb
|
32
33
|
test/progress.rb
|
33
34
|
test/ui.rb
|
34
35
|
Todo.rdoc
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
%w( rubygems rake echoe ./lib/commander.rb ).each { |lib| require lib }
|
3
3
|
|
4
|
-
Echoe.new("commander", Commander::VERSION
|
4
|
+
Echoe.new("commander", Commander::VERSION) do |p|
|
5
5
|
p.author = "TJ Holowaychuk"
|
6
6
|
p.email = "tj@vision-media.ca"
|
7
7
|
p.summary = "The complete solution for Ruby command-line executables"
|
data/Todo.rdoc
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
|
2
|
+
* Fix stupid #program error output
|
3
|
+
* mixins like c.use Commander::TraceOption ? ...
|
4
|
+
* add configuration management like release gem
|
5
|
+
* test bool switches --[no-]-foo ... document
|
6
|
+
* Add option defaults when null / revisit OpenStruct population
|
7
|
+
* Refactor specs / improve testing
|
8
|
+
* Add option copying / merging capabilities
|
2
9
|
* Fix issue with having command name in the args list, #args_without_command
|
3
10
|
* Add optional command to be executed when none is specified
|
4
11
|
* Add aliasing of commands / args / options
|
data/bin/commander
CHANGED
@@ -4,7 +4,7 @@ require 'rubygems'
|
|
4
4
|
require 'commander'
|
5
5
|
|
6
6
|
program :name, 'commander'
|
7
|
-
program :version, Commander::VERSION
|
7
|
+
program :version, Commander::VERSION
|
8
8
|
program :description, 'Commander utility program.'
|
9
9
|
|
10
10
|
command :init do |c|
|
@@ -27,7 +27,7 @@ require 'commander'
|
|
27
27
|
require '#{name}'
|
28
28
|
|
29
29
|
program :name, '#{name}'
|
30
|
-
program :version, #{name.camelcase}::VERSION
|
30
|
+
program :version, #{name.camelcase}::VERSION
|
31
31
|
program :description, '#{description}'
|
32
32
|
|
33
33
|
CODE
|
data/commander.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{commander}
|
5
|
-
s.version = "2.
|
5
|
+
s.version = "2.5.6"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["TJ Holowaychuk"]
|
9
|
-
s.date = %q{2009-03-
|
9
|
+
s.date = %q{2009-03-06}
|
10
10
|
s.default_executable = %q{commander}
|
11
11
|
s.description = %q{The complete solution for Ruby command-line executables}
|
12
12
|
s.email = %q{tj@vision-media.ca}
|
13
13
|
s.executables = ["commander"]
|
14
14
|
s.extra_rdoc_files = ["bin/commander", "lib/commander/command.rb", "lib/commander/core_ext/array.rb", "lib/commander/core_ext/kernel.rb", "lib/commander/core_ext/object.rb", "lib/commander/core_ext/string.rb", "lib/commander/core_ext.rb", "lib/commander/fileutils.rb", "lib/commander/help_formatters/base.rb", "lib/commander/help_formatters/terminal/command_help.erb", "lib/commander/help_formatters/terminal/help.erb", "lib/commander/help_formatters/terminal.rb", "lib/commander/help_formatters.rb", "lib/commander/import.rb", "lib/commander/runner.rb", "lib/commander/user_interaction.rb", "lib/commander/version.rb", "lib/commander.rb", "README.rdoc", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
|
15
|
-
s.files = ["bin/commander", "commander.gemspec", "History.rdoc", "lib/commander/command.rb", "lib/commander/core_ext/array.rb", "lib/commander/core_ext/kernel.rb", "lib/commander/core_ext/object.rb", "lib/commander/core_ext/string.rb", "lib/commander/core_ext.rb", "lib/commander/fileutils.rb", "lib/commander/help_formatters/base.rb", "lib/commander/help_formatters/terminal/command_help.erb", "lib/commander/help_formatters/terminal/help.erb", "lib/commander/help_formatters/terminal.rb", "lib/commander/help_formatters.rb", "lib/commander/import.rb", "lib/commander/runner.rb", "lib/commander/user_interaction.rb", "lib/commander/version.rb", "lib/commander.rb", "Manifest", "Rakefile", "README.rdoc", "spec/commander_spec.rb", "spec/
|
15
|
+
s.files = ["bin/commander", "commander.gemspec", "History.rdoc", "lib/commander/command.rb", "lib/commander/core_ext/array.rb", "lib/commander/core_ext/kernel.rb", "lib/commander/core_ext/object.rb", "lib/commander/core_ext/string.rb", "lib/commander/core_ext.rb", "lib/commander/fileutils.rb", "lib/commander/help_formatters/base.rb", "lib/commander/help_formatters/terminal/command_help.erb", "lib/commander/help_formatters/terminal/help.erb", "lib/commander/help_formatters/terminal.rb", "lib/commander/help_formatters.rb", "lib/commander/import.rb", "lib/commander/runner.rb", "lib/commander/user_interaction.rb", "lib/commander/version.rb", "lib/commander.rb", "Manifest", "Rakefile", "README.rdoc", "spec/commander_spec.rb", "spec/core_ext/string_spec.rb", "spec/help_formatter_spec.rb", "spec/spec_helper.rb", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake", "test/fileutils.rb", "test/names.rb", "test/progress.rb", "test/ui.rb", "Todo.rdoc"]
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.homepage = %q{http://github.com/visionmedia/commander}
|
18
18
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Commander", "--main", "README.rdoc"]
|
data/lib/commander/command.rb
CHANGED
@@ -52,10 +52,10 @@ module Commander
|
|
52
52
|
# contains the results of this option. This handles common formats such as:
|
53
53
|
#
|
54
54
|
# -h, --help options.help # => bool
|
55
|
-
# --[
|
55
|
+
# --[no-]feature options.feature # => bool
|
56
56
|
# --large-switch options.large_switch # => bool
|
57
57
|
# --file FILE options.file # => file passed
|
58
|
-
# --list
|
58
|
+
# --list WORDS options.list # => array
|
59
59
|
# --date [DATE] options.date # => date or nil when optional argument not set
|
60
60
|
#
|
61
61
|
# === Examples:
|
@@ -64,8 +64,8 @@ module Commander
|
|
64
64
|
# c.option '--recursive', 'Do something recursively'
|
65
65
|
# c.option '--file FILE', 'Specify a file'
|
66
66
|
# c.option('--info', 'Display info') { puts "handle with block" }
|
67
|
-
# c.option '--[no]
|
68
|
-
# c.option '--list
|
67
|
+
# c.option '--[no-]feature', 'With or without feature'
|
68
|
+
# c.option '--list FILES', Array, 'List the files specified'
|
69
69
|
#
|
70
70
|
# c.when_called do |args, options|
|
71
71
|
# do_something_recursively if options.recursive
|
@@ -195,7 +195,7 @@ module Commander
|
|
195
195
|
end
|
196
196
|
|
197
197
|
def inspect #:nodoc:
|
198
|
-
"#<Command:#{@name}>"
|
198
|
+
"#<Commander::Command:#{@name}>"
|
199
199
|
end
|
200
200
|
|
201
201
|
private
|
@@ -4,14 +4,15 @@ class String
|
|
4
4
|
##
|
5
5
|
# Replace +hash+ keys with associated values. Mutative.
|
6
6
|
|
7
|
-
def tokenize! hash
|
8
|
-
hash.
|
7
|
+
def tokenize! hash = {}
|
8
|
+
hash.each { |k, v| gsub! /:#{k}/, v.to_s }
|
9
|
+
self
|
9
10
|
end
|
10
11
|
|
11
12
|
##
|
12
13
|
# Replace +hash+ keys with associated values.
|
13
14
|
|
14
|
-
def tokenize hash
|
15
|
+
def tokenize hash = {}
|
15
16
|
self.dup.tokenize! hash
|
16
17
|
end
|
17
18
|
|
data/lib/commander/runner.rb
CHANGED
@@ -178,7 +178,7 @@ module Commander
|
|
178
178
|
def create_default_commands
|
179
179
|
command :help do |c|
|
180
180
|
c.syntax = "command help <sub_command>"
|
181
|
-
c.summary = "Display help documentation"
|
181
|
+
c.summary = "Display help documentation for <sub_command>"
|
182
182
|
c.description = "Display help documentation for the global or sub commands"
|
183
183
|
c.example "Display global help", "command help"
|
184
184
|
c.example "Display help for 'foo'", "command help foo"
|
@@ -47,13 +47,14 @@ module Commander
|
|
47
47
|
#
|
48
48
|
# Terminal progress bar utility. In its most basic form
|
49
49
|
# requires that the developer specifies when the bar should
|
50
|
-
# be incremented
|
50
|
+
# be incremented. Note that a hash of tokens may be passed to
|
51
|
+
# #increment, (or returned when using Kernel#progress).
|
51
52
|
#
|
52
|
-
# uris = %w
|
53
|
+
# uris = %w(
|
53
54
|
# http://vision-media.ca
|
54
55
|
# http://yahoo.com
|
55
56
|
# http://google.com
|
56
|
-
#
|
57
|
+
# )
|
57
58
|
#
|
58
59
|
# bar = Commander::UI::ProgressBar.new uris.length, options
|
59
60
|
# threads = []
|
@@ -61,25 +62,19 @@ module Commander
|
|
61
62
|
# threads << Thread.new do
|
62
63
|
# begin
|
63
64
|
# res = open uri
|
64
|
-
# bar.
|
65
|
+
# bar.increment :uri => uri
|
65
66
|
# rescue Exception => e
|
66
|
-
# bar.
|
67
|
+
# bar.increment :uri => "#{uri} failed"
|
67
68
|
# end
|
68
69
|
# end
|
69
70
|
# end
|
70
71
|
# threads.each { |t| t.join }
|
71
72
|
#
|
72
|
-
# The Kernel method #progress is also available
|
73
|
-
# single and multi-threaded examples:
|
73
|
+
# The Kernel method #progress is also available:
|
74
74
|
#
|
75
75
|
# progress uris, :width => 10 do |uri|
|
76
76
|
# res = open uri
|
77
77
|
# end
|
78
|
-
#
|
79
|
-
# threads = uris.collect { |uri| Thread.new { res = open uri } }
|
80
|
-
# progress threads, :progress_char => '-' do |thread|
|
81
|
-
# thread.join
|
82
|
-
# end
|
83
78
|
#
|
84
79
|
|
85
80
|
class ProgressBar
|
@@ -91,8 +86,8 @@ module Commander
|
|
91
86
|
#
|
92
87
|
# :title Title, defaults to "Progress"
|
93
88
|
# :width Width of :progress_bar
|
94
|
-
# :
|
95
|
-
# :
|
89
|
+
# :progress_str Progress string, defaults to "="
|
90
|
+
# :incomplete_str Incomplete bar string, defaults to '.'
|
96
91
|
# :format Defaults to ":title |:progress_bar| :percent_complete% complete "
|
97
92
|
# :tokens Additional tokens replaced within the format string
|
98
93
|
# :complete_message Defaults to "Process complete"
|
@@ -102,88 +97,129 @@ module Commander
|
|
102
97
|
# :title
|
103
98
|
# :percent_complete
|
104
99
|
# :progress_bar
|
105
|
-
# :
|
106
|
-
# :
|
107
|
-
# :
|
108
|
-
# :output
|
100
|
+
# :step
|
101
|
+
# :steps_remaining
|
102
|
+
# :total_steps
|
109
103
|
# :time_elapsed
|
110
104
|
# :time_remaining
|
111
105
|
#
|
112
106
|
|
113
107
|
def initialize total, options = {}
|
114
|
-
@
|
115
|
-
@
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
108
|
+
@total_steps, @step, @start_time = total, 0, Time.now
|
109
|
+
@title = options.fetch :title, 'Progress'
|
110
|
+
@width = options.fetch :width, 25
|
111
|
+
@progress_str = options.fetch :progress_str, '='
|
112
|
+
@incomplete_str = options.fetch :incomplete_str, '.'
|
113
|
+
@complete_message = options.fetch :complete_message, 'Process complete'
|
114
|
+
@format = options.fetch :format, ':title |:progress_bar| :percent_complete% complete '
|
115
|
+
@tokens = options.fetch :tokens, {}
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Completion percentage.
|
120
|
+
|
121
|
+
def percent_complete
|
122
|
+
@step * 100 / @total_steps
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Time that has elapsed since the operation started.
|
127
|
+
|
128
|
+
def time_elapsed
|
129
|
+
Time.now - @start_time
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Estimated time remaining.
|
134
|
+
|
135
|
+
def time_remaining
|
136
|
+
(time_elapsed / @step) * steps_remaining
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# Number of steps left.
|
141
|
+
|
142
|
+
def steps_remaining
|
143
|
+
@total_steps - @step
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Formatted progress bar.
|
148
|
+
|
149
|
+
def progress_bar
|
150
|
+
(@progress_str * (@width * percent_complete / 100)).ljust @width, @incomplete_str
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Generates tokens for this step.
|
155
|
+
|
156
|
+
def generate_tokens
|
157
|
+
{
|
158
|
+
:title => @title,
|
159
|
+
:percent_complete => percent_complete,
|
160
|
+
:progress_bar => progress_bar,
|
161
|
+
:step => @step,
|
162
|
+
:steps_remaining => steps_remaining,
|
163
|
+
:total_steps => @total_steps,
|
164
|
+
:time_elapsed => "%0.2fs" % time_elapsed,
|
165
|
+
:time_remaining => "%0.2fs" % time_remaining,
|
166
|
+
}.
|
167
|
+
merge! @tokens
|
126
168
|
end
|
127
169
|
|
128
170
|
##
|
129
171
|
# Output the progress bar.
|
130
172
|
|
131
173
|
def show
|
132
|
-
|
174
|
+
# TODO: shift steps stack instead
|
175
|
+
unless finished?
|
133
176
|
erase_line
|
134
|
-
percent = (@current * 100) / @total
|
135
|
-
elapsed = Time.now - @start
|
136
|
-
remaining = @total - @current
|
137
|
-
tokens = {
|
138
|
-
:title => @options[:title],
|
139
|
-
:percent_complete => percent,
|
140
|
-
:progress_bar => (@options[:progress_char] * (@options[:width] * percent / 100)).ljust(@options[:width], @options[:incomplete_char]),
|
141
|
-
:current => @current,
|
142
|
-
:remaining => remaining,
|
143
|
-
:total => @total,
|
144
|
-
:time_elapsed => "%0.2fs" % [elapsed],
|
145
|
-
:time_remaining => "%0.2fs" % [(elapsed / @current) * remaining],
|
146
|
-
}.merge! @options[:tokens]
|
147
177
|
if completed?
|
148
|
-
|
178
|
+
puts @complete_message.tokenize(generate_tokens) if @complete_message.is_a? String
|
149
179
|
else
|
150
|
-
|
180
|
+
print @format.tokenize(generate_tokens)
|
181
|
+
$stdout.flush
|
151
182
|
end
|
152
183
|
end
|
153
184
|
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Weither or not the operation is complete, and we have finished.
|
188
|
+
|
189
|
+
def finished?
|
190
|
+
@step == @total_steps + 1
|
191
|
+
end
|
154
192
|
|
155
193
|
##
|
156
194
|
# Weither or not the operation has completed.
|
157
195
|
|
158
196
|
def completed?
|
159
|
-
@
|
197
|
+
@step == @total_steps
|
160
198
|
end
|
161
|
-
alias :finished? :completed?
|
162
199
|
|
163
200
|
##
|
164
201
|
# Increment progress. Optionally pass _tokens_ which
|
165
202
|
# can be displayed in the output format.
|
166
203
|
|
167
204
|
def increment tokens = {}
|
168
|
-
@
|
169
|
-
@
|
205
|
+
@step += 1
|
206
|
+
@tokens.merge! tokens if tokens.is_a? Hash
|
170
207
|
show
|
171
208
|
end
|
172
|
-
alias :inc :increment
|
173
209
|
|
174
210
|
##
|
175
211
|
# Erase previous terminal line.
|
176
212
|
|
177
213
|
def erase_line
|
178
|
-
|
214
|
+
print "\r\e[K"
|
179
215
|
end
|
180
216
|
|
181
217
|
##
|
182
|
-
# Output progress while iterating
|
218
|
+
# Output progress while iterating _arr_.
|
183
219
|
#
|
184
220
|
# === Example:
|
185
221
|
#
|
186
|
-
# uris = %
|
222
|
+
# uris = %w( http://vision-media.ca http://google.com )
|
187
223
|
# ProgressBar.progress uris, :format => "Remaining: :time_remaining" do |uri|
|
188
224
|
# res = open uri
|
189
225
|
# end
|
@@ -192,9 +228,9 @@ module Commander
|
|
192
228
|
#
|
193
229
|
# * Kernel#progress
|
194
230
|
|
195
|
-
def self.progress
|
196
|
-
bar = ProgressBar.new
|
197
|
-
|
231
|
+
def self.progress arr, options = {}, &block
|
232
|
+
bar = ProgressBar.new arr.length, options
|
233
|
+
arr.each { |v| bar.increment yield(v) }
|
198
234
|
end
|
199
235
|
|
200
236
|
end
|
data/lib/commander/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
describe String do
|
3
|
+
|
4
|
+
describe "#tokenize" do
|
5
|
+
it "should replace tokens within a string, with hash values" do
|
6
|
+
s = 'Welcome :name, enjoy your :object'.tokenize :name => 'TJ', :object => 'cookie'
|
7
|
+
s.should == 'Welcome TJ, enjoy your cookie'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should not mutate the string" do
|
11
|
+
s = 'Hey :msg'
|
12
|
+
s.tokenize :msg => 'there'
|
13
|
+
s.should_not == 'Hey there'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#tokenize!" do
|
18
|
+
it "should mutate the string while replacing tokens" do
|
19
|
+
s = 'Hey :msg'
|
20
|
+
s.tokenize! :msg => 'there'
|
21
|
+
s.should == 'Hey there'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: visionmedia-commander
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TJ Holowaychuk
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-03-
|
12
|
+
date: 2009-03-06 00:00:00 -08:00
|
13
13
|
default_executable: commander
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -76,13 +76,14 @@ files:
|
|
76
76
|
- Rakefile
|
77
77
|
- README.rdoc
|
78
78
|
- spec/commander_spec.rb
|
79
|
-
- spec/
|
79
|
+
- spec/core_ext/string_spec.rb
|
80
80
|
- spec/help_formatter_spec.rb
|
81
81
|
- spec/spec_helper.rb
|
82
82
|
- tasks/docs.rake
|
83
83
|
- tasks/gemspec.rake
|
84
84
|
- tasks/spec.rake
|
85
85
|
- test/fileutils.rb
|
86
|
+
- test/names.rb
|
86
87
|
- test/progress.rb
|
87
88
|
- test/ui.rb
|
88
89
|
- Todo.rdoc
|
data/spec/core_ext_spec.rb
DELETED