gli 2.5.6 → 2.6.0.rc1
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.
- data/.travis.yml +1 -0
- data/Gemfile +1 -1
- data/features/step_definitions/todo_steps.rb +4 -0
- data/features/todo.feature +22 -0
- data/features/todo_legacy.feature +128 -0
- data/lib/gli.rb +3 -1
- data/lib/gli/app.rb +10 -2
- data/lib/gli/app_support.rb +39 -31
- data/lib/gli/command.rb +3 -2
- data/lib/gli/command_finder.rb +41 -0
- data/lib/gli/command_line_token.rb +0 -4
- data/lib/gli/command_support.rb +37 -64
- data/lib/gli/commands/doc.rb +12 -2
- data/lib/gli/commands/help.rb +3 -0
- data/lib/gli/commands/help_modules/command_help_format.rb +22 -5
- data/lib/gli/commands/scaffold.rb +1 -1
- data/lib/gli/exceptions.rb +17 -5
- data/lib/gli/gli_option_block_parser.rb +84 -0
- data/lib/gli/gli_option_parser.rb +116 -96
- data/lib/gli/option_parser_factory.rb +42 -10
- data/lib/gli/option_parsing_result.rb +19 -0
- data/lib/gli/version.rb +1 -1
- data/test/apps/todo/bin/todo +2 -0
- data/test/apps/todo/lib/todo/commands/make.rb +52 -0
- data/test/apps/todo_legacy/Gemfile +2 -0
- data/test/apps/todo_legacy/README.rdoc +6 -0
- data/test/apps/todo_legacy/Rakefile +23 -0
- data/test/apps/todo_legacy/bin/todo +61 -0
- data/test/apps/todo_legacy/lib/todo/commands/create.rb +24 -0
- data/test/apps/todo_legacy/lib/todo/commands/list.rb +63 -0
- data/test/apps/todo_legacy/lib/todo/commands/ls.rb +47 -0
- data/test/apps/todo_legacy/lib/todo/version.rb +3 -0
- data/test/apps/todo_legacy/test/tc_nothing.rb +14 -0
- data/test/apps/todo_legacy/todo.gemspec +23 -0
- data/test/apps/todo_legacy/todo.rdoc +5 -0
- data/test/tc_command.rb +84 -59
- data/test/{tc_compount_command.rb → tc_compound_command.rb} +0 -0
- data/test/tc_flag.rb +0 -1
- data/test/tc_gli.rb +2 -2
- data/test/tc_help.rb +11 -3
- data/test/tc_subcommand_parsing.rb +104 -0
- data/test/tc_subcommands.rb +1 -0
- data/test/tc_switch.rb +0 -1
- data/test/test_helper.rb +5 -0
- metadata +74 -13
- data/lib/gli/copy_options_to_aliases.rb +0 -33
@@ -1,27 +1,47 @@
|
|
1
1
|
module GLI
|
2
2
|
# Factory for creating an OptionParser based on app configuration and DSL calls
|
3
3
|
class OptionParserFactory
|
4
|
+
|
5
|
+
# Create an option parser factory for a command. This has the added
|
6
|
+
# feature of setting up -h and --help on the command if those
|
7
|
+
# options aren't otherwise configured, e.g. to allow todo add --help as an
|
8
|
+
# alternate to todo help add
|
9
|
+
def self.for_command(command,accepts)
|
10
|
+
self.new(command.flags,command.switches,accepts).tap { |factory|
|
11
|
+
add_help_switches_to_command(factory.option_parser,command)
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
4
15
|
# Create an OptionParserFactory for the given
|
5
16
|
# flags, switches, and accepts
|
6
17
|
def initialize(flags,switches,accepts)
|
7
18
|
@flags = flags
|
8
19
|
@switches = switches
|
9
|
-
@
|
20
|
+
@options_hash = {}
|
21
|
+
@option_parser = OptionParser.new do |opts|
|
22
|
+
self.class.setup_accepts(opts,accepts)
|
23
|
+
self.class.setup_options(opts,@switches,@options_hash)
|
24
|
+
self.class.setup_options(opts,@flags,@options_hash)
|
25
|
+
end
|
10
26
|
end
|
11
27
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
[option_parser,options]
|
28
|
+
attr_reader :option_parser
|
29
|
+
attr_reader :options_hash
|
30
|
+
|
31
|
+
def options_hash_with_defaults_set!
|
32
|
+
set_defaults(@flags,@options_hash)
|
33
|
+
set_defaults(@switches,@options_hash)
|
34
|
+
@options_hash
|
21
35
|
end
|
22
36
|
|
23
37
|
private
|
24
38
|
|
39
|
+
def set_defaults(options_by_name,options_hash)
|
40
|
+
options_by_name.each do |name,option|
|
41
|
+
options_hash[name] = option.default_value if options_hash[name].nil?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
25
45
|
def self.setup_accepts(opts,accepts)
|
26
46
|
accepts.each do |object,block|
|
27
47
|
opts.accept(object) do |arg_as_string|
|
@@ -41,5 +61,17 @@ module GLI
|
|
41
61
|
end
|
42
62
|
end
|
43
63
|
|
64
|
+
def self.add_help_switches_to_command(option_parser,command)
|
65
|
+
help_args = %w(-h --help).reject { |_| command.has_option?(_) }
|
66
|
+
|
67
|
+
unless help_args.empty?
|
68
|
+
help_args << "Get help for #{command.name}"
|
69
|
+
option_parser.on(*help_args) do
|
70
|
+
raise CommandException.new(nil,command,0)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
44
76
|
end
|
45
77
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GLI
|
2
|
+
class OptionParsingResult
|
3
|
+
attr_accessor :global_options
|
4
|
+
attr_accessor :command
|
5
|
+
attr_accessor :command_options
|
6
|
+
attr_accessor :arguments
|
7
|
+
|
8
|
+
def convert_to_openstruct!
|
9
|
+
@global_options = Options.new(@global_options)
|
10
|
+
@command_options = Options.new(@command_options)
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
# Allows us to splat this object into blocks and methods expecting parameters in this order
|
15
|
+
def to_a
|
16
|
+
[@global_options,@command,@command_options,@arguments]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/gli/version.rb
CHANGED
data/test/apps/todo/bin/todo
CHANGED
@@ -17,6 +17,8 @@ end
|
|
17
17
|
sort_help (ENV['TODO_SORT_HELP'] || 'alpha').to_sym
|
18
18
|
wrap_help_text (ENV['TODO_WRAP_HELP_TEXT'] || 'to_terminal').to_sym
|
19
19
|
|
20
|
+
subcommand_option_handling :normal
|
21
|
+
|
20
22
|
program_desc 'Manages tasks'
|
21
23
|
program_long_desc "A test program that has a sophisticated UI that can be used to exercise a lot of GLI's power"
|
22
24
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
command [:make] do |c|
|
2
|
+
c.desc "Show long form"
|
3
|
+
c.flag [:l,:long]
|
4
|
+
|
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]
|
9
|
+
|
10
|
+
task.action do |g,o,a|
|
11
|
+
puts 'new task'
|
12
|
+
puts a.join(',')
|
13
|
+
puts o[:long]
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'make a bug'
|
17
|
+
task.command :bug do |bug|
|
18
|
+
bug.desc 'make this bug in the legacy system'
|
19
|
+
bug.flag [:l,:legacy]
|
20
|
+
|
21
|
+
bug.action do |g,o,a|
|
22
|
+
puts 'new task bug'
|
23
|
+
puts a.join(',')
|
24
|
+
# All this .to_s is to make sure 1.8.7/REE don't convert nil to the string "nil"
|
25
|
+
puts o[:legacy].to_s
|
26
|
+
puts o[:long].to_s
|
27
|
+
puts o[:l].to_s
|
28
|
+
puts o[GLI::Command::PARENT][:l].to_s
|
29
|
+
puts o[GLI::Command::PARENT][:long].to_s
|
30
|
+
puts o[GLI::Command::PARENT][:legacy].to_s
|
31
|
+
puts o[GLI::Command::PARENT][GLI::Command::PARENT][:l].to_s
|
32
|
+
puts o[GLI::Command::PARENT][GLI::Command::PARENT][:long].to_s
|
33
|
+
puts o[GLI::Command::PARENT][GLI::Command::PARENT][:legacy].to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
c.desc 'make a new context'
|
39
|
+
c.command :context do |context|
|
40
|
+
context.desc 'make the context a local context'
|
41
|
+
context.flag [:l,:local]
|
42
|
+
|
43
|
+
context.action do |g,o,a|
|
44
|
+
puts 'new context'
|
45
|
+
puts a.join(',')
|
46
|
+
puts o[:local].to_s
|
47
|
+
puts o[:long].to_s
|
48
|
+
puts o[:l].to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
|
6
|
+
Rake::RDocTask.new do |rd|
|
7
|
+
rd.main = "README.rdoc"
|
8
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
9
|
+
rd.title = 'Your application title'
|
10
|
+
end
|
11
|
+
|
12
|
+
spec = eval(File.read('todo.gemspec'))
|
13
|
+
|
14
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'rake/testtask'
|
18
|
+
Rake::TestTask.new do |t|
|
19
|
+
t.libs << "test"
|
20
|
+
t.test_files = FileList['test/tc_*.rb']
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :test
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# These would not be in a real GLI app; we do this so we can easily run this on the command line
|
4
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','lib'))
|
5
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
|
6
|
+
|
7
|
+
require 'gli'
|
8
|
+
require 'todo/version'
|
9
|
+
|
10
|
+
|
11
|
+
if ENV['GLI1_COMPATIBILITY']
|
12
|
+
include GLI
|
13
|
+
else
|
14
|
+
include GLI::App
|
15
|
+
end
|
16
|
+
|
17
|
+
sort_help (ENV['TODO_SORT_HELP'] || 'alpha').to_sym
|
18
|
+
wrap_help_text (ENV['TODO_WRAP_HELP_TEXT'] || 'to_terminal').to_sym
|
19
|
+
|
20
|
+
program_desc 'Manages tasks'
|
21
|
+
program_long_desc "A test program that has a sophisticated UI that can be used to exercise a lot of GLI's power"
|
22
|
+
|
23
|
+
config_file "gli_test_todo.rc"
|
24
|
+
|
25
|
+
flag :flag
|
26
|
+
switch :switch
|
27
|
+
switch :otherswitch, :negatable => true
|
28
|
+
|
29
|
+
version Todo::VERSION
|
30
|
+
|
31
|
+
commands_from 'todo/commands'
|
32
|
+
commands_from File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'todo_plugins', 'commands'))
|
33
|
+
|
34
|
+
command :first do |c| c.action { |g,o,a| puts "first: #{a.join(',')}" } end
|
35
|
+
command :second do |c| c.action { |g,o,a| puts "second: #{a.join(',')}" } end
|
36
|
+
|
37
|
+
command :chained => [ :first, :second ]
|
38
|
+
command [:chained2,:ch2] => [ :second, :first ]
|
39
|
+
|
40
|
+
pre do |global,command,options,args|
|
41
|
+
# Pre logic here
|
42
|
+
# Return true to proceed; false to abort and not call the
|
43
|
+
# chosen command
|
44
|
+
# Use skips_pre before a command to skip this block
|
45
|
+
# on that command only
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
post do |global,command,options,args|
|
50
|
+
# Post logic here
|
51
|
+
# Use skips_post before a command to skip this
|
52
|
+
# block on that command only
|
53
|
+
end
|
54
|
+
|
55
|
+
on_error do |exception|
|
56
|
+
# Error logic here
|
57
|
+
# return false to skip default error handling
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
exit run(ARGV)
|
@@ -0,0 +1,24 @@
|
|
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.command :tasks do |tasks|
|
6
|
+
tasks.action do |global,options,args|
|
7
|
+
puts "#{args}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
c.desc "Make a new context"
|
12
|
+
c.arg_name 'context_name', :optional
|
13
|
+
c.command :contexts do |contexts|
|
14
|
+
contexts.action do |global,options,args|
|
15
|
+
puts "#{args}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
c.default_desc "Makes a new task"
|
20
|
+
c.action do
|
21
|
+
puts "default action"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
desc "List things, such as tasks or contexts"
|
2
|
+
long_desc %(
|
3
|
+
List a whole lot of things that you might be keeping track of
|
4
|
+
in your overall todo list.
|
5
|
+
|
6
|
+
This is your go-to place or finding all of the things that you
|
7
|
+
might have
|
8
|
+
stored in
|
9
|
+
your todo databases.
|
10
|
+
)
|
11
|
+
command [:list] do |c|
|
12
|
+
c.default_command :tasks
|
13
|
+
|
14
|
+
c.desc "Show long form"
|
15
|
+
c.switch [:l,:long]
|
16
|
+
|
17
|
+
c.desc "List tasks"
|
18
|
+
c.long_desc %(
|
19
|
+
Lists all of your tasks that you have, in varying orders, and
|
20
|
+
all that stuff. Yes, this is long, but I need a long description.
|
21
|
+
)
|
22
|
+
c.command :tasks do |tasks|
|
23
|
+
tasks.desc "blah blah crud x whatever"
|
24
|
+
tasks.flag [:x], :must_match => Array
|
25
|
+
|
26
|
+
tasks.flag :flag
|
27
|
+
|
28
|
+
tasks.action do |global,options,args|
|
29
|
+
puts options[:x].inspect
|
30
|
+
puts "list tasks: #{args.join(',')}"
|
31
|
+
end
|
32
|
+
|
33
|
+
tasks.desc 'list open tasks'
|
34
|
+
tasks.command :open do |open|
|
35
|
+
open.action do |global,options,args|
|
36
|
+
puts "tasks open"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
tasks.default_desc 'list all tasks'
|
41
|
+
end
|
42
|
+
|
43
|
+
c.desc "List contexts"
|
44
|
+
c.long_desc %(
|
45
|
+
Lists all of your contexts, which are places you might be
|
46
|
+
where you can do stuff and all that.
|
47
|
+
)
|
48
|
+
c.command :contexts do |contexts|
|
49
|
+
|
50
|
+
contexts.desc "Foobar"
|
51
|
+
contexts.switch [:f,'foobar']
|
52
|
+
|
53
|
+
contexts.desc "Blah"
|
54
|
+
contexts.switch [:b]
|
55
|
+
|
56
|
+
contexts.flag :otherflag
|
57
|
+
|
58
|
+
contexts.action do |global,options,args|
|
59
|
+
puts "list contexts: #{args.join(',')}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,47 @@
|
|
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 %(
|
4
|
+
List a whole lot of things that you might be keeping track of
|
5
|
+
in your overall todo list.
|
6
|
+
|
7
|
+
This is your go-to place or finding all of the things that you
|
8
|
+
might have
|
9
|
+
stored in
|
10
|
+
your todo databases.
|
11
|
+
)
|
12
|
+
command [:ls] do |c|
|
13
|
+
c.desc "Show long form"
|
14
|
+
c.switch [:l,:long]
|
15
|
+
|
16
|
+
c.desc "List tasks"
|
17
|
+
c.long_desc %(
|
18
|
+
Lists all of your tasks that you have, in varying orders, and
|
19
|
+
all that stuff. Yes, this is long, but I need a long description.
|
20
|
+
)
|
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(',')}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
c.desc "List contexts"
|
30
|
+
c.long_desc %(
|
31
|
+
Lists all of your contexts, which are places you might be
|
32
|
+
where you can do stuff and all that.
|
33
|
+
)
|
34
|
+
c.command :contexts do |contexts|
|
35
|
+
|
36
|
+
contexts.desc "Foobar"
|
37
|
+
contexts.switch [:f,'foobar']
|
38
|
+
|
39
|
+
contexts.desc "Blah"
|
40
|
+
contexts.switch [:b]
|
41
|
+
|
42
|
+
contexts.action do |global,options,args|
|
43
|
+
puts "ls contexts: #{args.join(',')}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','todo','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'todo'
|
5
|
+
s.version = Todo::VERSION
|
6
|
+
s.author = 'Your Name Here'
|
7
|
+
s.email = 'your@email.address.com'
|
8
|
+
s.homepage = 'http://your.website.com'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'A description of your project'
|
11
|
+
# Add your other files here if you make them
|
12
|
+
s.files = %w(
|
13
|
+
bin/todo
|
14
|
+
)
|
15
|
+
s.require_paths << 'lib'
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ['README.rdoc','todo.rdoc']
|
18
|
+
s.rdoc_options << '--title' << 'todo' << '--main' << 'README.rdoc' << '-ri'
|
19
|
+
s.bindir = 'bin'
|
20
|
+
s.executables << 'todo'
|
21
|
+
s.add_development_dependency('rake')
|
22
|
+
s.add_development_dependency('rdoc')
|
23
|
+
end
|