ktec-commander 3.3.1
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 +275 -0
- data/Manifest +35 -0
- data/README.rdoc +357 -0
- data/Rakefile +16 -0
- data/bin/commander +55 -0
- data/commander.gemspec +76 -0
- data/lib/commander.rb +31 -0
- data/lib/commander/blank.rb +8 -0
- data/lib/commander/command.rb +210 -0
- data/lib/commander/core_ext.rb +3 -0
- data/lib/commander/core_ext/array.rb +25 -0
- data/lib/commander/core_ext/object.rb +11 -0
- data/lib/commander/delegates.rb +13 -0
- data/lib/commander/help_formatters.rb +8 -0
- data/lib/commander/help_formatters/base.rb +18 -0
- data/lib/commander/help_formatters/terminal.rb +20 -0
- data/lib/commander/help_formatters/terminal/command_help.erb +35 -0
- data/lib/commander/help_formatters/terminal/help.erb +37 -0
- data/lib/commander/help_formatters/terminal_compact.rb +12 -0
- data/lib/commander/help_formatters/terminal_compact/command_help.erb +27 -0
- data/lib/commander/help_formatters/terminal_compact/help.erb +30 -0
- data/lib/commander/import.rb +10 -0
- data/lib/commander/runner.rb +387 -0
- data/lib/commander/user_interaction.rb +422 -0
- data/lib/commander/version.rb +4 -0
- data/spec/command_spec.rb +125 -0
- data/spec/core_ext/array_spec.rb +14 -0
- data/spec/core_ext/object_spec.rb +20 -0
- data/spec/help_formatters/base_spec.rb +24 -0
- data/spec/help_formatters/terminal_spec.rb +66 -0
- data/spec/runner_spec.rb +326 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/ui_spec.rb +11 -0
- data/tasks/docs.rake +18 -0
- data/tasks/gemspec.rake +3 -0
- data/tasks/spec.rake +25 -0
- metadata +127 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
describe Array do
|
3
|
+
|
4
|
+
describe "#parse" do
|
5
|
+
it "should seperate a list of words into an array" do
|
6
|
+
Array.parse('just a test').should == ['just', 'a', 'test']
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should preserve escaped whitespace" do
|
10
|
+
Array.parse('just a\ test').should == ['just', 'a test']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
describe Object do
|
3
|
+
|
4
|
+
describe "#get_binding" do
|
5
|
+
it "should return the objects binding" do
|
6
|
+
lambda {}.get_binding.should be_instance_of(Binding)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#method_missing" do
|
11
|
+
it "should preserve its original behavior for missing methods" do
|
12
|
+
lambda { i_am_a_missing_method() }.should raise_error(NoMethodError)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should preserve its original behavior for missing variables" do
|
16
|
+
lambda { i_am_a_missing_variable }.should raise_error(NameError)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
describe Commander::HelpFormatter do
|
3
|
+
|
4
|
+
before :each do
|
5
|
+
mock_terminal
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should display global help using --help switch" do
|
9
|
+
run('--help').should == "Implement global help here\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should display global help using help command" do
|
13
|
+
run('help').should == "Implement global help here\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should display command help" do
|
17
|
+
run('help', 'test').should == "Implement help for test here\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should display command help using --help switch" do
|
21
|
+
run('--help', 'test').should == "Implement help for test here\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
describe Commander::HelpFormatter::Terminal do
|
3
|
+
|
4
|
+
before :each do
|
5
|
+
mock_terminal
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "global help" do
|
9
|
+
before :each do
|
10
|
+
new_command_runner 'help' do
|
11
|
+
command :'install gem' do |c|
|
12
|
+
c.syntax = 'foo install gem [options]'
|
13
|
+
c.summary = 'Install some gem'
|
14
|
+
end
|
15
|
+
end.run!
|
16
|
+
@global_help = @output.string
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "should display" do
|
20
|
+
it "the command name" do
|
21
|
+
@global_help.should include('install gem')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "the summary" do
|
25
|
+
@global_help.should include('Install some gem')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "command help" do
|
31
|
+
before :each do
|
32
|
+
new_command_runner 'help', 'install', 'gem' do
|
33
|
+
command :'install gem' do |c|
|
34
|
+
c.syntax = 'foo install gem [options]'
|
35
|
+
c.summary = 'Install some gem'
|
36
|
+
c.description = 'Install some gem, blah blah blah'
|
37
|
+
c.example 'one', 'two'
|
38
|
+
c.example 'three', 'four'
|
39
|
+
end
|
40
|
+
end.run!
|
41
|
+
@command_help = @output.string
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "should display" do
|
45
|
+
it "the command name" do
|
46
|
+
@command_help.should include('install gem')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "the description" do
|
50
|
+
@command_help.should include('Install some gem, blah blah blah')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "all examples" do
|
54
|
+
@command_help.should include('# one')
|
55
|
+
@command_help.should include('two')
|
56
|
+
@command_help.should include('# three')
|
57
|
+
@command_help.should include('four')
|
58
|
+
end
|
59
|
+
|
60
|
+
it "the syntax" do
|
61
|
+
@command_help.should include('foo install gem [options]')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/spec/runner_spec.rb
ADDED
@@ -0,0 +1,326 @@
|
|
1
|
+
|
2
|
+
describe Commander do
|
3
|
+
|
4
|
+
before :each do
|
5
|
+
$stderr = StringIO.new
|
6
|
+
mock_terminal
|
7
|
+
create_test_command
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#program" do
|
11
|
+
it "should set / get program information" do
|
12
|
+
program :name, 'test'
|
13
|
+
program(:name).should == 'test'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should allow arbitrary blocks of global help documentation" do
|
17
|
+
program :help, 'Copyright', 'TJ Holowaychuk'
|
18
|
+
program(:help)['Copyright'].should == 'TJ Holowaychuk'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise an error when required info has not been set" do
|
22
|
+
new_command_runner '--help'
|
23
|
+
program :version, ''
|
24
|
+
lambda { run! }.should raise_error(Commander::Runner::CommandError)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow aliases of help formatters" do
|
28
|
+
program :help_formatter, :compact
|
29
|
+
program(:help_formatter).should == Commander::HelpFormatter::TerminalCompact
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#command" do
|
34
|
+
it "should return a command instance when only the name is passed" do
|
35
|
+
command(:test).should be_instance_of(Commander::Command)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return nil when the command does not exist" do
|
39
|
+
command(:im_not_real).should be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#separate_switches_from_description" do
|
44
|
+
it "should seperate switches and description returning both" do
|
45
|
+
switches, description = *Commander::Runner.separate_switches_from_description('-h', '--help', 'display help')
|
46
|
+
switches.should == ['-h', '--help']
|
47
|
+
description.should == 'display help'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#switch_to_sym" do
|
52
|
+
it "should return a symbol based on the switch name" do
|
53
|
+
Commander::Runner.switch_to_sym('--trace').should == :trace
|
54
|
+
Commander::Runner.switch_to_sym('--foo-bar').should == :foo_bar
|
55
|
+
Commander::Runner.switch_to_sym('--[no-]feature"').should == :feature
|
56
|
+
Commander::Runner.switch_to_sym('--[no-]feature ARG').should == :feature
|
57
|
+
Commander::Runner.switch_to_sym('--file [ARG]').should == :file
|
58
|
+
Commander::Runner.switch_to_sym('--colors colors').should == :colors
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#alias_command" do
|
63
|
+
it "should alias a command" do
|
64
|
+
alias_command :foo, :test
|
65
|
+
command(:foo).should == command(:test)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should pass arguments passed to the alias when called" do
|
69
|
+
gem_name = ''
|
70
|
+
new_command_runner 'install', 'gem', 'commander' do
|
71
|
+
command :install do |c|
|
72
|
+
c.option '--gem-name NAME', 'Install a gem'
|
73
|
+
c.when_called { |_, options| gem_name = options.gem_name }
|
74
|
+
end
|
75
|
+
alias_command :'install gem', :install, '--gem-name'
|
76
|
+
end.run!
|
77
|
+
gem_name.should == 'commander'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#global_option" do
|
82
|
+
it "should be invoked when used in the args list" do
|
83
|
+
file = ''
|
84
|
+
new_command_runner 'test', '--config', 'foo' do
|
85
|
+
global_option('--config FILE') { |f| file = f }
|
86
|
+
end.run!
|
87
|
+
file.should == 'foo'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be inherited by commands" do
|
91
|
+
quiet = nil
|
92
|
+
new_command_runner 'foo', '--quiet' do
|
93
|
+
global_option('--quiet', 'Suppress output')
|
94
|
+
command :foo do |c|
|
95
|
+
c.when_called { |_, options| quiet = options.quiet }
|
96
|
+
end
|
97
|
+
end.run!
|
98
|
+
quiet.should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should be inherited by commands even when a block is present" do
|
102
|
+
quiet = nil
|
103
|
+
new_command_runner 'foo', '--quiet' do
|
104
|
+
global_option('--quiet', 'Suppress output') {}
|
105
|
+
command :foo do |c|
|
106
|
+
c.when_called { |_, options| quiet = options.quiet }
|
107
|
+
end
|
108
|
+
end.run!
|
109
|
+
quiet.should be_true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#remove_global_options" do
|
114
|
+
it "should description" do
|
115
|
+
options, args = [], []
|
116
|
+
options << { :switches => ['-t', '--trace'] }
|
117
|
+
options << { :switches => ['--help'] }
|
118
|
+
options << { :switches => ['--paths PATHS'] }
|
119
|
+
args << '-t'
|
120
|
+
args << '--help'
|
121
|
+
args << '--command'
|
122
|
+
args << '--command-with-arg' << 'rawr'
|
123
|
+
args << '--paths' << '"lib/**/*.js","spec/**/*.js"'
|
124
|
+
command_runner.remove_global_options options, args
|
125
|
+
args.should == ['--command', '--command-with-arg', 'rawr']
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "--trace" do
|
130
|
+
it "should display pretty errors by default" do
|
131
|
+
lambda {
|
132
|
+
new_command_runner 'foo' do
|
133
|
+
command(:foo) { |c| c.when_called { raise 'cookies!' } }
|
134
|
+
end.run!
|
135
|
+
}.should raise_error(SystemExit, /error: cookies!. Use --trace/)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should display callstack when using this switch" do
|
139
|
+
lambda {
|
140
|
+
new_command_runner 'foo', '--trace' do
|
141
|
+
command(:foo) { |c| c.when_called { raise 'cookies!' } }
|
142
|
+
end.run!
|
143
|
+
}.should raise_error(RuntimeError)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "--version" do
|
148
|
+
it "should output program version" do
|
149
|
+
run('--version').should == "test 1.2.3\n"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "--help" do
|
154
|
+
it "should not output an invalid command message" do
|
155
|
+
run('--help').should_not == "invalid command. Use --help for more information\n"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "with invalid options" do
|
160
|
+
it "should output an invalid option message" do
|
161
|
+
lambda {
|
162
|
+
run('test', '--invalid-option')
|
163
|
+
}.should raise_error(SystemExit, /invalid option: --invalid-option/)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "with invalid command passed" do
|
168
|
+
it "should output an invalid command message" do
|
169
|
+
lambda {
|
170
|
+
run('foo')
|
171
|
+
}.should raise_error(SystemExit, /invalid command. Use --help for more information/)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "with invalid command passed to help" do
|
176
|
+
it "should output an invalid command message" do
|
177
|
+
lambda {
|
178
|
+
run('help', 'does_not_exist')
|
179
|
+
}.should raise_error(SystemExit, /invalid command. Use --help for more information/)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "#valid_command_names_from" do
|
184
|
+
it "should return array of valid command names" do
|
185
|
+
command('foo bar') {}
|
186
|
+
command('foo bar foo') {}
|
187
|
+
command_runner.valid_command_names_from('foo', 'bar', 'foo').should == ['foo bar', 'foo bar foo']
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should return empty array when no possible command names exist" do
|
191
|
+
command_runner.valid_command_names_from('fake', 'command', 'name').should == []
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#command_name_from_args" do
|
196
|
+
it "should locate command within arbitrary arguments passed" do
|
197
|
+
new_command_runner '--help', '--arbitrary', 'test'
|
198
|
+
command_runner.command_name_from_args.should == 'test'
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should support multi-word commands" do
|
202
|
+
new_command_runner '--help', '--arbitrary', 'some', 'long', 'command', 'foo'
|
203
|
+
command('some long command') {}
|
204
|
+
command_runner.command_name_from_args.should == 'some long command'
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should match the longest possible command" do
|
208
|
+
new_command_runner '--help', '--arbitrary', 'foo', 'bar', 'foo'
|
209
|
+
command('foo bar') {}
|
210
|
+
command('foo bar foo') {}
|
211
|
+
command_runner.command_name_from_args.should == 'foo bar foo'
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should use the left-most command name when multiple are present" do
|
215
|
+
new_command_runner 'help', 'test'
|
216
|
+
command_runner.command_name_from_args.should == 'help'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe "#active_command" do
|
221
|
+
it "should resolve the active command" do
|
222
|
+
new_command_runner '--help', 'test'
|
223
|
+
command_runner.active_command.should be_instance_of(Commander::Command)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should resolve active command when invalid options are passed" do
|
227
|
+
new_command_runner '--help', 'test', '--arbitrary'
|
228
|
+
command_runner.active_command.should be_instance_of(Commander::Command)
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should return nil when the command is not found" do
|
232
|
+
new_command_runner 'foo'
|
233
|
+
command_runner.active_command.should be_nil
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "#default_command" do
|
238
|
+
it "should allow you to default any command when one is not explicitly passed" do
|
239
|
+
new_command_runner '--trace' do
|
240
|
+
default_command :test
|
241
|
+
command(:test).should_receive(:run).once
|
242
|
+
command_runner.active_command.should == command(:test)
|
243
|
+
end.run!
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should not prevent other commands from being called" do
|
247
|
+
new_command_runner 'foo', 'bar', '--trace' do
|
248
|
+
default_command :test
|
249
|
+
command(:'foo bar'){}
|
250
|
+
command(:'foo bar').should_receive(:run).once
|
251
|
+
command_runner.active_command.should == command(:'foo bar')
|
252
|
+
end.run!
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should not prevent longer commands to use the same words as the default" do
|
256
|
+
new_command_runner 'foo', 'bar', 'something'
|
257
|
+
default_command :'foo bar'
|
258
|
+
command(:'foo bar'){}
|
259
|
+
command(:'foo bar something'){}
|
260
|
+
command_runner.active_command.should == command(:'foo bar something')
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should allow defaulting of command aliases" do
|
264
|
+
new_command_runner '--trace' do
|
265
|
+
default_command :foobar
|
266
|
+
alias_command :foobar, :test
|
267
|
+
command(:test).should_receive(:run).once
|
268
|
+
end.run!
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
describe "should function correctly" do
|
273
|
+
it "when options are passed before the command name" do
|
274
|
+
new_command_runner '--verbose', 'test', 'foo', 'bar' do
|
275
|
+
@command.when_called do |args, options|
|
276
|
+
args.should == ['foo', 'bar']
|
277
|
+
options.verbose.should be_true
|
278
|
+
end
|
279
|
+
end.run!
|
280
|
+
end
|
281
|
+
|
282
|
+
it "when options are passed after the command name" do
|
283
|
+
new_command_runner 'test', '--verbose', 'foo', 'bar' do
|
284
|
+
@command.when_called do |args, options|
|
285
|
+
args.should == ['foo', 'bar']
|
286
|
+
options.verbose.should be_true
|
287
|
+
end
|
288
|
+
end.run!
|
289
|
+
end
|
290
|
+
|
291
|
+
it "when an argument passed is the same name as the command" do
|
292
|
+
new_command_runner 'test', '--verbose', 'foo', 'test', 'bar' do
|
293
|
+
@command.when_called do |args, options|
|
294
|
+
args.should == ['foo', 'test', 'bar']
|
295
|
+
options.verbose.should be_true
|
296
|
+
end
|
297
|
+
end.run!
|
298
|
+
end
|
299
|
+
|
300
|
+
it "when using multi-word commands" do
|
301
|
+
new_command_runner '--verbose', 'my', 'command', 'something', 'foo', 'bar' do
|
302
|
+
command('my command') { |c| c.option('--verbose') }
|
303
|
+
command_runner.command_name_from_args.should == 'my command'
|
304
|
+
command_runner.args_without_command_name.should == ['--verbose', 'something', 'foo', 'bar']
|
305
|
+
end.run!
|
306
|
+
end
|
307
|
+
|
308
|
+
it "when using multi-word commands with parts of the command name as arguments" do
|
309
|
+
new_command_runner '--verbose', 'my', 'command', 'something', 'my', 'command' do
|
310
|
+
command('my command') { |c| c.option('--verbose') }
|
311
|
+
command_runner.command_name_from_args.should == 'my command'
|
312
|
+
command_runner.args_without_command_name.should == ['--verbose', 'something', 'my', 'command']
|
313
|
+
end.run!
|
314
|
+
end
|
315
|
+
|
316
|
+
it "when using multi-word commands with other commands using the same words" do
|
317
|
+
new_command_runner '--verbose', 'my', 'command', 'something', 'my', 'command' do
|
318
|
+
command('my command') {}
|
319
|
+
command('my command something') { |c| c.option('--verbose') }
|
320
|
+
command_runner.command_name_from_args.should == 'my command something'
|
321
|
+
command_runner.args_without_command_name.should == ['--verbose', 'my', 'command']
|
322
|
+
end.run!
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|