gli 2.11.0 → 2.20.0
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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +28 -0
- data/.gitignore +3 -3
- data/.tool-versions +1 -0
- data/Gemfile +0 -2
- data/README.rdoc +29 -19
- data/Rakefile +15 -37
- data/bin/ci +29 -0
- data/bin/gli +24 -54
- data/bin/rake +29 -0
- data/bin/setup +5 -0
- data/exe/gli +68 -0
- data/gli.gemspec +20 -24
- data/gli.rdoc +9 -9
- data/lib/gli/app.rb +31 -8
- data/lib/gli/app_support.rb +15 -3
- data/lib/gli/command.rb +24 -2
- data/lib/gli/command_finder.rb +42 -25
- data/lib/gli/command_support.rb +7 -6
- data/lib/gli/commands/doc.rb +9 -3
- data/lib/gli/commands/help.rb +2 -1
- data/lib/gli/commands/help_modules/arg_name_formatter.rb +2 -2
- data/lib/gli/commands/help_modules/command_help_format.rb +19 -1
- data/lib/gli/commands/help_modules/full_synopsis_formatter.rb +3 -2
- data/lib/gli/commands/help_modules/global_help_format.rb +1 -1
- data/lib/gli/commands/help_modules/options_formatter.rb +4 -6
- data/lib/gli/commands/initconfig.rb +3 -6
- data/lib/gli/commands/rdoc_document_listener.rb +2 -1
- data/lib/gli/commands/scaffold.rb +71 -142
- data/lib/gli/dsl.rb +2 -1
- data/lib/gli/flag.rb +23 -2
- data/lib/gli/gli_option_parser.rb +66 -15
- data/lib/gli/option_parser_factory.rb +9 -2
- data/lib/gli/options.rb +2 -2
- data/lib/gli/switch.rb +4 -0
- data/lib/gli/terminal.rb +6 -2
- data/lib/gli/version.rb +1 -1
- data/lib/gli.rb +1 -0
- data/object-model.dot +29 -0
- data/object-model.png +0 -0
- data/test/apps/todo/Gemfile +1 -1
- data/test/apps/todo/bin/todo +12 -6
- data/test/apps/todo/lib/todo/commands/create.rb +42 -41
- data/test/apps/todo/lib/todo/commands/list.rb +48 -36
- data/test/apps/todo/lib/todo/commands/ls.rb +25 -24
- data/test/apps/todo/lib/todo/commands/make.rb +42 -39
- data/test/apps/todo/todo.gemspec +1 -2
- data/test/apps/todo_legacy/todo.gemspec +1 -2
- data/test/apps/todo_plugins/commands/third.rb +2 -0
- data/test/integration/gli_cli_test.rb +69 -0
- data/test/integration/gli_powered_app_test.rb +52 -0
- data/test/integration/scaffold_test.rb +30 -0
- data/test/integration/test_helper.rb +52 -0
- data/test/unit/command_finder_test.rb +54 -0
- data/test/{tc_command.rb → unit/command_test.rb} +20 -7
- data/test/unit/compound_command_test.rb +17 -0
- data/test/{tc_doc.rb → unit/doc_test.rb} +38 -51
- data/test/{tc_flag.rb → unit/flag_test.rb} +19 -25
- data/test/{tc_gli.rb → unit/gli_test.rb} +78 -50
- data/test/{tc_help.rb → unit/help_test.rb} +54 -113
- data/test/{tc_options.rb → unit/options_test.rb} +4 -4
- data/test/unit/subcommand_parsing_test.rb +263 -0
- data/test/unit/subcommands_test.rb +245 -0
- data/test/{config.yaml → unit/support/gli_test_config.yml} +1 -0
- data/test/unit/switch_test.rb +49 -0
- data/test/{tc_terminal.rb → unit/terminal_test.rb} +28 -3
- data/test/unit/test_helper.rb +13 -0
- data/test/unit/verbatim_wrapper_test.rb +24 -0
- metadata +85 -141
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -12
- data/ObjectModel.graffle +0 -1191
- data/bin/report_on_rake_results +0 -10
- data/bin/test_all_rubies.sh +0 -6
- data/features/gli_executable.feature +0 -90
- data/features/gli_init.feature +0 -232
- data/features/step_definitions/gli_executable_steps.rb +0 -18
- data/features/step_definitions/gli_init_steps.rb +0 -11
- data/features/step_definitions/todo_steps.rb +0 -100
- data/features/support/env.rb +0 -55
- data/features/todo.feature +0 -546
- data/features/todo_legacy.feature +0 -128
- data/test/option_test_helper.rb +0 -13
- data/test/tc_compound_command.rb +0 -22
- data/test/tc_subcommand_parsing.rb +0 -104
- data/test/tc_subcommands.rb +0 -259
- data/test/tc_switch.rb +0 -55
- data/test/tc_verbatim_wrapper.rb +0 -36
- data/test/test_helper.rb +0 -20
- /data/test/{init_simplecov.rb → unit/init_simplecov.rb} +0 -0
- /data/test/{fake_std_out.rb → unit/support/fake_std_out.rb} +0 -0
@@ -0,0 +1,245 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
require_relative "support/fake_std_out"
|
3
|
+
|
4
|
+
class SubcommandsTest < MiniTest::Test
|
5
|
+
include TestHelper
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@fake_stdout = FakeStdOut.new
|
9
|
+
@fake_stderr = FakeStdOut.new
|
10
|
+
|
11
|
+
@original_stdout = $stdout
|
12
|
+
$stdout = @fake_stdout
|
13
|
+
@original_stderr = $stderr
|
14
|
+
$stderr = @fake_stderr
|
15
|
+
|
16
|
+
@app = CLIApp.new
|
17
|
+
@app.reset
|
18
|
+
@app.subcommand_option_handling :legacy
|
19
|
+
@app.error_device=@fake_stderr
|
20
|
+
ENV.delete('GLI_DEBUG')
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
$stdout = @original_stdout
|
25
|
+
$stderr = @original_stderr
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_we_run_add_command_using_add
|
29
|
+
we_have_a_command_with_two_subcommands
|
30
|
+
run_app('remote',"add",'-f','foo','bar')
|
31
|
+
assert_command_ran_with(:add, :command_options => {:f => true}, :args => %w(foo bar))
|
32
|
+
end
|
33
|
+
def test_we_run_add_command_using_new
|
34
|
+
we_have_a_command_with_two_subcommands
|
35
|
+
run_app('remote',"new",'-f','foo','bar')
|
36
|
+
assert_command_ran_with(:add, :command_options => {:f => true}, :args => %w(foo bar))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_subcommands_not_used_on_command_line_uses_base_action
|
40
|
+
we_have_a_command_with_two_subcommands
|
41
|
+
run_app('remote','foo','bar')
|
42
|
+
assert_command_ran_with(:base, :command_options => {:f => false}, :args => %w(foo bar))
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_switches_and_flags_on_subcommand_available
|
46
|
+
we_have_a_command_with_two_subcommands(:switches => [:addswitch], :flags => [:addflag])
|
47
|
+
run_app('remote','add','--addswitch','--addflag','foo','bar')
|
48
|
+
assert_command_ran_with(:add,:command_options => { :addswitch => true, :addflag => 'foo', :f => false },
|
49
|
+
:args => ['bar'])
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_help_flag_works_in_normal_mode
|
53
|
+
@app.subcommand_option_handling :normal
|
54
|
+
we_have_a_command_with_two_subcommands
|
55
|
+
@app.run(["remote", "add", "--help"]) rescue nil
|
56
|
+
refute_match /^error/, @fake_stderr.to_s, "should not output an error message"
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_help_flag_works_in_legacy_mode
|
60
|
+
@app.subcommand_option_handling :legacy
|
61
|
+
we_have_a_command_with_two_subcommands
|
62
|
+
@app.run(["remote", "add", "--help"]) rescue nil
|
63
|
+
refute_match /^error/, @fake_stderr.to_s, "should not output an error message"
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_we_can_reopen_commands_to_add_new_subcommands
|
67
|
+
@app.command :remote do |p|
|
68
|
+
p.command :add do |c|
|
69
|
+
c.action do |global_options,command_options,args|
|
70
|
+
@ran_command = :add
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@app.command :remote do |p|
|
75
|
+
p.command :new do |c|
|
76
|
+
c.action do |global_options,command_options,args|
|
77
|
+
@ran_command = :new
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
run_app('remote','new')
|
82
|
+
assert_equal(@ran_command, :new)
|
83
|
+
run_app('remote', 'add')
|
84
|
+
assert_equal(@ran_command, :add)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_reopening_commands_doesnt_readd_to_output
|
88
|
+
@app.command :remote do |p|
|
89
|
+
p.command(:add) { }
|
90
|
+
end
|
91
|
+
@app.command :remote do |p|
|
92
|
+
p.command(:new) { }
|
93
|
+
end
|
94
|
+
command_names = @app.instance_variable_get("@commands_declaration_order").collect { |c| c.name }
|
95
|
+
assert_equal 1, command_names.grep(:remote).size
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def test_we_can_reopen_commands_without_causing_conflicts
|
100
|
+
@app.command :remote do |p|
|
101
|
+
p.command :add do |c|
|
102
|
+
c.action do |global_options,command_options,args|
|
103
|
+
@ran_command = :remote_add
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
@app.command :local do |p|
|
108
|
+
p.command :add do |c|
|
109
|
+
c.action do |global_options,command_options,args|
|
110
|
+
@ran_command = :local_add
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
run_app('remote','add')
|
115
|
+
assert_equal(@ran_command, :remote_add)
|
116
|
+
run_app('local', 'add')
|
117
|
+
assert_equal(@ran_command, :local_add)
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def test_we_can_nest_subcommands_very_deep
|
122
|
+
@run_results = { :add => nil, :rename => nil, :base => nil }
|
123
|
+
@app.command :remote do |c|
|
124
|
+
|
125
|
+
c.switch :f
|
126
|
+
c.command :add do |add|
|
127
|
+
add.command :some do |some|
|
128
|
+
some.command :cmd do |cmd|
|
129
|
+
cmd.switch :s
|
130
|
+
cmd.action do |global_options,command_options,args|
|
131
|
+
@run_results[:cmd] = [global_options,command_options,args]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
ENV['GLI_DEBUG'] = 'true'
|
138
|
+
run_app('remote','add','some','cmd','-s','blah')
|
139
|
+
assert_command_ran_with(:cmd, :command_options => {:s => true, :f => false},:args => ['blah'])
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_when_any_command_has_no_action_but_there_are_args_indicate_unknown_command
|
143
|
+
a_very_deeply_nested_command_structure
|
144
|
+
assert_raises GLI::UnknownCommand do
|
145
|
+
When run_app('remote','add','some','foo')
|
146
|
+
end
|
147
|
+
assert_match /Unknown command 'foo'/,@fake_stderr.to_s
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_when_any_command_has_no_action_but_there_are_no_args_indicate_subcommand_needed
|
151
|
+
a_very_deeply_nested_command_structure
|
152
|
+
assert_raises GLI::BadCommandLine do
|
153
|
+
When run_app('remote','add','some')
|
154
|
+
end
|
155
|
+
assert_match /Command 'some' requires a subcommand/,@fake_stderr.to_s
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def run_app(*args)
|
161
|
+
@exit_code = @app.run(args)
|
162
|
+
end
|
163
|
+
|
164
|
+
def a_very_deeply_nested_command_structure
|
165
|
+
@run_results = { :add => nil, :rename => nil, :base => nil }
|
166
|
+
@app.command :remote do |c|
|
167
|
+
|
168
|
+
c.switch :f
|
169
|
+
c.command :add do |add|
|
170
|
+
add.command :some do |some|
|
171
|
+
some.command :cmd do |cmd|
|
172
|
+
cmd.switch :s
|
173
|
+
cmd.action do |global_options,command_options,args|
|
174
|
+
@run_results[:cmd] = [global_options,command_options,args]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
ENV['GLI_DEBUG'] = 'true'
|
181
|
+
end
|
182
|
+
|
183
|
+
# expected_command - name of command exepcted to have been run
|
184
|
+
# options:
|
185
|
+
# - global_options => hash of expected options
|
186
|
+
# - command_options => hash of expected command options
|
187
|
+
# - args => array of expected args
|
188
|
+
def assert_command_ran_with(expected_command,options)
|
189
|
+
global_options = options[:global_options] || { :help => false }
|
190
|
+
@run_results.each do |command,results|
|
191
|
+
if command == expected_command
|
192
|
+
assert_equal(indifferent_hash(global_options),results[0])
|
193
|
+
assert_equal(indifferent_hash(options[:command_options]),results[1])
|
194
|
+
assert_equal(options[:args],results[2])
|
195
|
+
else
|
196
|
+
assert_nil results
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def indifferent_hash(possibly_nil_hash)
|
202
|
+
return {} if possibly_nil_hash.nil?
|
203
|
+
possibly_nil_hash.keys.each do |key|
|
204
|
+
if key.kind_of? Symbol
|
205
|
+
possibly_nil_hash[key.to_s] = possibly_nil_hash[key] unless possibly_nil_hash.has_key?(key.to_s)
|
206
|
+
elsif key.kind_of? String
|
207
|
+
possibly_nil_hash[key.to_sym] = possibly_nil_hash[key] unless possibly_nil_hash.has_key?(key.to_sym)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
possibly_nil_hash
|
211
|
+
end
|
212
|
+
|
213
|
+
# options -
|
214
|
+
# :flags => flags to add to :add
|
215
|
+
# :switiches => switiches to add to :add
|
216
|
+
def we_have_a_command_with_two_subcommands(options = {})
|
217
|
+
@run_results = { :add => nil, :rename => nil, :base => nil }
|
218
|
+
@app.command :remote do |c|
|
219
|
+
|
220
|
+
c.switch :f
|
221
|
+
|
222
|
+
c.desc "add a remote"
|
223
|
+
c.command [:add,:new] do |add|
|
224
|
+
|
225
|
+
Array(options[:flags]).each { |_| add.flag _ }
|
226
|
+
Array(options[:switches]).each { |_| add.switch _ }
|
227
|
+
add.action do |global_options,command_options,args|
|
228
|
+
@run_results[:add] = [global_options,command_options,args]
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
c.desc "rename a remote"
|
233
|
+
c.command :rename do |rename|
|
234
|
+
rename.action do |global_options,command_options,args|
|
235
|
+
@run_results[:rename] = [global_options,command_options,args]
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
c.action do |global_options,command_options,args|
|
240
|
+
@run_results[:base] = [global_options,command_options,args]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
ENV['GLI_DEBUG'] = 'true'
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class SwitchTest < MiniTest::Test
|
4
|
+
include TestHelper
|
5
|
+
|
6
|
+
def test_basics_simple
|
7
|
+
switch_with_names(:filename)
|
8
|
+
attributes_should_be_set
|
9
|
+
assert_equal(:filename,@cli_option.name)
|
10
|
+
assert_nil @cli_option.aliases
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_basics_kinda_complex
|
14
|
+
switch_with_names([:f])
|
15
|
+
attributes_should_be_set
|
16
|
+
assert_equal(:f,@cli_option.name)
|
17
|
+
assert_nil @cli_option.aliases
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_basics_complex
|
21
|
+
switch_with_names([:f,:file,:filename])
|
22
|
+
attributes_should_be_set
|
23
|
+
assert_equal(:f,@cli_option.name)
|
24
|
+
assert_equal([:file,:filename],@cli_option.aliases)
|
25
|
+
assert_equal ["-f","--[no-]file","--[no-]filename"],@switch.arguments_for_option_parser
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_includes_negatable
|
29
|
+
assert_equal '-a',GLI::Switch.name_as_string('a')
|
30
|
+
assert_equal '--[no-]foo',GLI::Switch.name_as_string('foo')
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def switch_with_names(names)
|
36
|
+
@options = {
|
37
|
+
:desc => 'Filename',
|
38
|
+
:long_desc => 'The Filename',
|
39
|
+
}
|
40
|
+
@switch = GLI::Switch.new(names,@options)
|
41
|
+
@cli_option = @switch
|
42
|
+
end
|
43
|
+
|
44
|
+
def attributes_should_be_set
|
45
|
+
assert_equal(@options[:desc],@switch.description)
|
46
|
+
assert_equal(@options[:long_desc],@switch.long_description)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
|
1
|
+
require_relative "test_helper"
|
2
2
|
|
3
|
-
class
|
3
|
+
class TerminalTest < MiniTest::Test
|
4
4
|
include TestHelper
|
5
5
|
|
6
|
-
|
6
|
+
# TODO: Make this test not mess with the internals of the class
|
7
|
+
def xtest_command_exists
|
7
8
|
assert GLI::Terminal.instance.command_exists?('ls')
|
8
9
|
assert !GLI::Terminal.instance.command_exists?('asdfasfasdf')
|
9
10
|
end
|
@@ -73,6 +74,30 @@ class TC_testTerminal < Clean::Test::TestCase
|
|
73
74
|
assert_equal [5678,1234],terminal.size
|
74
75
|
end
|
75
76
|
|
77
|
+
def test_size_using_stty_but_returns_0
|
78
|
+
terminal = GLI::Terminal.new
|
79
|
+
terminal.make_unsafe!
|
80
|
+
GLI::Terminal.instance_eval do
|
81
|
+
def run_command(command)
|
82
|
+
|
83
|
+
if RUBY_PLATFORM == 'java'
|
84
|
+
return '0' if command == 'tput cols'
|
85
|
+
return '0' if command == 'tput lines'
|
86
|
+
else
|
87
|
+
return '0 0' if command == 'stty size'
|
88
|
+
return '0 0' if command == 'stty'
|
89
|
+
end
|
90
|
+
|
91
|
+
raise "Unexpected command called: #{command} for #{RUBY_PLATFORM}"
|
92
|
+
end
|
93
|
+
def command_exists?(command); true; end
|
94
|
+
def jruby?; false; end
|
95
|
+
def solaris?; false; end
|
96
|
+
end
|
97
|
+
ENV['COLUMNS'] = 'foo'
|
98
|
+
assert_equal [80,24],terminal.size
|
99
|
+
end
|
100
|
+
|
76
101
|
def test_size_using_default
|
77
102
|
terminal = GLI::Terminal.new
|
78
103
|
terminal.make_unsafe!
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class TerminalTest < MiniTest::Test
|
4
|
+
include TestHelper
|
5
|
+
|
6
|
+
def test_handles_nil
|
7
|
+
@wrapper = GLI::Commands::HelpModules::VerbatimWrapper.new(rand(100),rand(100))
|
8
|
+
@result = @wrapper.wrap(nil)
|
9
|
+
assert_equal '',@result
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_does_not_touch_input
|
13
|
+
@wrapper = GLI::Commands::HelpModules::VerbatimWrapper.new(rand(100),rand(100))
|
14
|
+
@input = <<EOS
|
15
|
+
|This is|an ASCII|table|
|
16
|
+
+-------+--------+-----+
|
17
|
+
| foo | bar | baz |
|
18
|
+
+-------+--------+-----+
|
19
|
+
EOS
|
20
|
+
@result = @wrapper.wrap(@input)
|
21
|
+
assert_equal @input,@result
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|