gli 2.17.2 → 2.19.1

Sign up to get free protection for your applications and to get access to all the features.
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