gli 2.19.2 → 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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +28 -0
  3. data/.gitignore +1 -3
  4. data/Gemfile +0 -6
  5. data/README.rdoc +2 -12
  6. data/Rakefile +15 -37
  7. data/bin/ci +29 -0
  8. data/bin/gli +25 -64
  9. data/bin/rake +29 -0
  10. data/bin/setup +5 -0
  11. data/exe/gli +68 -0
  12. data/gli.gemspec +19 -21
  13. data/gli.rdoc +2 -2
  14. data/lib/gli/commands/help_modules/command_help_format.rb +1 -1
  15. data/lib/gli/commands/help_modules/global_help_format.rb +1 -1
  16. data/lib/gli/commands/scaffold.rb +9 -93
  17. data/lib/gli/options.rb +2 -2
  18. data/lib/gli/version.rb +1 -1
  19. data/object-model.dot +29 -0
  20. data/object-model.png +0 -0
  21. data/test/apps/todo/Gemfile +1 -1
  22. data/test/apps/todo/bin/todo +1 -1
  23. data/test/integration/gli_cli_test.rb +69 -0
  24. data/test/integration/gli_powered_app_test.rb +52 -0
  25. data/test/integration/scaffold_test.rb +30 -0
  26. data/test/integration/test_helper.rb +52 -0
  27. data/test/{tc_command_finder.rb → unit/command_finder_test.rb} +6 -6
  28. data/test/{tc_command.rb → unit/command_test.rb} +4 -4
  29. data/test/unit/compound_command_test.rb +17 -0
  30. data/test/{tc_doc.rb → unit/doc_test.rb} +38 -51
  31. data/test/{tc_flag.rb → unit/flag_test.rb} +19 -25
  32. data/test/{tc_gli.rb → unit/gli_test.rb} +28 -47
  33. data/test/{tc_help.rb → unit/help_test.rb} +48 -107
  34. data/test/{init_simplecov.rb → unit/init_simplecov.rb} +0 -0
  35. data/test/{tc_options.rb → unit/options_test.rb} +4 -4
  36. data/test/unit/subcommand_parsing_test.rb +263 -0
  37. data/test/unit/subcommands_test.rb +245 -0
  38. data/test/{fake_std_out.rb → unit/support/fake_std_out.rb} +0 -0
  39. data/test/{config.yaml → unit/support/gli_test_config.yml} +0 -0
  40. data/test/unit/switch_test.rb +49 -0
  41. data/test/{tc_terminal.rb → unit/terminal_test.rb} +4 -3
  42. data/test/unit/test_helper.rb +13 -0
  43. data/test/unit/verbatim_wrapper_test.rb +24 -0
  44. metadata +57 -124
  45. data/.ruby-gemset +0 -1
  46. data/.ruby-version +0 -1
  47. data/.travis.yml +0 -11
  48. data/ObjectModel.graffle +0 -1191
  49. data/bin/report_on_rake_results +0 -10
  50. data/bin/test_all_rubies.sh +0 -6
  51. data/features/gli_executable.feature +0 -90
  52. data/features/gli_init.feature +0 -236
  53. data/features/step_definitions/gli_executable_steps.rb +0 -18
  54. data/features/step_definitions/gli_init_steps.rb +0 -11
  55. data/features/step_definitions/todo_steps.rb +0 -100
  56. data/features/support/env.rb +0 -54
  57. data/features/support/hooks.rb +0 -5
  58. data/features/todo.feature +0 -579
  59. data/features/todo_legacy.feature +0 -130
  60. data/test/option_test_helper.rb +0 -13
  61. data/test/tc_compound_command.rb +0 -22
  62. data/test/tc_subcommand_parsing.rb +0 -280
  63. data/test/tc_subcommands.rb +0 -259
  64. data/test/tc_switch.rb +0 -55
  65. data/test/tc_verbatim_wrapper.rb +0 -36
  66. 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...
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