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 +4 -4
- data/.tool-versions +1 -0
- data/README.rdoc +26 -6
- data/bin/gli +41 -38
- data/features/gli_executable.feature +1 -1
- data/features/gli_init.feature +4 -0
- data/features/support/hooks.rb +5 -0
- data/features/todo.feature +9 -9
- data/features/todo_legacy.feature +1 -1
- data/gli.gemspec +0 -1
- data/gli.rdoc +42 -4
- data/lib/gli.rb +1 -0
- data/lib/gli/commands/help_modules/arg_name_formatter.rb +2 -2
- data/lib/gli/commands/rdoc_document_listener.rb +1 -0
- data/lib/gli/commands/scaffold.rb +59 -48
- data/lib/gli/dsl.rb +1 -1
- data/lib/gli/gli_option_parser.rb +9 -9
- data/lib/gli/version.rb +1 -1
- data/test/apps/todo/bin/todo +5 -5
- data/test/apps/todo/lib/todo/commands/create.rb +42 -41
- data/test/apps/todo/lib/todo/commands/list.rb +43 -42
- data/test/apps/todo/lib/todo/commands/ls.rb +25 -24
- data/test/apps/todo/lib/todo/commands/make.rb +42 -40
- data/test/apps/todo_plugins/commands/third.rb +2 -0
- data/test/tc_subcommand_parsing.rb +60 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 635c14c43560039c5a46a367a501201b6d255dfb850d1280a8300e0c5b7f9ab8
|
4
|
+
data.tar.gz: 0d82f1d19eb5f41a91cdee92f3acf1732b84f93ff9e6353a4e18ad438a5f259a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae6e5aa99a45658686fdbd6cb0e7835c66f0761f8cb0a7e7822265e963d08830441ba6024b747bd0a077152110b55b7c7726bdb55178b1b188bfe2e9804b3968
|
7
|
+
data.tar.gz: '0396dc0ac0290db90f9715bf4b3f3352394003403b81fe0b0c1c6b57af5f981983ac7e691bf17d1e68e9dee80358b9e87991407137a4824464270c4574d468b8'
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 2.7.1
|
data/README.rdoc
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
= Git-Like Interface Command Line Parser
|
1
|
+
= GLI, the Git-Like Interface Command Line Parser
|
2
2
|
|
3
|
-
GLI
|
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
|
-
|
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]
|
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
|
-
|
42
|
+
c.switch :e,:ext, :desc => 'Create an ext dir'
|
42
43
|
|
43
|
-
|
44
|
+
c.switch :notest, :desc => 'Do not create a test or features dir', :negatable => false
|
44
45
|
|
45
|
-
|
46
|
+
c.switch :force, :desc => 'Overwrite/ignore existing files and directories'
|
46
47
|
|
47
|
-
|
48
|
+
c.switch :rvmrc, :desc => 'Create an .rvmrc based on your current RVM setup'
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
59
|
-
|
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
|
-
|
63
|
+
post do |global,command,options,args|
|
64
|
+
puts "Executed #{command.name}" if global[:v]
|
65
|
+
end
|
64
66
|
end
|
65
|
-
|
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]
|
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
|
data/features/gli_init.feature
CHANGED
@@ -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`
|
data/features/todo.feature
CHANGED
@@ -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]
|
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]
|
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]
|
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]
|
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]
|
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
|
374
|
-
todo [global options] create relation_n-1 first
|
375
|
-
todo [global options] create tasks 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]
|
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
|
95
|
+
todo [global options] create tasks task_name...
|
96
96
|
|
97
97
|
COMMANDS
|
98
98
|
<default> - Makes a new task
|
data/gli.gemspec
CHANGED
@@ -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.
|
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
@@ -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}
|
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}
|
40
|
+
desc = "#{desc}..."
|
41
41
|
end
|
42
42
|
" " + desc
|
43
43
|
end
|
@@ -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}
|
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
|
-
|
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
|
-
|
308
|
-
|
308
|
+
command :#{command} do |c|
|
309
|
+
c.desc 'Describe a switch to #{command}'
|
310
|
+
c.switch :s
|
309
311
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
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
|
-
|
317
|
+
# Your command logic here
|
316
318
|
|
317
|
-
|
318
|
-
|
319
|
+
# If you have any errors, just raise them
|
320
|
+
# raise "that command made no sense"
|
319
321
|
|
320
|
-
|
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
|
-
|
328
|
-
|
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
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
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
|
-
|
348
|
-
|
349
|
-
|
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
|
-
|
354
|
-
|
355
|
-
|
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
|
data/lib/gli/dsl.rb
CHANGED
@@ -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
|
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
|
data/lib/gli/version.rb
CHANGED
data/test/apps/todo/bin/todo
CHANGED
@@ -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
|
-
|
12
|
+
extend GLI
|
13
13
|
else
|
14
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
c.default_desc "Makes a new task"
|
23
|
+
c.action do
|
24
|
+
puts "default action"
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
2
|
-
|
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
|
-
|
13
|
+
command [:list] do |c|
|
14
|
+
c.default_command :tasks
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
c.desc "Show long form"
|
17
|
+
c.switch [:l,:long]
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
c.flag :required_flag, :required => true
|
20
|
+
c.flag :required_flag2, :required => true
|
20
21
|
|
21
|
-
|
22
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
+
tasks.flag :flag
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
tasks.action do |global,options,args|
|
36
|
+
puts options[:x].inspect
|
37
|
+
puts "list tasks: #{args.join(',')}"
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
45
|
+
open.flag :flag
|
45
46
|
|
46
|
-
|
47
|
-
|
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
|
-
|
50
|
-
|
50
|
+
open.action do |global,options,args|
|
51
|
+
puts "tasks open"
|
52
|
+
end
|
51
53
|
end
|
52
|
-
end
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
tasks.default_desc 'list all tasks'
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
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
|
-
|
63
|
+
c.command :contexts do |contexts|
|
63
64
|
|
64
|
-
|
65
|
-
|
65
|
+
contexts.desc "Foobar"
|
66
|
+
contexts.switch [:f,'foobar']
|
66
67
|
|
67
|
-
|
68
|
-
|
68
|
+
contexts.desc "Blah"
|
69
|
+
contexts.switch [:b]
|
69
70
|
|
70
|
-
|
71
|
+
contexts.flag :otherflag
|
71
72
|
|
72
|
-
|
73
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
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
|
-
|
14
|
-
|
13
|
+
command [:ls] do |c|
|
14
|
+
c.desc "Show long form"
|
15
|
+
c.switch [:l,:long]
|
15
16
|
|
16
|
-
|
17
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
35
|
+
c.command :contexts do |contexts|
|
35
36
|
|
36
|
-
|
37
|
-
|
37
|
+
contexts.desc "Foobar"
|
38
|
+
contexts.switch [:f,'foobar']
|
38
39
|
|
39
|
-
|
40
|
-
|
40
|
+
contexts.desc "Blah"
|
41
|
+
contexts.switch [:b]
|
41
42
|
|
42
|
-
|
43
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class App
|
2
|
+
command [:make] do |c|
|
3
|
+
c.desc "Show long form"
|
4
|
+
c.flag [:l,:long]
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
23
|
-
puts 'new
|
45
|
+
context.action do |g,o,a|
|
46
|
+
puts 'new context'
|
24
47
|
puts a.join(',')
|
25
|
-
|
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
|
@@ -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.
|
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:
|
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
|
-
|
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
|