escort 0.0.1 → 0.1.0
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 +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
|