visionmedia-commander 2.4.6 → 2.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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