gli 2.17.2 → 2.19.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f2ff76f03d4fc53954e649cea392e77f445b9fa0deae621fba59c66c52c27f0
4
- data.tar.gz: f26e176e6967175ea76cf2278a1665cb9332b8f1b425990d11f6313e458cb1fb
3
+ metadata.gz: 635c14c43560039c5a46a367a501201b6d255dfb850d1280a8300e0c5b7f9ab8
4
+ data.tar.gz: 0d82f1d19eb5f41a91cdee92f3acf1732b84f93ff9e6353a4e18ad438a5f259a
5
5
  SHA512:
6
- metadata.gz: d9895c2424a0e49d6d185fc73ab433e74d9b366d87697e865633713eedbc8abbdd2afc6cfe045e9aa1197fbe4ed41eb883dcde178e615e125a9d3d70056aca2d
7
- data.tar.gz: 1f5b8750936328ac2a175a7d8b9cf89cd050e8710b5b6939425bab405c8e61d7cbd59c7a34645910008440dc7034f7fab7a817553ac0ac85728bbda84e16324d
6
+ metadata.gz: ae6e5aa99a45658686fdbd6cb0e7835c66f0761f8cb0a7e7822265e963d08830441ba6024b747bd0a077152110b55b7c7726bdb55178b1b188bfe2e9804b3968
7
+ data.tar.gz: '0396dc0ac0290db90f9715bf4b3f3352394003403b81fe0b0c1c6b57af5f981983ac7e691bf17d1e68e9dee80358b9e87991407137a4824464270c4574d468b8'
@@ -0,0 +1 @@
1
+ ruby 2.7.1
@@ -1,10 +1,6 @@
1
- = Git-Like Interface Command Line Parser
1
+ = GLI, the Git-Like Interface Command Line Parser
2
2
 
3
- GLI is the best way to make a "command-suite" command-line application, e.g. one like <tt>git</tt> (for the best way to make a
4
- simpler command-line application, check out methadone[http://www.github.com/davetron5000/methadone]).
5
-
6
- GLI allows you to make a polished, easy-to-maintain command-line application without a lot
7
- of syntax, but without restricting you in any way from the power of +OptionParser+.
3
+ GLI allows you to create command-line app in Ruby that behaves like <tt>git</tt> in that it takes subcommands to perform a series of complex action, e.g. <tt>git remote add</tt>.
8
4
 
9
5
  * {Overview}[http://davetron5000.github.com/gli]
10
6
  * {Source on Github}[http://github.com/davetron5000/gli]
@@ -12,16 +8,40 @@ of syntax, but without restricting you in any way from the power of +OptionParse
12
8
 
13
9
  {<img src="https://secure.travis-ci.org/davetron5000/gli.svg?branch=gli-2" alt="Build Status" />}[https://travis-ci.org/davetron5000/gli]
14
10
 
11
+ == What Problem does GLI Solve?
12
+
13
+ Creating a command-line app that uses subcommands, each of which might accept different command-line options, is somewhat difficult with Ruby's built-in <tt>OptionParser</tt>. GLI provides an API that wraps <tt>OptionParser</tt> so that you can create a subcommand-based command-line app with minimal boilerplate. This API also produces complete documentation for your command-line app.
14
+
15
+ == Why is GLI's solution different from others?
16
+
17
+ There are other RubyGems that allow you to create a command-line app that takes subcommands. These solutions are often quite limited (e.g. they don't allow deeply nested subcommand structures or sophisticated command-line options per subcommand), or require more code that we think is needed. Some solutions make it difficult or impossible to properly document your command-line app.
18
+
19
+ == What you need to know to use GLI
20
+
21
+ You should know Ruby, and have a basic understanding of how the UNIX command line works: standard input, standard output, standard error, and exit codes.
22
+
15
23
  == Use
16
24
 
17
25
  Install if you need to:
18
26
 
19
27
  gem install gli
20
28
 
29
+ You can validate you have installed it correctly by running <tt>gli help</tt>. You should see formatted help output.
30
+
31
+ If you are using GLI in another application, add it to your <tt>Gemfile</tt>:
32
+
33
+ gem "gli"
34
+
35
+ You can test your install via Bundler by running <tt>bundle exec gli help</tt>. This should produce formatted help output from GLI.
36
+
37
+ == Getting Started
38
+
21
39
  The simplest way to get started is to create a scaffold project
22
40
 
23
41
  gli init todo list add complete
24
42
 
43
+ (note if you installed via Bundler you will need to execute <tt>bundle exec gli init todo list add complete</tt>)
44
+
25
45
  This will create a basic scaffold project in <tt>./todo</tt> with:
26
46
 
27
47
  * executable in <tt>./todo/bin/todo</tt>. This file demonstrates most of what you need to describe your command line interface.
data/bin/gli CHANGED
@@ -3,63 +3,66 @@
3
3
  require 'gli'
4
4
  require 'gli/commands/scaffold'
5
5
 
6
- include GLI::App
6
+ class App
7
+ extend GLI::App
7
8
 
8
- program_desc 'create scaffolding for a GLI-powered application'
9
+ program_desc 'create scaffolding for a GLI-powered application'
9
10
 
10
- version GLI::VERSION
11
+ version GLI::VERSION
11
12
 
12
- # Can't use these without changing the current behavior of gli
13
- # arguments :strict
14
- # subcommand_option_handling :normal
13
+ # Can't use these without changing the current behavior of gli
14
+ # arguments :strict
15
+ # subcommand_option_handling :normal
15
16
 
16
- switch :v, :desc => 'Be verbose'
17
+ switch :v, :desc => 'Be verbose'
17
18
 
18
- switch :n, :desc => 'Dry run; don''t change the disk'
19
+ switch :n, :desc => 'Dry run; don''t change the disk'
19
20
 
20
- desc 'Root dir of project'
21
+ desc 'Root dir of project'
21
22
  long_desc <<EOS
22
- This is the directory where the project''s directory will be made, so if you
23
- specify a project name ''foo'' and the root dir of ''.'', the directory
24
- ''./foo'' will be created'
23
+ This is the directory where the project''s directory will be made, so if you
24
+ specify a project name ''foo'' and the root dir of ''.'', the directory
25
+ ''./foo'' will be created'
25
26
  EOS
26
27
 
27
- flag :r,:root, :default_value => '.'
28
+ flag :r,:root, :default_value => '.'
28
29
 
29
- desc 'Create a new GLI-based project'
30
+ desc 'Create a new GLI-based project'
30
31
  long_desc <<EOS
31
- This will create a scaffold command line project that uses GLI
32
- for command line processing. Specifically, this will create
33
- an executable ready to go, as well as a lib and test directory, all
34
- inside the directory named for your project
32
+ This will create a scaffold command line project that uses GLI
33
+ for command line processing. Specifically, this will create
34
+ an executable ready to go, as well as a lib and test directory, all
35
+ inside the directory named for your project
35
36
  EOS
36
- arg :project_name
37
- arg :command_name, [:optional, :multiple]
38
- arg_name "project_name [command_name][, [command_name]]*"
39
- command [:init,:scaffold] do |c|
37
+ arg :project_name
38
+ arg :command_name, [:optional, :multiple]
39
+ arg_name "project_name [command_name]..."
40
+ command [:init,:scaffold] do |c|
40
41
 
41
- c.switch :e,:ext, :desc => 'Create an ext dir'
42
+ c.switch :e,:ext, :desc => 'Create an ext dir'
42
43
 
43
- c.switch :notest, :desc => 'Do not create a test or features dir', :negatable => false
44
+ c.switch :notest, :desc => 'Do not create a test or features dir', :negatable => false
44
45
 
45
- c.switch :force, :desc => 'Overwrite/ignore existing files and directories'
46
+ c.switch :force, :desc => 'Overwrite/ignore existing files and directories'
46
47
 
47
- c.switch :rvmrc, :desc => 'Create an .rvmrc based on your current RVM setup'
48
+ c.switch :rvmrc, :desc => 'Create an .rvmrc based on your current RVM setup'
48
49
 
49
- c.action do |g,o,args|
50
- if args.length < 1
51
- raise 'You must specify the name of your project'
50
+ c.action do |g,o,args|
51
+ if args.length < 1
52
+ raise 'You must specify the name of your project'
53
+ end
54
+ GLI::Commands::Scaffold.create_scaffold(g[:r],!o[:notest],o[:e],args[0],args[1..-1],o[:force],g[:n],o[:rvmrc])
52
55
  end
53
- GLI::Commands::Scaffold.create_scaffold(g[:r],!o[:notest],o[:e],args[0],args[1..-1],o[:force],g[:n],o[:rvmrc])
54
56
  end
55
- end
56
57
 
57
- pre do |global,command,options,args|
58
- puts "Executing #{command.name}" if global[:v]
59
- true
60
- end
58
+ pre do |global,command,options,args|
59
+ puts "Executing #{command.name}" if global[:v]
60
+ true
61
+ end
61
62
 
62
- post do |global,command,options,args|
63
- puts "Executed #{command.name}" if global[:v]
63
+ post do |global,command,options,args|
64
+ puts "Executed #{command.name}" if global[:v]
65
+ end
64
66
  end
65
- exit run(ARGV)
67
+
68
+ exit App.run(ARGV)
@@ -49,7 +49,7 @@ Feature: The GLI executable works as intended
49
49
  init - Create a new GLI-based project
50
50
 
51
51
  SYNOPSIS
52
- gli [global options] init [command options] project_name [command_name][, [command_name]]*
52
+ gli [global options] init [command options] project_name [command_name]...
53
53
 
54
54
  DESCRIPTION
55
55
  This will create a scaffold command line project that uses GLI for command
@@ -8,6 +8,7 @@ Feature: The scaffold GLI generates works
8
8
  And GLI's libs are in my path
9
9
  And my terminal size is "80x24"
10
10
 
11
+ @slow-command
11
12
  Scenario: Scaffold generates and things look good
12
13
  When I run `gli init --rvmrc todo add complete list`
13
14
  Then the exit status should be 0
@@ -35,6 +36,7 @@ Feature: The scaffold GLI generates works
35
36
  |todo/bin |
36
37
  |todo/test |
37
38
  |todo/lib |
39
+ |todo/.git |
38
40
  And the following files should exist:
39
41
  |todo/bin/todo |
40
42
  |todo/README.rdoc |
@@ -47,6 +49,8 @@ Feature: The scaffold GLI generates works
47
49
  |todo/lib/todo/version.rb |
48
50
  |todo/lib/todo.rb |
49
51
  |todo/.rvmrc |
52
+ And the file "todo/README.rdoc" should contain ":include:todo.rdoc"
53
+ And the file "todo/todo.rdoc" should contain "todo _doc"
50
54
  When I cd to "todo"
51
55
  And I make sure todo's lib dir is in my lib path
52
56
  And I run `bin/todo`
@@ -0,0 +1,5 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before '@slow-command' do
4
+ @aruba_timeout_seconds = 10
5
+ end
@@ -191,7 +191,7 @@ Feature: The todo app has a nice user interface
191
191
  list - List things, such as tasks or contexts
192
192
 
193
193
  SYNOPSIS
194
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
194
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
195
195
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
196
196
 
197
197
  DESCRIPTION
@@ -261,7 +261,7 @@ Feature: The todo app has a nice user interface
261
261
  list - List things, such as tasks or contexts
262
262
 
263
263
  SYNOPSIS
264
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
264
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
265
265
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
266
266
 
267
267
  DESCRIPTION
@@ -286,7 +286,7 @@ Feature: The todo app has a nice user interface
286
286
  list - List things, such as tasks or contexts
287
287
 
288
288
  SYNOPSIS
289
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
289
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
290
290
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
291
291
 
292
292
  DESCRIPTION
@@ -319,7 +319,7 @@ Feature: The todo app has a nice user interface
319
319
  list - List things, such as tasks or contexts
320
320
 
321
321
  SYNOPSIS
322
- todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]*
322
+ todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task]...
323
323
  todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar]
324
324
 
325
325
  DESCRIPTION
@@ -343,7 +343,7 @@ Feature: The todo app has a nice user interface
343
343
  tasks - List tasks
344
344
 
345
345
  SYNOPSIS
346
- todo [global options] list tasks [command options] [task][, [task]]*
346
+ todo [global options] list tasks [command options] [task]...
347
347
  todo [global options] list tasks [command options] open [--flag arg] [-x arg]
348
348
 
349
349
  DESCRIPTION
@@ -370,9 +370,9 @@ Feature: The todo app has a nice user interface
370
370
  todo [global options] create
371
371
  todo [global options] create contexts [context_name]
372
372
  todo [global options] create relation_1-1 first second [name]
373
- todo [global options] create relation_1-n first second[, second]* [name]
374
- todo [global options] create relation_n-1 first[, first]* second [name]
375
- todo [global options] create tasks task_name[, task_name]*
373
+ todo [global options] create relation_1-n first second... [name]
374
+ todo [global options] create relation_n-1 first... second [name]
375
+ todo [global options] create tasks task_name...
376
376
 
377
377
  COMMANDS
378
378
  <default> - Makes a new task
@@ -530,7 +530,7 @@ Feature: The todo app has a nice user interface
530
530
  list - List things, such as tasks or contexts
531
531
 
532
532
  SYNOPSIS
533
- todo [global options] list [command options] [tasks] [subcommand options] [task][, [task]]*
533
+ todo [global options] list [command options] [tasks] [subcommand options] [task]...
534
534
  todo [global options] list [command options] contexts [subcommand options]
535
535
 
536
536
  DESCRIPTION
@@ -92,7 +92,7 @@ Feature: The todo app is backwards compatible with legacy subcommand parsing
92
92
  SYNOPSIS
93
93
  todo [global options] create
94
94
  todo [global options] create contexts [context_name]
95
- todo [global options] create tasks task_name[, task_name]*
95
+ todo [global options] create tasks task_name...
96
96
 
97
97
  COMMANDS
98
98
  <default> - Makes a new task
@@ -20,7 +20,6 @@ spec = Gem::Specification.new do |s|
20
20
  s.extra_rdoc_files = ['README.rdoc', 'gli.rdoc']
21
21
  s.rdoc_options << '--title' << 'Git Like Interface' << '--main' << 'README.rdoc'
22
22
  s.bindir = 'bin'
23
- s.rubyforge_project = 'gli'
24
23
  s.add_development_dependency('rake', '~> 0.9.2.2')
25
24
  s.add_development_dependency('rdoc', '~> 4.2')
26
25
  s.add_development_dependency('rainbow', '~> 1.1', '~> 1.1.1')
data/gli.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
  == gli - create scaffolding for a GLI-powered application
2
2
 
3
- v2.12.1
3
+ v2.17.1
4
4
 
5
5
  === Global Options
6
6
  === -r|--root arg
@@ -8,9 +8,9 @@ v2.12.1
8
8
  Root dir of project
9
9
 
10
10
  [Default Value] .
11
- This is the directory where the project''s directory will be made, so if you
12
- specify a project name ''foo'' and the root dir of ''.'', the directory
13
- ''./foo'' will be created'
11
+ This is the directory where the project''s directory will be made, so if you
12
+ specify a project name ''foo'' and the root dir of ''.'', the directory
13
+ ''./foo'' will be created'
14
14
 
15
15
  === --help
16
16
  Show this message
@@ -33,3 +33,41 @@ Display the program version
33
33
 
34
34
 
35
35
  === Commands
36
+ ==== Command: <tt>help command</tt>
37
+ Shows a list of commands or help for one command
38
+
39
+ Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function
40
+ ===== Options
41
+ ===== -c
42
+ List commands one per line, to assist with shell completion
43
+
44
+
45
+
46
+ ==== Command: <tt>init|scaffold project_name [command_name][, [command_name]]*</tt>
47
+ Create a new GLI-based project
48
+
49
+ This will create a scaffold command line project that uses GLI
50
+ for command line processing. Specifically, this will create
51
+ an executable ready to go, as well as a lib and test directory, all
52
+ inside the directory named for your project
53
+ ===== Options
54
+ ===== -e|--[no-]ext
55
+ Create an ext dir
56
+
57
+
58
+
59
+ ===== --[no-]force
60
+ Overwrite/ignore existing files and directories
61
+
62
+
63
+
64
+ ===== --notest
65
+ Do not create a test or features dir
66
+
67
+
68
+
69
+ ===== --[no-]rvmrc
70
+ Create an .rvmrc based on your current RVM setup
71
+
72
+
73
+
data/lib/gli.rb CHANGED
@@ -24,6 +24,7 @@ require 'gli/commands/doc'
24
24
 
25
25
  module GLI
26
26
  include GLI::App
27
+
27
28
  def self.included(klass)
28
29
  warn "You should include GLI::App instead"
29
30
  end
@@ -22,7 +22,7 @@ module GLI
22
22
  arg_desc = "[#{arg_desc}]"
23
23
  end
24
24
  if arg.multiple?
25
- arg_desc = "#{arg_desc}[, #{arg_desc}]*"
25
+ arg_desc = "#{arg_desc}..."
26
26
  end
27
27
  desc = desc + " " + arg_desc
28
28
  end
@@ -37,7 +37,7 @@ module GLI
37
37
  desc = "[#{desc}]"
38
38
  end
39
39
  if arguments_options.include? :multiple
40
- desc = "#{desc}[, #{desc}]*"
40
+ desc = "#{desc}..."
41
41
  end
42
42
  " " + desc
43
43
  end
@@ -5,6 +5,7 @@ module GLI
5
5
  class RdocDocumentListener
6
6
 
7
7
  def initialize(global_options,options,arguments,app)
8
+ @app = app
8
9
  @io = File.new("#{app.exe_name}.rdoc",'w')
9
10
  @nest = ''
10
11
  @arg_name_formatter = GLI::Commands::HelpModules::ArgNameFormatter.new
@@ -31,6 +31,7 @@ module GLI
31
31
  end
32
32
  puts "Created #{rvmrc}"
33
33
  end
34
+ init_git(root_dir, project_name)
34
35
  end
35
36
  end
36
37
 
@@ -44,7 +45,7 @@ module GLI
44
45
  puts "Created #{root_dir}/#{project_name}/README.rdoc"
45
46
  File.open("#{root_dir}/#{project_name}/#{project_name}.rdoc",'w') do |file|
46
47
  file << "= #{project_name}\n\n"
47
- file << "Generate this with\n #{project_name} rdoc\nAfter you have described your command line interface"
48
+ file << "Generate this with\n #{project_name} _doc\nAfter you have described your command line interface"
48
49
  end
49
50
  puts "Created #{root_dir}/#{project_name}/#{project_name}.rdoc"
50
51
  end
@@ -277,85 +278,87 @@ rescue LoadError
277
278
  exit 64
278
279
  end
279
280
 
280
- include GLI::App
281
+ class App
282
+ extend GLI::App
281
283
 
282
- program_desc 'Describe your application here'
284
+ program_desc 'Describe your application here'
283
285
 
284
- version #{project_name_as_module_name(project_name)}::VERSION
286
+ version #{project_name_as_module_name(project_name)}::VERSION
285
287
 
286
- subcommand_option_handling :normal
287
- arguments :strict
288
+ subcommand_option_handling :normal
289
+ arguments :strict
288
290
 
289
- desc 'Describe some switch here'
290
- switch [:s,:switch]
291
+ desc 'Describe some switch here'
292
+ switch [:s,:switch]
291
293
 
292
- desc 'Describe some flag here'
293
- default_value 'the default'
294
- arg_name 'The name of the argument'
295
- flag [:f,:flagname]
294
+ desc 'Describe some flag here'
295
+ default_value 'the default'
296
+ arg_name 'The name of the argument'
297
+ flag [:f,:flagname]
296
298
  EOS
297
299
  first = true
298
300
  commands.each do |command|
299
301
  file.puts <<EOS
300
302
 
301
- desc 'Describe #{command} here'
302
- arg_name 'Describe arguments to #{command} here'
303
+ desc 'Describe #{command} here'
304
+ arg_name 'Describe arguments to #{command} here'
303
305
  EOS
304
306
  if first
305
307
  file.puts <<EOS
306
- command :#{command} do |c|
307
- c.desc 'Describe a switch to #{command}'
308
- c.switch :s
308
+ command :#{command} do |c|
309
+ c.desc 'Describe a switch to #{command}'
310
+ c.switch :s
309
311
 
310
- c.desc 'Describe a flag to #{command}'
311
- c.default_value 'default'
312
- c.flag :f
313
- c.action do |global_options,options,args|
312
+ c.desc 'Describe a flag to #{command}'
313
+ c.default_value 'default'
314
+ c.flag :f
315
+ c.action do |global_options,options,args|
314
316
 
315
- # Your command logic here
317
+ # Your command logic here
316
318
 
317
- # If you have any errors, just raise them
318
- # raise "that command made no sense"
319
+ # If you have any errors, just raise them
320
+ # raise "that command made no sense"
319
321
 
320
- puts "#{command} command ran"
322
+ puts "#{command} command ran"
323
+ end
321
324
  end
322
- end
323
325
  EOS
324
326
  else
325
327
  file.puts <<EOS
326
- command :#{command} do |c|
327
- c.action do |global_options,options,args|
328
- puts "#{command} command ran"
328
+ command :#{command} do |c|
329
+ c.action do |global_options,options,args|
330
+ puts "#{command} command ran"
331
+ end
329
332
  end
330
- end
331
333
  EOS
332
334
  end
333
335
  first = false
334
336
  end
335
337
  file.puts <<EOS
336
338
 
337
- pre do |global,command,options,args|
338
- # Pre logic here
339
- # Return true to proceed; false to abort and not call the
340
- # chosen command
341
- # Use skips_pre before a command to skip this block
342
- # on that command only
343
- true
344
- end
339
+ pre do |global,command,options,args|
340
+ # Pre logic here
341
+ # Return true to proceed; false to abort and not call the
342
+ # chosen command
343
+ # Use skips_pre before a command to skip this block
344
+ # on that command only
345
+ true
346
+ end
345
347
 
346
- post do |global,command,options,args|
347
- # Post logic here
348
- # Use skips_post before a command to skip this
349
- # block on that command only
350
- end
348
+ post do |global,command,options,args|
349
+ # Post logic here
350
+ # Use skips_post before a command to skip this
351
+ # block on that command only
352
+ end
351
353
 
352
- on_error do |exception|
353
- # Error logic here
354
- # return false to skip default error handling
355
- true
354
+ on_error do |exception|
355
+ # Error logic here
356
+ # return false to skip default error handling
357
+ true
358
+ end
356
359
  end
357
360
 
358
- exit run(ARGV)
361
+ exit App.run(ARGV)
359
362
  EOS
360
363
  puts "Created #{bin_file}"
361
364
  end
@@ -367,6 +370,14 @@ EOS
367
370
  true
368
371
  end
369
372
 
373
+ def self.init_git(root_dir, project_name)
374
+ project_dir = "#{root_dir}/#{project_name}"
375
+
376
+ unless system("git", "init", "--quiet", project_dir)
377
+ puts "There was a problem initializing Git. Your gemspec may not work until you have done a successful `git init`"
378
+ end
379
+ end
380
+
370
381
  def self.mkdirs(dirs,force,dry_run)
371
382
  exists = false
372
383
  if !force
@@ -50,7 +50,7 @@ module GLI
50
50
  # command :pack do ...
51
51
  #
52
52
  # Produces the synopsis:
53
- # app.rb [global options] pack output input[, input]*
53
+ # app.rb [global options] pack output input...
54
54
  def arg(name, options=[])
55
55
  @next_arguments ||= []
56
56
  @next_arguments << Argument.new(name, Array(options).flatten)
@@ -29,7 +29,7 @@ module GLI
29
29
  OptionParsingResult.new.tap { |parsing_result|
30
30
  parsing_result.arguments = args
31
31
  parsing_result = @global_option_parser.parse!(parsing_result)
32
- option_parser_class.new(@accepts).parse!(parsing_result, options[:argument_handling_strategy])
32
+ option_parser_class.new(@accepts).parse!(parsing_result, options[:argument_handling_strategy], options[:autocomplete])
33
33
  }
34
34
  end
35
35
 
@@ -117,7 +117,7 @@ module GLI
117
117
  }
118
118
  end
119
119
 
120
- def parse!(parsing_result,argument_handling_strategy)
120
+ def parse!(parsing_result,argument_handling_strategy,autocomplete)
121
121
  parsed_command_options = {}
122
122
  command = parsing_result.command
123
123
  arguments = nil
@@ -131,7 +131,7 @@ module GLI
131
131
  arguments = option_block_parser.parse!(arguments)
132
132
 
133
133
  parsed_command_options[command] = option_parser_factory.options_hash_with_defaults_set!
134
- command_finder = CommandFinder.new(command.commands, :default_command => command.get_default_command)
134
+ command_finder = CommandFinder.new(command.commands, :default_command => command.get_default_command, :autocomplete => autocomplete)
135
135
  next_command_name = arguments.shift
136
136
 
137
137
  verify_required_options!(command.flags, command, parsed_command_options[command])
@@ -178,7 +178,7 @@ module GLI
178
178
  end
179
179
 
180
180
  class LegacyCommandOptionParser < NormalCommandOptionParser
181
- def parse!(parsing_result,argument_handling_strategy)
181
+ def parse!(parsing_result,argument_handling_strategy,autocomplete)
182
182
  command = parsing_result.command
183
183
  option_parser_factory = OptionParserFactory.for_command(command,@accepts)
184
184
  option_block_parser = LegacyCommandOptionBlockParser.new(option_parser_factory, self.error_handler)
@@ -187,7 +187,7 @@ module GLI
187
187
  parsing_result.arguments = option_block_parser.parse!(parsing_result.arguments)
188
188
  parsing_result.command_options = option_parser_factory.options_hash_with_defaults_set!
189
189
 
190
- subcommand,args = find_subcommand(command,parsing_result.arguments)
190
+ subcommand,args = find_subcommand(command,parsing_result.arguments,autocomplete)
191
191
  parsing_result.command = subcommand
192
192
  parsing_result.arguments = args
193
193
  verify_required_options!(command.flags, parsing_result.command, parsing_result.command_options)
@@ -195,7 +195,7 @@ module GLI
195
195
 
196
196
  private
197
197
 
198
- def find_subcommand(command,arguments)
198
+ def find_subcommand(command,arguments,autocomplete)
199
199
  arguments = Array(arguments)
200
200
  command_name = if arguments.empty?
201
201
  nil
@@ -204,15 +204,15 @@ module GLI
204
204
  end
205
205
 
206
206
  default_command = command.get_default_command
207
- finder = CommandFinder.new(command.commands, :default_command => default_command.to_s)
207
+ finder = CommandFinder.new(command.commands, :default_command => default_command.to_s, :autocomplete => autocomplete)
208
208
 
209
209
  begin
210
210
  results = [finder.find_command(command_name),arguments[1..-1]]
211
- find_subcommand(results[0],results[1])
211
+ find_subcommand(results[0],results[1],autocomplete)
212
212
  rescue UnknownCommand, AmbiguousCommand
213
213
  begin
214
214
  results = [finder.find_command(default_command.to_s),arguments]
215
- find_subcommand(results[0],results[1])
215
+ find_subcommand(results[0],results[1],autocomplete)
216
216
  rescue UnknownCommand, AmbiguousCommand
217
217
  [command,arguments]
218
218
  end
@@ -1,5 +1,5 @@
1
1
  module GLI
2
2
  unless const_defined? :VERSION
3
- VERSION = '2.17.2'
3
+ VERSION = '2.19.1'
4
4
  end
5
5
  end
@@ -7,11 +7,11 @@ $: << File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
7
7
  require 'gli'
8
8
  require 'todo/version'
9
9
 
10
-
10
+ class App
11
11
  if ENV['GLI1_COMPATIBILITY']
12
- include GLI
12
+ extend GLI
13
13
  else
14
- include GLI::App
14
+ extend GLI::App
15
15
  end
16
16
 
17
17
  sort_help (ENV['TODO_SORT_HELP'] || 'alpha').to_sym
@@ -70,5 +70,5 @@ on_error do |exception|
70
70
  # return false to skip default error handling
71
71
  true
72
72
  end
73
-
74
- exit run(ARGV)
73
+ end
74
+ exit App.run(ARGV)
@@ -1,53 +1,54 @@
1
- desc "Create a new task or context"
2
- command [:create,:new] do |c|
3
- c.desc "Make a new task"
4
- c.arg_name 'task_name', :multiple
5
- c.arg :should_ignore_this
6
- c.command :tasks do |tasks|
7
- tasks.action do |global,options,args|
8
- puts "#{args}"
1
+ class App
2
+ desc "Create a new task or context"
3
+ command [:create,:new] do |c|
4
+ c.desc "Make a new task"
5
+ c.arg_name 'task_name', :multiple
6
+ c.arg :should_ignore_this
7
+ c.command :tasks do |tasks|
8
+ tasks.action do |global,options,args|
9
+ puts "#{args}"
10
+ end
9
11
  end
10
- end
11
12
 
12
- c.desc "Make a new context"
13
- c.arg :should_ignore_this
14
- c.arg_name 'context_name', :optional
15
- c.command :contexts do |contexts|
16
- contexts.action do |global,options,args|
17
- puts "#{args}"
13
+ c.desc "Make a new context"
14
+ c.arg :should_ignore_this
15
+ c.arg_name 'context_name', :optional
16
+ c.command :contexts do |contexts|
17
+ contexts.action do |global,options,args|
18
+ puts "#{args}"
19
+ end
18
20
  end
19
- end
20
21
 
21
- c.default_desc "Makes a new task"
22
- c.action do
23
- puts "default action"
24
- end
22
+ c.default_desc "Makes a new task"
23
+ c.action do
24
+ puts "default action"
25
+ end
25
26
 
26
- c.arg "first"
27
- c.arg "second"
28
- c.arg "name", :optional
29
- c.command :"relation_1-1" do |remote|
30
- remote.action do |global,options,args|
31
- puts "relation: #{args}"
27
+ c.arg "first"
28
+ c.arg "second"
29
+ c.arg "name", :optional
30
+ c.command :"relation_1-1" do |remote|
31
+ remote.action do |global,options,args|
32
+ puts "relation: #{args}"
33
+ end
32
34
  end
33
- end
34
35
 
35
- c.arg "first", :multiple
36
- c.arg "second"
37
- c.arg "name", :optional
38
- c.command :"relation_n-1" do |remote|
39
- remote.action do |global,options,args|
40
- puts "relation: #{args}"
36
+ c.arg "first", :multiple
37
+ c.arg "second"
38
+ c.arg "name", :optional
39
+ c.command :"relation_n-1" do |remote|
40
+ remote.action do |global,options,args|
41
+ puts "relation: #{args}"
42
+ end
41
43
  end
42
- end
43
44
 
44
- c.arg "first"
45
- c.arg "second", :multiple
46
- c.arg "name", :optional
47
- c.command :"relation_1-n" do |remote|
48
- remote.action do |global,options,args|
49
- puts "relation: #{args}"
45
+ c.arg "first"
46
+ c.arg "second", :multiple
47
+ c.arg "name", :optional
48
+ c.command :"relation_1-n" do |remote|
49
+ remote.action do |global,options,args|
50
+ puts "relation: #{args}"
51
+ end
50
52
  end
51
53
  end
52
54
  end
53
-
@@ -1,5 +1,6 @@
1
- desc "List things, such as tasks or contexts"
2
- long_desc %(
1
+ class App
2
+ desc "List things, such as tasks or contexts"
3
+ long_desc %(
3
4
  List a whole lot of things that you might be keeping track of
4
5
  in your overall todo list.
5
6
 
@@ -9,69 +10,69 @@ long_desc %(
9
10
  your todo databases.
10
11
  )
11
12
 
12
- command [:list] do |c|
13
- c.default_command :tasks
13
+ command [:list] do |c|
14
+ c.default_command :tasks
14
15
 
15
- c.desc "Show long form"
16
- c.switch [:l,:long]
16
+ c.desc "Show long form"
17
+ c.switch [:l,:long]
17
18
 
18
- c.flag :required_flag, :required => true
19
- c.flag :required_flag2, :required => true
19
+ c.flag :required_flag, :required => true
20
+ c.flag :required_flag2, :required => true
20
21
 
21
- c.desc "List tasks"
22
- c.long_desc %(
22
+ c.desc "List tasks"
23
+ c.long_desc %(
23
24
  Lists all of your tasks that you have, in varying orders, and
24
25
  all that stuff. Yes, this is long, but I need a long description.
25
26
  )
26
27
 
27
- c.arg :task, [:optional, :multiple]
28
- c.command :tasks do |tasks|
29
- tasks.desc "blah blah crud x whatever"
30
- tasks.flag [:x], :must_match => Array
28
+ c.arg :task, [:optional, :multiple]
29
+ c.command :tasks do |tasks|
30
+ tasks.desc "blah blah crud x whatever"
31
+ tasks.flag [:x], :must_match => Array
31
32
 
32
- tasks.flag :flag
33
+ tasks.flag :flag
33
34
 
34
- tasks.action do |global,options,args|
35
- puts options[:x].inspect
36
- puts "list tasks: #{args.join(',')}"
37
- end
35
+ tasks.action do |global,options,args|
36
+ puts options[:x].inspect
37
+ puts "list tasks: #{args.join(',')}"
38
+ end
38
39
 
39
- tasks.desc 'list open tasks'
40
- tasks.command :open do |open|
41
- open.desc "blah blah crud x whatever"
42
- open.flag [:x], :must_match => Array
40
+ tasks.desc 'list open tasks'
41
+ tasks.command :open do |open|
42
+ open.desc "blah blah crud x whatever"
43
+ open.flag [:x], :must_match => Array
43
44
 
44
- open.flag :flag
45
+ open.flag :flag
45
46
 
46
- open.example "todo list tasks open --flag=blah", desc: "example number 1"
47
- open.example "todo list tasks open -x foo"
47
+ open.example "todo list tasks open --flag=blah", desc: "example number 1"
48
+ open.example "todo list tasks open -x foo"
48
49
 
49
- open.action do |global,options,args|
50
- puts "tasks open"
50
+ open.action do |global,options,args|
51
+ puts "tasks open"
52
+ end
51
53
  end
52
- end
53
54
 
54
- tasks.default_desc 'list all tasks'
55
- end
55
+ tasks.default_desc 'list all tasks'
56
+ end
56
57
 
57
- c.desc "List contexts"
58
- c.long_desc %(
58
+ c.desc "List contexts"
59
+ c.long_desc %(
59
60
  Lists all of your contexts, which are places you might be
60
61
  where you can do stuff and all that.
61
62
  )
62
- c.command :contexts do |contexts|
63
+ c.command :contexts do |contexts|
63
64
 
64
- contexts.desc "Foobar"
65
- contexts.switch [:f,'foobar']
65
+ contexts.desc "Foobar"
66
+ contexts.switch [:f,'foobar']
66
67
 
67
- contexts.desc "Blah"
68
- contexts.switch [:b]
68
+ contexts.desc "Blah"
69
+ contexts.switch [:b]
69
70
 
70
- contexts.flag :otherflag
71
+ contexts.flag :otherflag
71
72
 
72
- contexts.action do |global,options,args|
73
- puts "list contexts: #{args.join(',')}"
73
+ contexts.action do |global,options,args|
74
+ puts "list contexts: #{args.join(',')}"
75
+ end
74
76
  end
75
77
  end
76
78
  end
77
-
@@ -1,6 +1,7 @@
1
- # This is copied so I can have two slightly different versions of the same thing
2
- desc "LS things, such as tasks or contexts"
3
- long_desc %(
1
+ class App
2
+ # This is copied so I can have two slightly different versions of the same thing
3
+ desc "LS things, such as tasks or contexts"
4
+ long_desc %(
4
5
  List a whole lot of things that you might be keeping track of
5
6
  in your overall todo list.
6
7
 
@@ -9,39 +10,39 @@ long_desc %(
9
10
  stored in
10
11
  your todo databases.
11
12
  )
12
- command [:ls] do |c|
13
- c.desc "Show long form"
14
- c.switch [:l,:long]
13
+ command [:ls] do |c|
14
+ c.desc "Show long form"
15
+ c.switch [:l,:long]
15
16
 
16
- c.desc "List tasks"
17
- c.long_desc %(
17
+ c.desc "List tasks"
18
+ c.long_desc %(
18
19
  Lists all of your tasks that you have, in varying orders, and
19
20
  all that stuff. Yes, this is long, but I need a long description.
20
21
  )
21
- c.command :tasks do |tasks|
22
- tasks.desc "blah blah crud x whatever"
23
- tasks.flag [:x]
24
- tasks.action do |global,options,args|
25
- puts "ls tasks: #{args.join(',')}"
22
+ c.command :tasks do |tasks|
23
+ tasks.desc "blah blah crud x whatever"
24
+ tasks.flag [:x]
25
+ tasks.action do |global,options,args|
26
+ puts "ls tasks: #{args.join(',')}"
27
+ end
26
28
  end
27
- end
28
29
 
29
- c.desc "List contexts"
30
- c.long_desc %(
30
+ c.desc "List contexts"
31
+ c.long_desc %(
31
32
  Lists all of your contexts, which are places you might be
32
33
  where you can do stuff and all that.
33
34
  )
34
- c.command :contexts do |contexts|
35
+ c.command :contexts do |contexts|
35
36
 
36
- contexts.desc "Foobar"
37
- contexts.switch [:f,'foobar']
37
+ contexts.desc "Foobar"
38
+ contexts.switch [:f,'foobar']
38
39
 
39
- contexts.desc "Blah"
40
- contexts.switch [:b]
40
+ contexts.desc "Blah"
41
+ contexts.switch [:b]
41
42
 
42
- contexts.action do |global,options,args|
43
- puts "ls contexts: #{args.join(',')}"
43
+ contexts.action do |global,options,args|
44
+ puts "ls contexts: #{args.join(',')}"
45
+ end
44
46
  end
45
47
  end
46
48
  end
47
-
@@ -1,53 +1,55 @@
1
- command [:make] do |c|
2
- c.desc "Show long form"
3
- c.flag [:l,:long]
1
+ class App
2
+ command [:make] do |c|
3
+ c.desc "Show long form"
4
+ c.flag [:l,:long]
4
5
 
5
- c.desc 'make a new task'
6
- c.command :task do |task|
7
- task.desc 'make the task a long task'
8
- task.flag [:l,:long]
6
+ c.desc 'make a new task'
7
+ c.command :task do |task|
8
+ task.desc 'make the task a long task'
9
+ task.flag [:l,:long]
9
10
 
10
- task.action do |g,o,a|
11
- puts 'new task'
12
- puts a.join(',')
13
- puts o[:long]
11
+ task.action do |g,o,a|
12
+ puts 'new task'
13
+ puts a.join(',')
14
+ puts o[:long]
15
+ end
16
+
17
+ task.desc 'make a bug'
18
+ task.arg :argument, [:multiple, :optional]
19
+ task.command :bug do |bug|
20
+ bug.desc 'make this bug in the legacy system'
21
+ bug.flag [:l,:legacy]
22
+
23
+ bug.action do |g,o,a|
24
+ puts 'new task bug'
25
+ puts a.join(',')
26
+ # All this .to_s is to make sure 1.8.7/REE don't convert nil to the string "nil"
27
+ puts o[:legacy].to_s
28
+ puts o[:long].to_s
29
+ puts o[:l].to_s
30
+ puts o[GLI::Command::PARENT][:l].to_s
31
+ puts o[GLI::Command::PARENT][:long].to_s
32
+ puts o[GLI::Command::PARENT][:legacy].to_s
33
+ puts o[GLI::Command::PARENT][GLI::Command::PARENT][:l].to_s
34
+ puts o[GLI::Command::PARENT][GLI::Command::PARENT][:long].to_s
35
+ puts o[GLI::Command::PARENT][GLI::Command::PARENT][:legacy].to_s
36
+ end
37
+ end
14
38
  end
15
39
 
16
- task.desc 'make a bug'
17
- task.arg :argument, [:multiple, :optional]
18
- task.command :bug do |bug|
19
- bug.desc 'make this bug in the legacy system'
20
- bug.flag [:l,:legacy]
40
+ c.desc 'make a new context'
41
+ c.command :context do |context|
42
+ context.desc 'make the context a local context'
43
+ context.flag [:l,:local]
21
44
 
22
- bug.action do |g,o,a|
23
- puts 'new task bug'
45
+ context.action do |g,o,a|
46
+ puts 'new context'
24
47
  puts a.join(',')
25
- # All this .to_s is to make sure 1.8.7/REE don't convert nil to the string "nil"
26
- puts o[:legacy].to_s
48
+ puts o[:local].to_s
27
49
  puts o[:long].to_s
28
50
  puts o[:l].to_s
29
- puts o[GLI::Command::PARENT][:l].to_s
30
- puts o[GLI::Command::PARENT][:long].to_s
31
- puts o[GLI::Command::PARENT][:legacy].to_s
32
- puts o[GLI::Command::PARENT][GLI::Command::PARENT][:l].to_s
33
- puts o[GLI::Command::PARENT][GLI::Command::PARENT][:long].to_s
34
- puts o[GLI::Command::PARENT][GLI::Command::PARENT][:legacy].to_s
35
51
  end
36
52
  end
37
- end
38
-
39
- c.desc 'make a new context'
40
- c.command :context do |context|
41
- context.desc 'make the context a local context'
42
- context.flag [:l,:local]
43
53
 
44
- context.action do |g,o,a|
45
- puts 'new context'
46
- puts a.join(',')
47
- puts o[:local].to_s
48
- puts o[:long].to_s
49
- puts o[:l].to_s
50
- end
51
54
  end
52
-
53
55
  end
@@ -1 +1,3 @@
1
+ class App
1
2
  command :third do |c| c.action { |g,o,a| puts "third: #{a.join(',')}" } end
3
+ end
@@ -78,6 +78,31 @@ class TC_testSubCommandParsing < Clean::Test::TestCase
78
78
  }
79
79
  end
80
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
+
81
106
  test_that "in loose mode, argument validation is ignored" do
82
107
  Given :app_with_arguments, 1, 1, false, :loose
83
108
  When :run_app_with_X_arguments, 0
@@ -160,6 +185,41 @@ private
160
185
  raise
161
186
  end
162
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
+
163
223
  def app_with_subcommands_storing_results(subcommand_option_handling_strategy = :legacy)
164
224
  @app.subcommand_option_handling subcommand_option_handling_strategy
165
225
  @app.flag ['f','flag']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.2
4
+ version: 2.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Copeland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-18 00:00:00.000000000 Z
11
+ date: 2020-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -156,6 +156,7 @@ files:
156
156
  - ".gitignore"
157
157
  - ".ruby-gemset"
158
158
  - ".ruby-version"
159
+ - ".tool-versions"
159
160
  - ".travis.yml"
160
161
  - CONTRIBUTING.md
161
162
  - Gemfile
@@ -172,6 +173,7 @@ files:
172
173
  - features/step_definitions/gli_init_steps.rb
173
174
  - features/step_definitions/todo_steps.rb
174
175
  - features/support/env.rb
176
+ - features/support/hooks.rb
175
177
  - features/todo.feature
176
178
  - features/todo_legacy.feature
177
179
  - gli.cheat
@@ -283,8 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
285
  - !ruby/object:Gem::Version
284
286
  version: '0'
285
287
  requirements: []
286
- rubyforge_project: gli
287
- rubygems_version: 2.7.6
288
+ rubygems_version: 3.1.2
288
289
  signing_key:
289
290
  specification_version: 4
290
291
  summary: Build command-suite CLI apps that are awesome.
@@ -295,6 +296,7 @@ test_files:
295
296
  - features/step_definitions/gli_init_steps.rb
296
297
  - features/step_definitions/todo_steps.rb
297
298
  - features/support/env.rb
299
+ - features/support/hooks.rb
298
300
  - features/todo.feature
299
301
  - features/todo_legacy.feature
300
302
  - test/apps/README.md