gli_aziz_light 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +17 -0
  6. data/CONTRIBUTING.md +23 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE.txt +201 -0
  9. data/ObjectModel.graffle +1191 -0
  10. data/README.rdoc +109 -0
  11. data/Rakefile +126 -0
  12. data/bin/gli +59 -0
  13. data/bin/report_on_rake_results +10 -0
  14. data/bin/test_all_rubies.sh +6 -0
  15. data/features/gli_executable.feature +90 -0
  16. data/features/gli_init.feature +232 -0
  17. data/features/step_definitions/gli_executable_steps.rb +18 -0
  18. data/features/step_definitions/gli_init_steps.rb +11 -0
  19. data/features/step_definitions/todo_steps.rb +88 -0
  20. data/features/support/env.rb +53 -0
  21. data/features/todo.feature +413 -0
  22. data/features/todo_legacy.feature +128 -0
  23. data/gli.cheat +95 -0
  24. data/gli.gemspec +34 -0
  25. data/gli.rdoc +73 -0
  26. data/lib/gli.rb +35 -0
  27. data/lib/gli/app.rb +286 -0
  28. data/lib/gli/app_support.rb +341 -0
  29. data/lib/gli/command.rb +171 -0
  30. data/lib/gli/command_finder.rb +41 -0
  31. data/lib/gli/command_line_option.rb +34 -0
  32. data/lib/gli/command_line_token.rb +63 -0
  33. data/lib/gli/command_support.rb +181 -0
  34. data/lib/gli/commands/compound_command.rb +42 -0
  35. data/lib/gli/commands/doc.rb +231 -0
  36. data/lib/gli/commands/help.rb +95 -0
  37. data/lib/gli/commands/help_modules/arg_name_formatter.rb +20 -0
  38. data/lib/gli/commands/help_modules/command_finder.rb +60 -0
  39. data/lib/gli/commands/help_modules/command_help_format.rb +156 -0
  40. data/lib/gli/commands/help_modules/global_help_format.rb +70 -0
  41. data/lib/gli/commands/help_modules/help_completion_format.rb +31 -0
  42. data/lib/gli/commands/help_modules/list_formatter.rb +23 -0
  43. data/lib/gli/commands/help_modules/one_line_wrapper.rb +18 -0
  44. data/lib/gli/commands/help_modules/options_formatter.rb +49 -0
  45. data/lib/gli/commands/help_modules/text_wrapper.rb +53 -0
  46. data/lib/gli/commands/help_modules/tty_only_wrapper.rb +23 -0
  47. data/lib/gli/commands/help_modules/verbatim_wrapper.rb +16 -0
  48. data/lib/gli/commands/initconfig.rb +74 -0
  49. data/lib/gli/commands/rdoc_document_listener.rb +116 -0
  50. data/lib/gli/commands/scaffold.rb +401 -0
  51. data/lib/gli/dsl.rb +226 -0
  52. data/lib/gli/exceptions.rb +71 -0
  53. data/lib/gli/flag.rb +68 -0
  54. data/lib/gli/gli_option_block_parser.rb +84 -0
  55. data/lib/gli/gli_option_parser.rb +156 -0
  56. data/lib/gli/option_parser_factory.rb +81 -0
  57. data/lib/gli/option_parsing_result.rb +21 -0
  58. data/lib/gli/options.rb +23 -0
  59. data/lib/gli/switch.rb +35 -0
  60. data/lib/gli/terminal.rb +101 -0
  61. data/lib/gli/version.rb +5 -0
  62. data/test/apps/README.md +2 -0
  63. data/test/apps/todo/Gemfile +2 -0
  64. data/test/apps/todo/README.rdoc +6 -0
  65. data/test/apps/todo/Rakefile +23 -0
  66. data/test/apps/todo/bin/todo +63 -0
  67. data/test/apps/todo/lib/todo/commands/create.rb +24 -0
  68. data/test/apps/todo/lib/todo/commands/list.rb +63 -0
  69. data/test/apps/todo/lib/todo/commands/ls.rb +47 -0
  70. data/test/apps/todo/lib/todo/commands/make.rb +52 -0
  71. data/test/apps/todo/lib/todo/version.rb +3 -0
  72. data/test/apps/todo/test/tc_nothing.rb +14 -0
  73. data/test/apps/todo/todo.gemspec +23 -0
  74. data/test/apps/todo/todo.rdoc +5 -0
  75. data/test/apps/todo_legacy/Gemfile +2 -0
  76. data/test/apps/todo_legacy/README.rdoc +6 -0
  77. data/test/apps/todo_legacy/Rakefile +23 -0
  78. data/test/apps/todo_legacy/bin/todo +61 -0
  79. data/test/apps/todo_legacy/lib/todo/commands/create.rb +24 -0
  80. data/test/apps/todo_legacy/lib/todo/commands/list.rb +63 -0
  81. data/test/apps/todo_legacy/lib/todo/commands/ls.rb +47 -0
  82. data/test/apps/todo_legacy/lib/todo/version.rb +3 -0
  83. data/test/apps/todo_legacy/test/tc_nothing.rb +14 -0
  84. data/test/apps/todo_legacy/todo.gemspec +23 -0
  85. data/test/apps/todo_legacy/todo.rdoc +5 -0
  86. data/test/apps/todo_plugins/commands/third.rb +1 -0
  87. data/test/config.yaml +10 -0
  88. data/test/fake_std_out.rb +30 -0
  89. data/test/init_simplecov.rb +8 -0
  90. data/test/option_test_helper.rb +13 -0
  91. data/test/tc_command.rb +508 -0
  92. data/test/tc_compound_command.rb +22 -0
  93. data/test/tc_doc.rb +325 -0
  94. data/test/tc_flag.rb +62 -0
  95. data/test/tc_gli.rb +773 -0
  96. data/test/tc_help.rb +387 -0
  97. data/test/tc_options.rb +43 -0
  98. data/test/tc_subcommand_parsing.rb +104 -0
  99. data/test/tc_subcommands.rb +260 -0
  100. data/test/tc_switch.rb +55 -0
  101. data/test/tc_terminal.rb +100 -0
  102. data/test/tc_verbatim_wrapper.rb +36 -0
  103. data/test/test_helper.rb +20 -0
  104. metadata +330 -0
@@ -0,0 +1,18 @@
1
+ Given /^I have GLI installed$/ do
2
+ add_to_lib_path(GLI_LIB_PATH)
3
+ end
4
+
5
+ Given /^my terminal size is "([^"]*)"$/ do |terminal_size|
6
+ if terminal_size =~/^(\d+)x(\d+)$/
7
+ ENV['COLUMNS'] = $1
8
+ ENV['LINES'] = $2
9
+ else
10
+ raise "Terminal size should be COLxLines, e.g. 80x24"
11
+ end
12
+ end
13
+
14
+
15
+ Given /^the file "(.*?)" doesn't exist$/ do |filename|
16
+ FileUtils.rm filename if File.exists?(filename)
17
+ end
18
+
@@ -0,0 +1,11 @@
1
+ Given /^GLI's libs are in my path$/ do
2
+ ENV['RUBYLIB'] = GLI_LIB_PATH
3
+ end
4
+
5
+ Given /^I make sure todo's lib dir is in my lib path$/ do
6
+ add_to_lib_path("./lib")
7
+ end
8
+
9
+ Given /^todo's libs are no longer in my load path$/ do
10
+ remove_from_lib_path("./lib")
11
+ end
@@ -0,0 +1,88 @@
1
+ Given /^todo_legacy's bin directory is in my path/ do
2
+ add_to_path(File.expand_path(File.join(File.dirname(__FILE__),'..','..','test','apps','todo_legacy','bin')))
3
+ end
4
+
5
+ Given /^todo's bin directory is in my path/ do
6
+ add_to_path(File.expand_path(File.join(File.dirname(__FILE__),'..','..','test','apps','todo','bin')))
7
+ end
8
+
9
+ Given /^the todo app is coded to avoid sorted help commands$/ do
10
+ ENV['TODO_SORT_HELP'] = 'manually'
11
+ end
12
+
13
+ Given /^the todo app is coded to avoid wrapping text$/ do
14
+ ENV['TODO_WRAP_HELP_TEXT'] = 'one_line'
15
+ end
16
+
17
+ Given /^the todo app is coded to wrap text only for tty$/ do
18
+ ENV['TODO_WRAP_HELP_TEXT'] = 'tty_only'
19
+ end
20
+
21
+ Given /^a clean home directory$/ do
22
+ FileUtils.rm_rf File.join(ENV['HOME'],'gli_test_todo.rc')
23
+ end
24
+
25
+ Then /^the config file should contain a section for each command and subcommand$/ do
26
+ config = File.open(File.join(ENV['HOME'],'gli_test_todo.rc')) do |file|
27
+ YAML::load(file)
28
+ end
29
+ config.keys.should include(:flag)
30
+ config[:flag].should == 'foo'
31
+ config[:flag].tap do |flag|
32
+ if flag.respond_to?(:encoding)
33
+ flag.encoding.name.should == 'UTF-8'
34
+ end
35
+ end
36
+ config.keys.should include(:switch)
37
+ config[:switch].should == true
38
+ config.keys.should include(:otherswitch)
39
+ config[:otherswitch].should == false
40
+ config.keys.should include('commands')
41
+ %w(chained chained2 create first list ls second).map(&:to_sym).each do |command_name|
42
+ config['commands'].keys.should include(command_name)
43
+ end
44
+ config['commands'][:create].keys.should include('commands')
45
+ config['commands'][:create]['commands'].should include(:tasks)
46
+ config['commands'][:create]['commands'].should include(:contexts)
47
+
48
+ config['commands'][:list].keys.should include('commands')
49
+ config['commands'][:list]['commands'].should include(:tasks)
50
+ config['commands'][:list]['commands'].should include(:contexts)
51
+ end
52
+
53
+ Given /^a config file that specifies defaults for some commands with subcommands$/ do
54
+ @config = {
55
+ 'commands' => {
56
+ :list => {
57
+ 'commands' => {
58
+ :tasks => {
59
+ :flag => 'foobar',
60
+ },
61
+ :contexts => {
62
+ :otherflag => 'crud',
63
+ },
64
+ }
65
+ }
66
+ }
67
+ }
68
+ File.open(File.join(ENV['HOME'],'gli_test_todo.rc'),'w') do |file|
69
+ file.puts @config.to_yaml
70
+ end
71
+ end
72
+
73
+ Then /^I should see the defaults for '(.*)' from the config file in the help$/ do |command_path|
74
+ if command_path == 'list tasks'
75
+ step %{the output should match /--flag.*default: foobar/}
76
+ unescape(all_output).should_not =~ /#{unescape("--otherflag.*default: crud")}/m
77
+ elsif command_path == 'list contexts'
78
+ step %{the output should match /--otherflag.*default: crud/}
79
+ unescape(all_output).should_not =~ /#{unescape("--flag.*default: foobar")}/m
80
+ else
81
+ raise "Don't know how to test for command path #{command_path}"
82
+ end
83
+ end
84
+
85
+
86
+ Given /^the todo app is coded to use verbatim formatting$/ do
87
+ ENV['TODO_WRAP_HELP_TEXT'] = 'verbatim'
88
+ end
@@ -0,0 +1,53 @@
1
+ begin
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ rescue LoadError
5
+ # Don't care
6
+ end
7
+ require 'aruba/cucumber'
8
+ require 'fileutils'
9
+
10
+ # Adds GLI's bin dir to our path
11
+ ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
12
+ GLI_LIB_PATH = File.expand_path(File.join(File.dirname(__FILE__),'..','..','lib'))
13
+
14
+ GLI_GEMSET = 'gli-testing'
15
+ TMP_PATH = 'tmp/aruba'
16
+
17
+ Before do
18
+ # Not sure how else to get this dynamically
19
+ @dirs = [TMP_PATH]
20
+ @aruba_timeout_seconds = 5
21
+ @original_path = ENV['PATH'].split(File::PATH_SEPARATOR)
22
+ @original_home = ENV['HOME']
23
+ new_home = "/tmp/fakehome"
24
+ FileUtils.rm_rf new_home
25
+ FileUtils.mkdir new_home
26
+ ENV['HOME'] = new_home
27
+ FileUtils.cp 'gli.rdoc','gli.rdoc.orig'
28
+ end
29
+
30
+ After do |scenario|
31
+ ENV['RUBYLIB'] = ''
32
+ todo_app_dir = File.join(TMP_PATH,'todo')
33
+ if File.exists? todo_app_dir
34
+ FileUtils.rm_rf(todo_app_dir)
35
+ end
36
+ ENV['PATH'] = @original_path.join(File::PATH_SEPARATOR)
37
+ ENV['HOME'] = @original_home
38
+ ENV['TODO_SORT_HELP'] = nil
39
+ ENV['TODO_WRAP_HELP_TEXT'] = nil
40
+ FileUtils.mv 'gli.rdoc.orig','gli.rdoc'
41
+ end
42
+
43
+ def add_to_path(dir)
44
+ ENV['PATH'] = "#{dir}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
45
+ end
46
+
47
+ def add_to_lib_path(path)
48
+ ENV["RUBYLIB"] = (String(ENV["RUBYLIB"]).split(File::PATH_SEPARATOR) + [path]).join(File::PATH_SEPARATOR)
49
+ end
50
+
51
+ def remove_from_lib_path(path)
52
+ ENV["RUBYLIB"] = (String(ENV["RUBYLIB"]).split(File::PATH_SEPARATOR) - [path]).join(File::PATH_SEPARATOR)
53
+ end
@@ -0,0 +1,413 @@
1
+ Feature: The todo app has a nice user interface
2
+ As a user of the todo application
3
+ It should have a nice UI, since it's GLI-powered
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's bin directory is in my path
10
+
11
+ Scenario: Error message for unknown command
12
+ When I run `todo help unknown`
13
+ Then the output should contain:
14
+ """
15
+ error: Unknown command 'unknown'. Use 'todo help' for a list of commands.
16
+ """
17
+
18
+ Scenario Outline: Getting Help for todo in general
19
+ When I successfully run `todo <help>`
20
+ Then the output should contain:
21
+ """
22
+ NAME
23
+ todo - Manages tasks
24
+
25
+ A test program that has a sophisticated UI that can be used to exercise a
26
+ lot of GLI's power
27
+
28
+ SYNOPSIS
29
+ todo [global options] command [command options] [arguments...]
30
+
31
+ VERSION
32
+ 0.0.1
33
+
34
+ GLOBAL OPTIONS
35
+ --flag=arg - (default: none)
36
+ --help - Show this message
37
+ --[no-]otherswitch -
38
+ --[no-]switch -
39
+ --version - Display the program version
40
+
41
+ COMMANDS
42
+ chained -
43
+ chained2, ch2 -
44
+ create, new - Create a new task or context
45
+ first -
46
+ help - Shows a list of commands or help for one command
47
+ initconfig - Initialize the config file using current global options
48
+ list - List things, such as tasks or contexts
49
+ ls - LS things, such as tasks or contexts
50
+ make -
51
+ second -
52
+ third -
53
+ """
54
+ Examples:
55
+ | help |
56
+ | help |
57
+
58
+ Scenario: Version display
59
+ When I successfully run `todo --version`
60
+ Then the output should contain:
61
+ """
62
+ todo version 0.0.1
63
+ """
64
+
65
+ Scenario: Help completion mode
66
+ When I successfully run `todo help -c`
67
+ Then the output should contain:
68
+ """
69
+ _doc
70
+ ch2
71
+ chained
72
+ chained2
73
+ create
74
+ first
75
+ help
76
+ initconfig
77
+ list
78
+ ls
79
+ make
80
+ new
81
+ second
82
+ third
83
+ """
84
+
85
+ Scenario: Help completion mode for partial match
86
+ When I successfully run `todo help -c ch`
87
+ Then the output should contain:
88
+ """
89
+ ch2
90
+ chained
91
+ chained2
92
+ """
93
+
94
+ Scenario: Help completion mode for subcommands
95
+ When I successfully run `todo help -c list`
96
+ Then the output should contain:
97
+ """
98
+ contexts
99
+ tasks
100
+ """
101
+
102
+ Scenario: Help completion mode partial match for subcommands
103
+ When I successfully run `todo help -c list con`
104
+ Then the output should contain:
105
+ """
106
+ contexts
107
+ """
108
+
109
+ Scenario: Getting Help with self-ordered commands
110
+ Given the todo app is coded to avoid sorted help commands
111
+ When I successfully run `todo help`
112
+ Then the output should contain:
113
+ """
114
+ NAME
115
+ todo - Manages tasks
116
+
117
+ A test program that has a sophisticated UI that can be used to exercise a
118
+ lot of GLI's power
119
+
120
+ SYNOPSIS
121
+ todo [global options] command [command options] [arguments...]
122
+
123
+ VERSION
124
+ 0.0.1
125
+
126
+ GLOBAL OPTIONS
127
+ --flag=arg - (default: none)
128
+ --[no-]switch -
129
+ --[no-]otherswitch -
130
+ --version - Display the program version
131
+ --help - Show this message
132
+
133
+ COMMANDS
134
+ help - Shows a list of commands or help for one command
135
+ initconfig - Initialize the config file using current global options
136
+ create, new - Create a new task or context
137
+ list - List things, such as tasks or contexts
138
+ ls - LS things, such as tasks or contexts
139
+ make -
140
+ third -
141
+ first -
142
+ second -
143
+ chained -
144
+ chained2, ch2 -
145
+ """
146
+
147
+ Scenario Outline: Getting Help for a top level command of todo
148
+ When I successfully run `todo <help_invocation>`
149
+ Then the output should contain:
150
+ """
151
+ NAME
152
+ list - List things, such as tasks or contexts
153
+
154
+ SYNOPSIS
155
+ todo [global options] list [command options] [--flag arg] [-x arg] [tasks]
156
+ todo [global options] list [command options] [--otherflag arg] [-b] [-f|--foobar] contexts
157
+
158
+ DESCRIPTION
159
+ List a whole lot of things that you might be keeping track of in your
160
+ overall todo list.
161
+
162
+ This is your go-to place or finding all of the things that you might have
163
+ stored in your todo databases.
164
+
165
+ COMMAND OPTIONS
166
+ -l, --[no-]long - Show long form
167
+
168
+ COMMANDS
169
+ contexts - List contexts
170
+ tasks - List tasks (default)
171
+ """
172
+
173
+ Examples:
174
+ | help_invocation |
175
+ | help list |
176
+ | list -h |
177
+ | list --help |
178
+ | --help list |
179
+
180
+
181
+ Scenario: Getting Help for a top level command of todo with no command options
182
+ When I successfully run `todo help chained`
183
+ Then the output should contain:
184
+ """
185
+ NAME
186
+ chained -
187
+
188
+ SYNOPSIS
189
+ todo [global options] chained
190
+ """
191
+
192
+ Scenario: Getting Help with no wrapping
193
+ Given the todo app is coded to avoid wrapping text
194
+ When I successfully run `todo help list`
195
+ Then the output should contain:
196
+ """
197
+ NAME
198
+ list - List things, such as tasks or contexts
199
+
200
+ SYNOPSIS
201
+ todo [global options] list [command options] [--flag arg] [-x arg] [tasks]
202
+ todo [global options] list [command options] [--otherflag arg] [-b] [-f|--foobar] contexts
203
+
204
+ DESCRIPTION
205
+ List a whole lot of things that you might be keeping track of in your overall todo list. This is your go-to place or finding all of the things that you might have stored in your todo databases.
206
+
207
+ COMMAND OPTIONS
208
+ -l, --[no-]long - Show long form
209
+
210
+ COMMANDS
211
+ contexts - List contexts
212
+ tasks - List tasks (default)
213
+ """
214
+
215
+ Scenario: Getting Help with verbatim formatting
216
+ Given the todo app is coded to use verbatim formatting
217
+ When I successfully run `todo help list`
218
+ Then the output should contain:
219
+ """
220
+ NAME
221
+ list - List things, such as tasks or contexts
222
+
223
+ SYNOPSIS
224
+ todo [global options] list [command options] [--flag arg] [-x arg] [tasks]
225
+ todo [global options] list [command options] [--otherflag arg] [-b] [-f|--foobar] contexts
226
+
227
+ DESCRIPTION
228
+
229
+ List a whole lot of things that you might be keeping track of
230
+ in your overall todo list.
231
+
232
+ This is your go-to place or finding all of the things that you
233
+ might have
234
+ stored in
235
+ your todo databases.
236
+
237
+
238
+ COMMAND OPTIONS
239
+ -l, --[no-]long - Show long form
240
+
241
+ COMMANDS
242
+ contexts - List contexts
243
+ tasks - List tasks (default)
244
+ """
245
+
246
+ Scenario: Getting Help without wrapping
247
+ Given the todo app is coded to wrap text only for tty
248
+ When I successfully run `todo help list`
249
+ Then the output should contain:
250
+ """
251
+ NAME
252
+ list - List things, such as tasks or contexts
253
+
254
+ SYNOPSIS
255
+ todo [global options] list [command options] [--flag arg] [-x arg] [tasks]
256
+ todo [global options] list [command options] [--otherflag arg] [-b] [-f|--foobar] contexts
257
+
258
+ DESCRIPTION
259
+ List a whole lot of things that you might be keeping track of in your overall todo list. This is your go-to place or finding all of the things that you might have stored in your todo databases.
260
+
261
+ COMMAND OPTIONS
262
+ -l, --[no-]long - Show long form
263
+
264
+ COMMANDS
265
+ contexts - List contexts
266
+ tasks - List tasks (default)
267
+ """
268
+
269
+ Scenario: Getting Help for a sub command of todo list
270
+ When I successfully run `todo help list tasks`
271
+ Then the output should contain:
272
+ """
273
+ NAME
274
+ tasks - List tasks
275
+
276
+ SYNOPSIS
277
+ todo [global options] list tasks [command options]
278
+ todo [global options] list tasks [command options] open
279
+
280
+ DESCRIPTION
281
+ Lists all of your tasks that you have, in varying orders, and all that
282
+ stuff. Yes, this is long, but I need a long description.
283
+
284
+ COMMAND OPTIONS
285
+ --flag=arg - (default: none)
286
+ -x arg - blah blah crud x whatever (default: none)
287
+
288
+ COMMANDS
289
+ <default> - list all tasks
290
+ open - list open tasks
291
+ """
292
+
293
+ Scenario: Getting Help for a sub command with no command options
294
+ When I successfully run `todo help new`
295
+ Then the output should contain:
296
+ """
297
+ NAME
298
+ create - Create a new task or context
299
+
300
+ SYNOPSIS
301
+ todo [global options] create
302
+ todo [global options] create contexts [context_name]
303
+ todo [global options] create tasks task_name[, task_name]*
304
+
305
+ COMMANDS
306
+ <default> - Makes a new task
307
+ contexts - Make a new context
308
+ tasks - Make a new task
309
+ """
310
+ And the output should not contain "COMMAND OPTIONS"
311
+
312
+ Scenario: Running list w/out subcommand performs list tasks by default
313
+ When I successfully run `todo list boo yay`
314
+ Then the output should contain "list tasks: boo,yay"
315
+
316
+ Scenario: Running list w/out subcommand or any arguments performs list tasks by default
317
+ When I successfully run `todo list`
318
+ Then the output should contain "list tasks:"
319
+
320
+ Scenario: Running chained commands works
321
+ When I successfully run `todo chained foo bar`
322
+ Then the output should contain:
323
+ """
324
+ first: foo,bar
325
+ second: foo,bar
326
+ """
327
+
328
+ Scenario: Running chained commands works and is ordered
329
+ When I successfully run `todo chained2 foo bar`
330
+ Then the output should contain:
331
+ """
332
+ second: foo,bar
333
+ first: foo,bar
334
+ """
335
+
336
+ Scenario: Running chained commands works and is ordered
337
+ When I successfully run `todo ch2 foo bar`
338
+ Then the output should contain:
339
+ """
340
+ second: foo,bar
341
+ first: foo,bar
342
+ """
343
+
344
+ Scenario: Running ls w/out subcommand shows help and an error
345
+ When I run `todo ls`
346
+ Then the exit status should not be 0
347
+ And the stderr should contain "error: Command 'ls' requires a subcommand"
348
+ And the stdout should contain:
349
+ """
350
+ NAME
351
+ ls - LS things, such as tasks or contexts
352
+
353
+ SYNOPSIS
354
+ todo [global options] ls [command options] [-b] [-f|--foobar] contexts
355
+ todo [global options] ls [command options] [-x arg] tasks
356
+
357
+ DESCRIPTION
358
+ List a whole lot of things that you might be keeping track of in your
359
+ overall todo list.
360
+
361
+ This is your go-to place or finding all of the things that you might have
362
+ stored in your todo databases.
363
+
364
+ COMMAND OPTIONS
365
+ -l, --[no-]long - Show long form
366
+
367
+ COMMANDS
368
+ contexts - List contexts
369
+ tasks - List tasks
370
+ """
371
+
372
+ Scenario: Access to the complex command-line options for nested subcommands
373
+ Given I run `todo make -l MAKE task -l TASK bug -l BUG other args`
374
+ Then the exit status should be 0
375
+ And the stdout should contain:
376
+ """
377
+ new task bug
378
+ other,args
379
+ BUG
380
+
381
+ BUG
382
+ TASK
383
+ TASK
384
+
385
+ MAKE
386
+ MAKE
387
+
388
+ """
389
+
390
+ Scenario: Init Config makes a reasonable config file
391
+ Given a clean home directory
392
+ When I successfully run `todo --flag foo --switch --no-otherswitch initconfig`
393
+ Then the config file should contain a section for each command and subcommand
394
+
395
+ Scenario: Init Config makes a reasonable config file if one is there and we force it
396
+ Given a clean home directory
397
+ And I successfully run `todo --flag foo --switch --no-otherswitch initconfig`
398
+ When I run `todo --flag foo --switch --no-otherswitch initconfig`
399
+ Then the exit status should not be 0
400
+ When I run `todo --flag foo --switch --no-otherswitch initconfig --force`
401
+ Then the exit status should be 0
402
+
403
+ Scenario: Configuration percolates to the app
404
+ Given a clean home directory
405
+ And a config file that specifies defaults for some commands with subcommands
406
+ When I successfully run `todo help list tasks`
407
+ Then I should see the defaults for 'list tasks' from the config file in the help
408
+
409
+ Scenario: Do it again because aruba buffers all output
410
+ Given a clean home directory
411
+ And a config file that specifies defaults for some commands with subcommands
412
+ When I successfully run `todo help list contexts`
413
+ Then I should see the defaults for 'list contexts' from the config file in the help