gli 2.18.2 → 2.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +28 -0
  3. data/.gitignore +1 -3
  4. data/.tool-versions +1 -1
  5. data/Gemfile +0 -6
  6. data/README.rdoc +33 -23
  7. data/Rakefile +21 -37
  8. data/bin/ci +29 -0
  9. data/bin/gli +25 -64
  10. data/bin/rake +29 -0
  11. data/bin/setup +5 -0
  12. data/exe/gli +68 -0
  13. data/gli.gemspec +19 -22
  14. data/gli.rdoc +2 -2
  15. data/lib/gli/command_support.rb +2 -6
  16. data/lib/gli/commands/help_modules/arg_name_formatter.rb +2 -2
  17. data/lib/gli/commands/help_modules/command_help_format.rb +1 -1
  18. data/lib/gli/commands/help_modules/global_help_format.rb +1 -1
  19. data/lib/gli/commands/scaffold.rb +9 -93
  20. data/lib/gli/dsl.rb +1 -1
  21. data/lib/gli/options.rb +2 -2
  22. data/lib/gli/version.rb +1 -1
  23. data/object-model.dot +29 -0
  24. data/object-model.png +0 -0
  25. data/test/apps/todo/Gemfile +1 -1
  26. data/test/apps/todo/bin/todo +1 -1
  27. data/test/integration/gli_cli_test.rb +69 -0
  28. data/test/integration/gli_powered_app_test.rb +52 -0
  29. data/test/integration/scaffold_test.rb +30 -0
  30. data/test/integration/test_helper.rb +52 -0
  31. data/test/{tc_command_finder.rb → unit/command_finder_test.rb} +6 -6
  32. data/test/{tc_command.rb → unit/command_test.rb} +4 -4
  33. data/test/unit/compound_command_test.rb +17 -0
  34. data/test/{tc_doc.rb → unit/doc_test.rb} +38 -51
  35. data/test/{tc_flag.rb → unit/flag_test.rb} +19 -25
  36. data/test/{tc_gli.rb → unit/gli_test.rb} +28 -47
  37. data/test/{tc_help.rb → unit/help_test.rb} +48 -107
  38. data/test/{init_simplecov.rb → unit/init_simplecov.rb} +0 -0
  39. data/test/{tc_options.rb → unit/options_test.rb} +4 -4
  40. data/test/unit/subcommand_parsing_test.rb +263 -0
  41. data/test/unit/subcommands_test.rb +245 -0
  42. data/test/{fake_std_out.rb → unit/support/fake_std_out.rb} +0 -0
  43. data/test/{config.yaml → unit/support/gli_test_config.yml} +0 -0
  44. data/test/unit/switch_test.rb +49 -0
  45. data/test/{tc_terminal.rb → unit/terminal_test.rb} +4 -3
  46. data/test/unit/test_helper.rb +13 -0
  47. data/test/unit/verbatim_wrapper_test.rb +24 -0
  48. metadata +74 -139
  49. data/.ruby-gemset +0 -1
  50. data/.ruby-version +0 -1
  51. data/.travis.yml +0 -11
  52. data/ObjectModel.graffle +0 -1191
  53. data/bin/report_on_rake_results +0 -10
  54. data/bin/test_all_rubies.sh +0 -6
  55. data/features/gli_executable.feature +0 -90
  56. data/features/gli_init.feature +0 -235
  57. data/features/step_definitions/gli_executable_steps.rb +0 -18
  58. data/features/step_definitions/gli_init_steps.rb +0 -11
  59. data/features/step_definitions/todo_steps.rb +0 -100
  60. data/features/support/env.rb +0 -54
  61. data/features/todo.feature +0 -579
  62. data/features/todo_legacy.feature +0 -130
  63. data/test/option_test_helper.rb +0 -13
  64. data/test/tc_compound_command.rb +0 -22
  65. data/test/tc_subcommand_parsing.rb +0 -280
  66. data/test/tc_subcommands.rb +0 -259
  67. data/test/tc_switch.rb +0 -55
  68. data/test/tc_verbatim_wrapper.rb +0 -36
  69. data/test/test_helper.rb +0 -21
@@ -1,130 +0,0 @@
1
- Feature: The todo app is backwards compatible with legacy subcommand parsing
2
- As a user of GLI
3
- My apps with subcommands should support the old, legacy way, by default
4
-
5
- Background:
6
- Given I have GLI installed
7
- And GLI's libs are in my path
8
- And my terminal size is "80x24"
9
- And todo_legacy's bin directory is in my path
10
-
11
- Scenario: Help completion mode for subcommands
12
- When I successfully run `todo help -c list`
13
- Then the output should contain:
14
- """
15
- contexts
16
- tasks
17
- """
18
-
19
- Scenario: Help completion mode partial match for subcommands
20
- When I successfully run `todo help -c list con`
21
- Then the output should contain:
22
- """
23
- contexts
24
- """
25
-
26
- Scenario Outline: Getting Help for a top level command of todo
27
- # No idea why I have to do this again.
28
- Given todo_legacy's bin directory is in my path
29
- When I successfully run `todo <help_invocation>`
30
- Then the output should contain:
31
- """
32
- NAME
33
- list - List things, such as tasks or contexts
34
-
35
- SYNOPSIS
36
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg]
37
- todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
38
-
39
- DESCRIPTION
40
- List a whole lot of things that you might be keeping track of in your
41
- overall todo list.
42
-
43
- This is your go-to place or finding all of the things that you might have
44
- stored in your todo databases.
45
-
46
- COMMAND OPTIONS
47
- -l, --[no-]long - Show long form
48
-
49
- COMMANDS
50
- contexts - List contexts
51
- tasks - List tasks (default)
52
- """
53
-
54
- Examples:
55
- | help_invocation |
56
- | help list |
57
- | list -h |
58
- | list --help |
59
-
60
-
61
- Scenario: Getting Help for a sub command of todo list
62
- When I successfully run `todo help list tasks`
63
- Then the output should contain:
64
- """
65
- NAME
66
- tasks - List tasks
67
-
68
- SYNOPSIS
69
- todo [global options] list tasks [command options]
70
- todo [global options] list tasks [command options] open
71
-
72
- DESCRIPTION
73
- Lists all of your tasks that you have, in varying orders, and all that
74
- stuff. Yes, this is long, but I need a long description.
75
-
76
- COMMAND OPTIONS
77
- --flag=arg - (default: none)
78
- -x arg - blah blah crud x whatever (default: none)
79
-
80
- COMMANDS
81
- <default> - list all tasks
82
- open - list open tasks
83
- """
84
-
85
- Scenario: Getting Help for a sub command with no command options
86
- When I successfully run `todo help new`
87
- Then the output should contain:
88
- """
89
- NAME
90
- create - Create a new task or context
91
-
92
- SYNOPSIS
93
- todo [global options] create
94
- todo [global options] create contexts [context_name]
95
- todo [global options] create tasks task_name[, task_name]*
96
-
97
- COMMANDS
98
- <default> - Makes a new task
99
- contexts - Make a new context
100
- tasks - Make a new task
101
- """
102
- And the output should not contain "COMMAND OPTIONS"
103
-
104
- Scenario: Running ls w/out subcommand shows help and an error
105
- When I run `todo ls`
106
- Then the exit status should not be 0
107
- And the stderr should contain "error: Command 'ls' requires a subcommand"
108
- And the stdout should contain:
109
- """
110
- NAME
111
- ls - LS things, such as tasks or contexts
112
-
113
- SYNOPSIS
114
- todo [global options] ls [command options] contexts [-b] [-f|--foobar]
115
- todo [global options] ls [command options] tasks [-x arg]
116
-
117
- DESCRIPTION
118
- List a whole lot of things that you might be keeping track of in your
119
- overall todo list.
120
-
121
- This is your go-to place or finding all of the things that you might have
122
- stored in your todo databases.
123
-
124
- COMMAND OPTIONS
125
- -l, --[no-]long - Show long form
126
-
127
- COMMANDS
128
- contexts - List contexts
129
- tasks - List tasks
130
- """
@@ -1,13 +0,0 @@
1
- module OptionTestHelper
2
- def name_should_be(name)
3
- lambda {
4
- assert_equal(name,@cli_option.name)
5
- }
6
- end
7
-
8
- def aliases_should_be(aliases)
9
- lambda {
10
- assert_equal(aliases,@cli_option.aliases)
11
- }
12
- end
13
- end
@@ -1,22 +0,0 @@
1
- require 'test_helper'
2
- require 'tempfile'
3
-
4
- class TC_testCompounCommand < Clean::Test::TestCase
5
- include TestHelper
6
-
7
- test_that "when we create a CompoundCommand where some commands are missing, we get an exception" do
8
- Given {
9
- @name = any_string
10
- @unknown_name = any_string
11
- @existing_command = OpenStruct.new(:name => @name)
12
- @base = OpenStruct.new( :commands => { @name => @existing_command })
13
- }
14
- When {
15
- @code = lambda { GLI::Commands::CompoundCommand.new(@base,{:foo => [@name,@unknown_name]}) }
16
- }
17
- Then {
18
- ex = assert_raises(RuntimeError,&@code)
19
- assert_match /#{@unknown_name}/,ex.message
20
- }
21
- end
22
- end
@@ -1,280 +0,0 @@
1
- require 'test_helper'
2
- require 'pp'
3
-
4
- class TC_testSubCommandParsing < Clean::Test::TestCase
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
-
22
- @results = {}
23
- @exit_code = 0
24
- end
25
-
26
- def teardown
27
- $stdout = @original_stdout
28
- $stderr = @original_stderr
29
- end
30
-
31
- test_that "commands options may clash with globals and it gets sorted out" do
32
- Given :app_with_subcommands_storing_results
33
- When {
34
- @app.run(%w(-f global command1 -f command -s foo))
35
- }
36
- Then {
37
- assert_equal 'command1',@results[:command_name]
38
- assert_equal 'global', @results[:global_options][:f],'global'
39
- assert !@results[:global_options][:s]
40
- assert_equal 'command', @results[:command_options][:f]
41
- assert @results[:command_options][:s]
42
- }
43
- end
44
-
45
- test_that "in legacy mode, subcommand options all share a namespace" do
46
- Given :app_with_subcommands_storing_results
47
- When {
48
- @app.run(%w(-f global command1 -f command -s subcommand10 -f sub))
49
- }
50
- Then {
51
- with_clue {
52
- assert_equal 'subcommand10',@results[:command_name]
53
- assert_equal 'global', @results[:global_options][:f],'global'
54
- assert !@results[:global_options][:s]
55
- assert_equal 'sub', @results[:command_options][:f]
56
- assert @results[:command_options][:s]
57
- assert_nil @results[:command_options][GLI::Command::PARENT]
58
- assert_nil @results[:command_options][GLI::Command::PARENT]
59
- }
60
- }
61
- end
62
-
63
- test_that "in normal mode, each subcommand has its own namespace" do
64
- Given :app_with_subcommands_storing_results, :normal
65
- When {
66
- @app.run(%w(-f global command1 -f command -s subcommand10 -f sub))
67
- }
68
- Then {
69
- with_clue {
70
- assert_equal 'subcommand10',@results[:command_name]
71
- assert_equal 'global', @results[:global_options][:f],'global'
72
- assert !@results[:global_options][:s]
73
- assert_equal 'sub', @results[:command_options][:f]
74
- assert !@results[:command_options][:s]
75
- assert_equal 'command',@results[:command_options][GLI::Command::PARENT][:f]
76
- assert @results[:command_options][GLI::Command::PARENT][:s]
77
- }
78
- }
79
- end
80
-
81
- test_that "in loose mode with autocomplete false, it doesn't autocorrect a sub command" do
82
- Given :app_with_subcommand_storing_results, :normal, false, :loose
83
- When {
84
- @app.run(%w(-f global command -f flag -s subcomm -f subflag))
85
- }
86
- Then {
87
- with_clue {
88
- assert_equal "command",@results[:command_name]
89
- }
90
- }
91
- end
92
-
93
- test_that "in strict mode with autocomplete false, it doesn't autocorrect a sub command" do
94
- Given :app_with_subcommand_storing_results, :normal, false, :strict
95
- When {
96
- @app.run(%w(-f global command -f flag -s subcomm -f subflag))
97
- }
98
- Then {
99
- with_clue {
100
- assert_equal nil,@results[:command_name]
101
- assert @fake_stderr.contained?(/error: Too many arguments for command/)
102
- }
103
- }
104
- end
105
-
106
- test_that "in loose mode, argument validation is ignored" do
107
- Given :app_with_arguments, 1, 1, false, :loose
108
- When :run_app_with_X_arguments, 0
109
- Then {
110
- with_clue {
111
- assert_equal 0, @results[:number_of_args_give_to_action]
112
- assert_equal 0, @exit_code
113
- }
114
- }
115
- end
116
-
117
- test_that "in strict mode, subcommand_option_handling must be normal" do
118
- Given :app_with_arguments, 1, 1, false, :strict, :legacy
119
- When :run_app_with_X_arguments, 1
120
- Then {
121
- with_clue {
122
- assert_nil @results[:number_of_args_give_to_action]
123
- assert_equal 1, @exit_code
124
- assert @fake_stderr.contained?(/you must enable normal subcommand_option_handling/)
125
- }
126
- }
127
- end
128
-
129
- ix = -1
130
- [
131
- [1 , 1 , false , 0 , :not_enough] ,
132
- [1 , 1 , false , 1 , :success] ,
133
- [1 , 1 , false , 2 , :success] ,
134
- [1 , 1 , false , 3 , :too_many] ,
135
- [1 , 1 , true , 0 , :not_enough] ,
136
- [1 , 1 , true , 1 , :success] ,
137
- [1 , 1 , true , 2 , :success] ,
138
- [1 , 1 , true , 3 , :success] ,
139
- [1 , 1 , true , 30 , :success] ,
140
- [0 , 0 , false , 0 , :success] ,
141
- [0 , 0 , false , 1 , :too_many] ,
142
- [0 , 1 , false , 1 , :success] ,
143
- [0 , 1 , false , 0 , :success] ,
144
- [1 , 0 , false , 1 , :success] ,
145
- [1 , 0 , false , 0 , :not_enough] ,
146
- [0 , 0 , true , 0 , :success] ,
147
- [0 , 0 , true , 10 , :success]
148
-
149
- ].each do |number_required, number_optional, has_multiple, number_generated, status|
150
- ix = ix + 1
151
- test_that "in strict mode, with #{number_required} required, #{number_optional} optional, #{ has_multiple ? 'multiple' : 'not multiple' } and #{number_generated} generated, it should be #{status}" do
152
- Given :app_with_arguments, number_required, number_optional, has_multiple, :strict
153
- When :run_app_with_X_arguments, number_generated
154
- Then {
155
- with_clue {
156
- if status == :success then
157
- assert_equal number_generated, @results[:number_of_args_give_to_action]
158
- assert_equal 0, @exit_code
159
- assert !@fake_stderr.contained?(/Not enough arguments for command/)
160
- assert !@fake_stderr.contained?(/Too many arguments for command/)
161
- elsif status == :not_enough then
162
- assert_equal nil, @results[:number_of_args_give_to_action]
163
- assert_equal 64, @exit_code
164
- assert @fake_stderr.contained?(/Not enough arguments for command/)
165
- elsif status == :too_many then
166
- assert_equal nil, @results[:number_of_args_give_to_action]
167
- assert_equal 64, @exit_code
168
- assert @fake_stderr.contained?(/Too many arguments for command/)
169
- else
170
- assert false
171
- end
172
- }
173
- }
174
- end
175
- end
176
- private
177
- def with_clue(&block)
178
- block.call
179
- rescue Exception
180
- dump = ""
181
- PP.pp "\nRESULTS---#{@results}", dump unless @results.empty?
182
- PP.pp "\nSTDERR---\n#{@fake_stderr.to_s}", dump
183
- PP.pp "\nSTDOUT---\n#{@fake_stdout.to_s}", dump
184
- @original_stdout.puts dump
185
- raise
186
- end
187
-
188
- def app_with_subcommand_storing_results(subcommand_option_handling_strategy, autocomplete, arguments_handling_strategy)
189
- @app.subcommand_option_handling subcommand_option_handling_strategy
190
- @app.autocomplete_commands autocomplete
191
- @app.arguments arguments_handling_strategy
192
- @app.flag ['f','flag']
193
- @app.switch ['s','switch']
194
-
195
- @app.command "command" do |c|
196
- c.flag ['f','flag']
197
- c.switch ['s','switch']
198
- c.action do |global,options,args|
199
- @results = {
200
- :command_name => "command",
201
- :global_options => global,
202
- :command_options => options,
203
- :args => args
204
- }
205
- end
206
-
207
- c.command "subcommand" do |subcommand|
208
- subcommand.flag ['f','flag']
209
- subcommand.flag ['foo']
210
- subcommand.switch ['s','switch']
211
- subcommand.action do |global,options,args|
212
- @results = {
213
- :command_name => "subcommand",
214
- :global_options => global,
215
- :command_options => options,
216
- :args => args
217
- }
218
- end
219
- end
220
- end
221
- end
222
-
223
- def app_with_subcommands_storing_results(subcommand_option_handling_strategy = :legacy)
224
- @app.subcommand_option_handling subcommand_option_handling_strategy
225
- @app.flag ['f','flag']
226
- @app.switch ['s','switch']
227
-
228
- 2.times do |i|
229
- @app.command "command#{i}" do |c|
230
- c.flag ['f','flag']
231
- c.switch ['s','switch']
232
- c.action do |global,options,args|
233
- @results = {
234
- :command_name => "command#{i}",
235
- :global_options => global,
236
- :command_options => options,
237
- :args => args
238
- }
239
- end
240
-
241
- 2.times do |j|
242
- c.command "subcommand#{i}#{j}" do |subcommand|
243
- subcommand.flag ['f','flag']
244
- subcommand.flag ['foo']
245
- subcommand.switch ['s','switch']
246
- subcommand.action do |global,options,args|
247
- @results = {
248
- :command_name => "subcommand#{i}#{j}",
249
- :global_options => global,
250
- :command_options => options,
251
- :args => args
252
- }
253
- end
254
- end
255
- end
256
- end
257
- end
258
- end
259
-
260
- def app_with_arguments(number_required_arguments, number_optional_arguments, has_argument_multiple, arguments_handling_strategy = :loose, subcommand_option_handling_strategy = :normal)
261
- @app.arguments arguments_handling_strategy
262
- @app.subcommand_option_handling subcommand_option_handling_strategy
263
-
264
- number_required_arguments.times { |i| @app.arg("needed#{i}") }
265
- number_optional_arguments.times { |i| @app.arg("optional#{i}", :optional) }
266
- @app.arg :multiple, [:multiple, :optional] if has_argument_multiple
267
-
268
- @app.command :cmd do |c|
269
- c.action do |g,o,a|
270
- @results = {
271
- :number_of_args_give_to_action => a.size
272
- }
273
- end
274
- end
275
- end
276
-
277
- def run_app_with_X_arguments(number_arguments)
278
- @exit_code = @app.run [].tap{|args| args << "cmd"; number_arguments.times {|i| args << "arg#{i}"}}
279
- end
280
- end