escort 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +1 -0
- data/.irbrc +1 -0
- data/.rspec +3 -0
- data/.rvmrc +22 -0
- data/README.md +31 -56
- data/TODO.md +152 -0
- data/escort.gemspec +6 -2
- data/examples/1_1_basic.rb +15 -0
- data/examples/1_2_basic_requires_arguments.rb +15 -0
- data/examples/2_2_command.rb +18 -0
- data/examples/2_2_command_requires_arguments.rb +20 -0
- data/examples/2_3_nested_commands.rb +26 -0
- data/examples/3_validations.rb +31 -0
- data/examples/4_1_config_file.rb +42 -0
- data/examples/argument_handling/basic.rb +12 -0
- data/examples/argument_handling/basic_command.rb +18 -0
- data/examples/argument_handling/no_arguments.rb +14 -0
- data/examples/argument_handling/no_arguments_command.rb +20 -0
- data/examples/basic/app.rb +16 -0
- data/examples/command_aliases/app.rb +31 -0
- data/examples/config_file/.apprc2 +16 -0
- data/examples/config_file/app.rb +78 -0
- data/examples/config_file/sub_commands.rb +35 -0
- data/examples/default_command/app.rb +20 -0
- data/examples/sub_commands/app.rb +18 -0
- data/examples/validation_basic/app.rb +31 -0
- data/lib/escort.rb +51 -4
- data/lib/escort/action_command/base.rb +79 -0
- data/lib/escort/action_command/escort_utility_command.rb +53 -0
- data/lib/escort/app.rb +89 -36
- data/lib/escort/arguments.rb +20 -0
- data/lib/escort/auto_options.rb +71 -0
- data/lib/escort/error/error.rb +50 -0
- data/lib/escort/formatter/borderless_table.rb +102 -0
- data/lib/escort/formatter/common.rb +58 -0
- data/lib/escort/formatter/default_help_formatter.rb +106 -0
- data/lib/escort/formatter/options.rb +13 -0
- data/lib/escort/formatter/string_splitter.rb +30 -0
- data/lib/escort/formatter/terminal.rb +22 -0
- data/lib/escort/formatter/terminal_formatter.rb +52 -0
- data/lib/escort/global_pre_parser.rb +43 -0
- data/lib/escort/logger.rb +75 -0
- data/lib/escort/option_parser.rb +145 -0
- data/lib/escort/setup/configuration/generator.rb +75 -0
- data/lib/escort/setup/configuration/instance.rb +33 -0
- data/lib/escort/setup/configuration/loader.rb +37 -0
- data/lib/escort/setup/configuration/locator/base.rb +19 -0
- data/lib/escort/setup/configuration/locator/descending_to_home.rb +23 -0
- data/lib/escort/setup/configuration/merge_tool.rb +38 -0
- data/lib/escort/setup/configuration/reader.rb +36 -0
- data/lib/escort/setup/configuration/writer.rb +44 -0
- data/lib/escort/setup/dsl/action.rb +17 -0
- data/lib/escort/setup/dsl/command.rb +74 -0
- data/lib/escort/setup/dsl/config_file.rb +13 -0
- data/lib/escort/setup/dsl/global.rb +84 -0
- data/lib/escort/setup/dsl/options.rb +25 -0
- data/lib/escort/setup/dsl/validations.rb +25 -0
- data/lib/escort/setup_accessor.rb +194 -0
- data/lib/escort/trollop.rb +15 -4
- data/lib/escort/utils.rb +21 -0
- data/lib/escort/validator.rb +42 -0
- data/lib/escort/version.rb +1 -1
- data/spec/helpers/execute_action_matcher.rb +21 -0
- data/spec/helpers/exit_with_code_matcher.rb +21 -0
- data/spec/helpers/give_option_to_action_with_value_matcher.rb +22 -0
- data/spec/integration/basic_options_spec.rb +53 -0
- data/spec/integration/basic_spec.rb +24 -0
- data/spec/lib/escort/formatter/string_splitter_spec.rb +38 -0
- data/spec/lib/escort/setup_accessor_spec.rb +42 -0
- data/spec/lib/escort/utils_spec.rb +30 -0
- data/spec/spec_helper.rb +22 -0
- metadata +128 -16
- data/lib/escort/command.rb +0 -23
- data/lib/escort/dsl.rb +0 -20
- data/lib/escort/global_dsl.rb +0 -11
@@ -0,0 +1,58 @@
|
|
1
|
+
module Escort
|
2
|
+
module Formatter
|
3
|
+
module Common
|
4
|
+
def option_output_strings(parser)
|
5
|
+
options = {}
|
6
|
+
parser.specs.each do |name, spec|
|
7
|
+
options[name] = "--#{spec[:long]}" +
|
8
|
+
(spec[:type] == :flag && spec[:default] ? ", --no-#{spec[:long]}" : "") +
|
9
|
+
(spec[:short] && spec[:short] != :none ? ", -#{spec[:short]}" : "") +
|
10
|
+
case spec[:type]
|
11
|
+
when :flag; ""
|
12
|
+
when :int; " <i>"
|
13
|
+
when :ints; " <i+>"
|
14
|
+
when :string; " <s>"
|
15
|
+
when :strings; " <s+>"
|
16
|
+
when :float; " <f>"
|
17
|
+
when :floats; " <f+>"
|
18
|
+
when :io; " <filename/uri>"
|
19
|
+
when :ios; " <filename/uri+>"
|
20
|
+
when :date; " <date>"
|
21
|
+
when :dates; " <date+>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
parser.order.each do |what, opt|
|
26
|
+
if what == :text
|
27
|
+
next
|
28
|
+
end
|
29
|
+
spec = parser.specs[opt]
|
30
|
+
desc = spec[:desc] + begin
|
31
|
+
default_s = case spec[:default]
|
32
|
+
when $stdout; "<stdout>"
|
33
|
+
when $stdin; "<stdin>"
|
34
|
+
when $stderr; "<stderr>"
|
35
|
+
when Array
|
36
|
+
spec[:default].join(", ")
|
37
|
+
else
|
38
|
+
spec[:default].to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
if spec[:default]
|
42
|
+
if spec[:desc] =~ /\.$/
|
43
|
+
" (Default: #{default_s})"
|
44
|
+
else
|
45
|
+
" (default: #{default_s})"
|
46
|
+
end
|
47
|
+
else
|
48
|
+
""
|
49
|
+
end
|
50
|
+
end
|
51
|
+
options[opt] = {:string => options[opt]}
|
52
|
+
options[opt][:desc] = desc
|
53
|
+
end
|
54
|
+
options
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Escort
|
2
|
+
module Formatter
|
3
|
+
class DefaultHelpFormatter
|
4
|
+
include Escort::Formatter::Common
|
5
|
+
|
6
|
+
attr_reader :setup, :context
|
7
|
+
|
8
|
+
def initialize(setup, context)
|
9
|
+
@setup = setup
|
10
|
+
@context = context
|
11
|
+
end
|
12
|
+
|
13
|
+
def print(parser)
|
14
|
+
option_strings = option_output_strings(parser)
|
15
|
+
command_strings = command_output_strings
|
16
|
+
|
17
|
+
TerminalFormatter.display($stdout, Terminal.width) do |d|
|
18
|
+
d.puts "NAME"
|
19
|
+
d.indent(4) do
|
20
|
+
d.table(:columns => 3, :newlines => 1) do |t|
|
21
|
+
t.row script_name_with_command, '-', current_command_summary
|
22
|
+
end
|
23
|
+
d.put(setup.description_for(context), :newlines => 2) if setup.description_for(context)
|
24
|
+
end
|
25
|
+
d.puts "USAGE"
|
26
|
+
d.indent(4) do
|
27
|
+
context_usage_part = context.map { |command_name| "#{command_name} [#{command_name} options]" }.join(" ")
|
28
|
+
context_usage_part ||= ""
|
29
|
+
nested_command_part = "command [command options]" if !setup.canonical_command_names_for(context).nil? && setup.canonical_command_names_for(context).length > 0
|
30
|
+
nested_command_part ||= ""
|
31
|
+
usage_string = "#{script_name} [options] #{context_usage_part} #{nested_command_part} [arguments...]".gsub(/\s+/, ' ')
|
32
|
+
d.put usage_string, :newlines => 2
|
33
|
+
end
|
34
|
+
if setup.version
|
35
|
+
d.puts "VERSION"
|
36
|
+
d.indent(4) {
|
37
|
+
d.put setup.version, :newlines => 2
|
38
|
+
}
|
39
|
+
end
|
40
|
+
if option_strings.keys.size > 0
|
41
|
+
d.puts "OPTIONS"
|
42
|
+
d.indent(4) {
|
43
|
+
d.table(:columns => 3, :newlines => 1) do |t|
|
44
|
+
option_strings.each_pair do |key, value|
|
45
|
+
t.row value[:string], '-', value[:desc] || ''
|
46
|
+
end
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
if command_strings.keys.size > 0
|
51
|
+
d.puts "COMMANDS"
|
52
|
+
d.indent(4) {
|
53
|
+
d.table(:columns => 3, :newlines => 1) do |t|
|
54
|
+
command_strings.each_pair do |command_name, values_array|
|
55
|
+
t.row values_array[0], '-', command_outline(values_array)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def script_name_with_command
|
67
|
+
result = []
|
68
|
+
result << script_name
|
69
|
+
result << current_command unless context.empty?
|
70
|
+
result.join(" ")
|
71
|
+
end
|
72
|
+
|
73
|
+
def script_name
|
74
|
+
File.basename($0)
|
75
|
+
end
|
76
|
+
|
77
|
+
def current_command
|
78
|
+
context.last || :global
|
79
|
+
end
|
80
|
+
|
81
|
+
def command_outline(command_data)
|
82
|
+
result = command_data[1] || ''
|
83
|
+
result = command_data[2] || '' if result.nil? || result.empty?
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
def current_command_summary
|
88
|
+
setup.summary_for(context) || ''
|
89
|
+
end
|
90
|
+
|
91
|
+
def command_output_strings
|
92
|
+
commands = {}
|
93
|
+
setup.canonical_command_names_for(context).each do |command_name|
|
94
|
+
command_description = setup.command_description_for(command_name, context) || ""
|
95
|
+
command_summary = setup.command_summary_for(command_name, context) || ""
|
96
|
+
command_aliases = setup.command_aliases_for(command_name, context)
|
97
|
+
command_alias_string = command_aliases.join(", ") if command_aliases && command_aliases.size > 0
|
98
|
+
command_string = (command_aliases && command_aliases.size > 0 ? "#{command_name}, #{command_alias_string}" : "#{command_name}" )
|
99
|
+
command_name = command_name.to_s
|
100
|
+
commands[command_name] = [command_string, command_summary, command_description]
|
101
|
+
end
|
102
|
+
commands
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Escort
|
2
|
+
module Formatter
|
3
|
+
class StringSplitter
|
4
|
+
attr_reader :max_segment_width
|
5
|
+
|
6
|
+
def initialize(max_segment_width)
|
7
|
+
@max_segment_width = max_segment_width
|
8
|
+
end
|
9
|
+
|
10
|
+
def split(string)
|
11
|
+
string.split("\n").map { |s| split_string(s) }.flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def split_string(string)
|
17
|
+
result = []
|
18
|
+
if string.length > max_segment_width
|
19
|
+
first_part = string.slice(0, max_segment_width)
|
20
|
+
second_part = string.slice(max_segment_width..-1)
|
21
|
+
result << first_part
|
22
|
+
result << split_string(second_part)
|
23
|
+
else
|
24
|
+
result << string
|
25
|
+
end
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'curses'
|
2
|
+
|
3
|
+
module Escort
|
4
|
+
module Formatter
|
5
|
+
class Terminal
|
6
|
+
DEFAULT_WIDTH = 80
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def width
|
10
|
+
screen_size = self::DEFAULT_WIDTH
|
11
|
+
Curses.init_screen
|
12
|
+
begin
|
13
|
+
screen_size = Curses.cols
|
14
|
+
ensure
|
15
|
+
Curses.close_screen
|
16
|
+
end
|
17
|
+
screen_size
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Escort
|
2
|
+
module Formatter
|
3
|
+
class TerminalFormatter
|
4
|
+
class << self
|
5
|
+
def display(stream = $stdout, max_width = Terminal::DEFAULT_WIDTH, &block)
|
6
|
+
formatter = self.new(stream, max_width)
|
7
|
+
block.call(formatter)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :stream, :indent_char, :indent_count, :terminal_columns
|
12
|
+
|
13
|
+
def initialize(stream = $stdout, max_width = Terminal::DEFAULT_WIDTH)
|
14
|
+
@stream = stream
|
15
|
+
@indent_char = " "
|
16
|
+
@indent_count = 0
|
17
|
+
@terminal_columns = (max_width < Terminal::DEFAULT_WIDTH/2 ? Terminal::DEFAULT_WIDTH/2 : max_width)
|
18
|
+
end
|
19
|
+
|
20
|
+
def put(data, options = {:newlines => 0})
|
21
|
+
segments = StringSplitter.new(terminal_columns - current_indent_string.size - 1).split(data.to_s)
|
22
|
+
segments.each do |segment|
|
23
|
+
stream.print "#{current_indent_string}#{segment}"
|
24
|
+
end
|
25
|
+
newline(options[:newlines])
|
26
|
+
end
|
27
|
+
|
28
|
+
def puts(data)
|
29
|
+
put(data, :newlines => 1)
|
30
|
+
end
|
31
|
+
|
32
|
+
def indent(count, &block)
|
33
|
+
@indent_count += count
|
34
|
+
block.call
|
35
|
+
@indent_count -= count
|
36
|
+
end
|
37
|
+
|
38
|
+
def table(options = {}, &block)
|
39
|
+
BorderlessTable.new(self, options).output(&block)
|
40
|
+
newline(options[:newlines] || 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def newline(newline_count = 1)
|
44
|
+
stream.print("\n" * newline_count)
|
45
|
+
end
|
46
|
+
|
47
|
+
def current_indent_string
|
48
|
+
indent_char * indent_count
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Escort
|
2
|
+
class GlobalPreParser
|
3
|
+
attr_reader :setup
|
4
|
+
|
5
|
+
def initialize(setup)
|
6
|
+
@setup = setup
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse(cli_options)
|
10
|
+
AutoOptions.new(parse_global_options(cli_options))
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def parse_global_options(cli_options, context = [])
|
16
|
+
stop_words = setup.command_names_for(context).map(&:to_s)
|
17
|
+
parser = init_parser(stop_words)
|
18
|
+
parser = add_setup_options_to(parser, context)
|
19
|
+
parser.version(setup.version) #set the version if it was provided
|
20
|
+
parser.help_formatter(Escort::Formatter::DefaultHelpFormatter.new(setup, context))
|
21
|
+
parsed_options = parse_options_string(parser, cli_options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def init_parser(stop_words)
|
25
|
+
Trollop::Parser.new.tap do |parser|
|
26
|
+
parser.stop_on(stop_words)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_setup_options_to(parser, context = [])
|
31
|
+
setup.options_for(context).each do |name, opts|
|
32
|
+
parser.opt name, opts[:desc] || "", opts
|
33
|
+
end
|
34
|
+
parser
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_options_string(parser, cli_options)
|
38
|
+
Trollop::with_standard_exception_handling(parser) do
|
39
|
+
parser.parse(cli_options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Escort
|
4
|
+
class Logger
|
5
|
+
class << self
|
6
|
+
def close
|
7
|
+
error.close
|
8
|
+
output.close
|
9
|
+
end
|
10
|
+
|
11
|
+
def error
|
12
|
+
@error_logger ||= ::Logger.new($stderr).tap do |l|
|
13
|
+
#l.formatter = advanced_error_formatter
|
14
|
+
l.formatter = basic_error_formatter
|
15
|
+
l.sev_threshold = ::Logger::WARN
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def output
|
20
|
+
@output_logger ||= ::Logger.new($stdout).tap do |l|
|
21
|
+
l.formatter = output_formatter
|
22
|
+
l.sev_threshold = ::Logger::DEBUG
|
23
|
+
l.instance_eval do
|
24
|
+
def puts(message = nil, &block)
|
25
|
+
if block_given?
|
26
|
+
fatal(&block)
|
27
|
+
else
|
28
|
+
fatal(message || "")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup_error_logger(auto_options)
|
36
|
+
error.formatter = send(:"#{auto_options.error_formatter}_error_formatter")
|
37
|
+
error.sev_threshold = ::Logger.const_get(auto_options.verbosity)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def basic_error_formatter
|
43
|
+
proc do |severity, datetime, progname, msg|
|
44
|
+
"\"#{msg2str(msg)}\"\n"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#"#{severity} [#{datetime.strftime("%d/%b/%Y %H:%M:%S")}] \"#{msg}\"\n"
|
49
|
+
def advanced_error_formatter
|
50
|
+
proc do |severity, datetime, progname, msg|
|
51
|
+
sprintf("%-8s \"#{msg2str(msg, 10)}\"\n", severity)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def output_formatter
|
56
|
+
proc do |severity, datetime, progname, msg|
|
57
|
+
"\"#{msg}\"\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def msg2str(msg, backtrace_indent = 0)
|
62
|
+
case msg
|
63
|
+
when ::String
|
64
|
+
msg
|
65
|
+
when ::Exception
|
66
|
+
"#{msg.message} (#{ msg.class })\n" <<
|
67
|
+
(msg.backtrace || []).map{|line| sprintf("%#{backtrace_indent}s#{line}", " ")}.join("\n")
|
68
|
+
else
|
69
|
+
msg.inspect
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module Escort
|
2
|
+
class OptionParser
|
3
|
+
attr_reader :setup, :configuration
|
4
|
+
|
5
|
+
def initialize(configuration, setup)
|
6
|
+
@configuration = configuration
|
7
|
+
@setup = setup
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(cli_options)
|
11
|
+
options = init_invoked_options_hash
|
12
|
+
parse_global_options(cli_options, options[:global][:options])
|
13
|
+
parse_command_options(cli_options, [], options[:global][:commands])
|
14
|
+
|
15
|
+
[options, arguments_from(cli_options)]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def init_invoked_options_hash
|
21
|
+
{
|
22
|
+
:global => {
|
23
|
+
:options => {},
|
24
|
+
:commands => {}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_global_options(cli_options, options)
|
30
|
+
context = []
|
31
|
+
options.merge!(parse_options(cli_options, context))
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_command_options(cli_options, context, options)
|
35
|
+
unless cli_option_is_a_command?(cli_options, context)
|
36
|
+
options
|
37
|
+
else
|
38
|
+
command = command_name_from(cli_options)
|
39
|
+
context << command
|
40
|
+
current_options = parse_options(cli_options, context)
|
41
|
+
options[command] = {}
|
42
|
+
options[command][:options] = current_options
|
43
|
+
options[command][:commands] = {}
|
44
|
+
parse_command_options(cli_options, context, options[command][:commands])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_options(cli_options, context = [])
|
49
|
+
stop_words = setup.command_names_for(context).map(&:to_s)
|
50
|
+
parser = init_parser(stop_words)
|
51
|
+
parser = add_setup_options_to(parser, context)
|
52
|
+
parser = add_option_conflicts_to(parser, context)
|
53
|
+
parser = default_option_values_from_config_for(parser, context)
|
54
|
+
parser.version(setup.version) #set the version if it was provided
|
55
|
+
parser.help_formatter(Escort::Formatter::DefaultHelpFormatter.new(setup, context))
|
56
|
+
parsed_options = parse_options_string(parser, cli_options)
|
57
|
+
Escort::Validator.for(parser).validate(parsed_options, setup.validations_for(context))
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_setup_options_to(parser, context = [])
|
61
|
+
setup.options_for(context).each do |name, opts|
|
62
|
+
parser.opt name, opts[:desc] || "", opts.dup #have to make sure to dup here, otherwise opts might get stuff added to it and it
|
63
|
+
#may cause problems later, e.g. adds default value and when parsed again trollop barfs
|
64
|
+
end
|
65
|
+
parser
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_option_conflicts_to(parser, context = [])
|
69
|
+
setup.conflicting_options_for(context).each do |conflict_list|
|
70
|
+
parser.conflicts *conflict_list
|
71
|
+
end
|
72
|
+
parser
|
73
|
+
end
|
74
|
+
|
75
|
+
def default_option_values_from_config_for(parser, context)
|
76
|
+
unless configuration.empty?
|
77
|
+
parser.specs.each do |sym, opts|
|
78
|
+
if config_has_value_for_context?(sym, context)
|
79
|
+
default = config_value_for_context(sym, context)
|
80
|
+
opts[:default] = default
|
81
|
+
if opts[:multi] && default.nil?
|
82
|
+
opts[:default] = [] # multi arguments default to [], not nil
|
83
|
+
elsif opts[:multi] && !default.kind_of?(Array)
|
84
|
+
opts[:default] = [default]
|
85
|
+
else
|
86
|
+
opts[:default] = default
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
parser
|
92
|
+
end
|
93
|
+
|
94
|
+
def config_has_value_for_context?(option, context)
|
95
|
+
relevant_config_hash = config_hash_for_context(context)
|
96
|
+
relevant_config_hash[:options].include?(option)
|
97
|
+
end
|
98
|
+
|
99
|
+
def config_value_for_context(option, context)
|
100
|
+
relevant_config_hash = config_hash_for_context(context)
|
101
|
+
relevant_config_hash[:options][option]
|
102
|
+
end
|
103
|
+
|
104
|
+
def config_hash_for_context(context)
|
105
|
+
relevant_config_hash = configuration.global
|
106
|
+
context.each do |command_name|
|
107
|
+
command_name = command_name.to_sym
|
108
|
+
relevant_config_hash = relevant_config_hash[:commands][command_name]
|
109
|
+
relevant_config_hash = ensure_config_hash_has_options_and_commands(relevant_config_hash)
|
110
|
+
end
|
111
|
+
relevant_config_hash
|
112
|
+
end
|
113
|
+
|
114
|
+
def ensure_config_hash_has_options_and_commands(relevant_config_hash)
|
115
|
+
relevant_config_hash ||= {}
|
116
|
+
relevant_config_hash[:commands] ||= {}
|
117
|
+
relevant_config_hash[:options] ||= {}
|
118
|
+
relevant_config_hash
|
119
|
+
end
|
120
|
+
|
121
|
+
def cli_option_is_a_command?(cli_options, context)
|
122
|
+
cli_options.size > 0 && setup.command_names_for(context).include?(cli_options[0].to_sym)
|
123
|
+
end
|
124
|
+
|
125
|
+
def init_parser(stop_words)
|
126
|
+
Trollop::Parser.new.tap do |parser|
|
127
|
+
parser.stop_on(stop_words) # make sure we halt parsing if we see a command
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def parse_options_string(parser, cli_options)
|
132
|
+
Trollop::with_standard_exception_handling(parser) do
|
133
|
+
parser.parse(cli_options)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def command_name_from(cli_options)
|
138
|
+
cli_options.shift.to_sym
|
139
|
+
end
|
140
|
+
|
141
|
+
def arguments_from(cli_options)
|
142
|
+
cli_options
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|