escort 0.1.0 → 0.2.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 +8 -8
- data/.travis.yml +8 -0
- data/README.md +365 -14
- data/TODO.md +157 -44
- data/escort.gemspec +1 -0
- data/examples/{1_1_basic.rb → attic/1_1_basic.rb} +0 -0
- data/examples/{1_2_basic_requires_arguments.rb → attic/1_2_basic_requires_arguments.rb} +0 -0
- data/examples/{2_2_command.rb → attic/2_2_command.rb} +0 -0
- data/examples/{2_2_command_requires_arguments.rb → attic/2_2_command_requires_arguments.rb} +0 -0
- data/examples/{2_3_nested_commands.rb → attic/2_3_nested_commands.rb} +0 -0
- data/examples/{3_validations.rb → attic/3_validations.rb} +0 -0
- data/examples/{4_1_config_file.rb → attic/4_1_config_file.rb} +0 -0
- data/examples/{argument_handling → attic/argument_handling}/basic.rb +0 -0
- data/examples/{argument_handling → attic/argument_handling}/basic_command.rb +0 -0
- data/examples/{argument_handling → attic/argument_handling}/no_arguments.rb +0 -0
- data/examples/{argument_handling → attic/argument_handling}/no_arguments_command.rb +0 -0
- data/examples/{command_aliases → attic/command_aliases}/app.rb +0 -0
- data/examples/{config_file → attic/config_file}/.apprc2 +0 -0
- data/examples/{config_file → attic/config_file}/app.rb +0 -0
- data/examples/{config_file → attic/config_file}/sub_commands.rb +0 -0
- data/examples/{default_command → attic/default_command}/app.rb +0 -0
- data/examples/{sub_commands → attic/sub_commands}/app.rb +0 -0
- data/examples/{validation_basic → attic/validation_basic}/app.rb +0 -0
- data/examples/basic +10 -0
- data/examples/basic_conflicts +17 -0
- data/examples/basic_depends_on +25 -0
- data/examples/basic_flags +15 -0
- data/examples/basic_options +14 -0
- data/examples/basic_options_multi +15 -0
- data/examples/basic_require_arguments +17 -0
- data/examples/basic_texts +21 -0
- data/examples/basic_validations +21 -0
- data/examples/command +19 -0
- data/examples/commands/example_command.rb +13 -0
- data/lib/escort/action_command/base.rb +4 -0
- data/lib/escort/app.rb +33 -11
- data/lib/escort/formatter/borderless_table.rb +4 -0
- data/lib/escort/formatter/command.rb +87 -0
- data/lib/escort/formatter/commands.rb +36 -0
- data/lib/escort/formatter/default_help_formatter.rb +68 -73
- data/lib/escort/formatter/global_command.rb +17 -0
- data/lib/escort/formatter/option.rb +138 -0
- data/lib/escort/formatter/options.rb +17 -3
- data/lib/escort/formatter/shell_command_executor.rb +49 -0
- data/lib/escort/formatter/terminal.rb +17 -9
- data/lib/escort/formatter/terminal_formatter.rb +6 -0
- data/lib/escort/logger.rb +4 -4
- data/lib/escort/option_dependency_validator.rb +83 -0
- data/lib/escort/option_parser.rb +11 -1
- data/lib/escort/setup/configuration/reader.rb +0 -2
- data/lib/escort/setup/configuration/writer.rb +0 -2
- data/lib/escort/setup/dsl/command.rb +2 -7
- data/lib/escort/setup/dsl/global.rb +2 -9
- data/lib/escort/setup/dsl/options.rb +56 -0
- data/lib/escort/setup_accessor.rb +23 -6
- data/lib/escort/trollop.rb +4 -3
- data/lib/escort/validator.rb +4 -1
- data/lib/escort/version.rb +1 -1
- data/lib/escort.rb +8 -1
- data/spec/integration/basic_conflicts_spec.rb +47 -0
- data/spec/integration/basic_depends_on_spec.rb +275 -0
- data/spec/integration/basic_options_spec.rb +9 -21
- data/spec/integration/basic_options_with_multi_spec.rb +30 -0
- data/spec/integration/basic_spec.rb +5 -6
- data/spec/integration/basic_validations_spec.rb +77 -0
- data/spec/integration/basic_with_arguments_spec.rb +33 -0
- data/spec/integration/basic_with_text_fields_spec.rb +21 -0
- data/spec/lib/escort/formatter/command_spec.rb +238 -0
- data/spec/lib/escort/formatter/global_command_spec.rb +50 -0
- data/spec/lib/escort/formatter/option_spec.rb +300 -0
- data/spec/lib/escort/formatter/shell_command_executor_spec.rb +59 -0
- data/spec/lib/escort/formatter/string_splitter_spec.rb +12 -0
- data/spec/lib/escort/formatter/terminal_spec.rb +19 -0
- data/spec/lib/escort/setup_accessor_spec.rb +1 -0
- data/spec/spec_helper.rb +9 -3
- data/spec/support/integration_helpers.rb +2 -0
- data/spec/{helpers/execute_action_matcher.rb → support/matchers/execute_action_for_command_matcher.rb} +3 -3
- data/spec/support/matchers/execute_action_with_arguments_matcher.rb +25 -0
- data/spec/support/matchers/execute_action_with_options_matcher.rb +29 -0
- data/spec/support/matchers/exit_with_code_matcher.rb +29 -0
- data/spec/support/shared_contexts/integration_setup.rb +34 -0
- metadata +86 -28
- data/examples/basic/app.rb +0 -16
- data/lib/escort/formatter/common.rb +0 -58
- data/spec/helpers/exit_with_code_matcher.rb +0 -21
- data/spec/helpers/give_option_to_action_with_value_matcher.rb +0 -22
@@ -0,0 +1,83 @@
|
|
1
|
+
module Escort
|
2
|
+
class OptionDependencyValidator
|
3
|
+
class << self
|
4
|
+
def for(parser)
|
5
|
+
self.new(parser)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :parser
|
10
|
+
|
11
|
+
def initialize(parser)
|
12
|
+
@parser = parser
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate(options, dependencies)
|
16
|
+
dependencies.each_pair do |option_name, dependency_rules|
|
17
|
+
ensure_dependencies_satisfied_for(option_name, dependency_rules, options)
|
18
|
+
end
|
19
|
+
options
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def option_exists?(option)
|
25
|
+
parser.specs.keys.include?(option)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ensure_dependencies_satisfied_for(option_name, dependency_rules, options)
|
29
|
+
ensure_dependency_for_valid_option(option_name)
|
30
|
+
dependency_rules.each do |rule|
|
31
|
+
case rule
|
32
|
+
when Hash
|
33
|
+
handle_all_option_value_dependency_rules(option_name, rule, options)
|
34
|
+
else
|
35
|
+
ensure_option_depends_on_valid_option(option_name, rule)
|
36
|
+
handle_possible_presence_dependency_issue(option_name, rule, options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_all_option_value_dependency_rules(option_name, rule, options)
|
42
|
+
if option_was_specified?(option_name, options)
|
43
|
+
rule.each_pair do |rule_option, rule_option_value|
|
44
|
+
ensure_option_depends_on_valid_option(option_name, rule_option)
|
45
|
+
handle_possible_option_value_dependency_issue(option_name, rule_option, rule_option_value, options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle_possible_option_value_dependency_issue(option_name, rule_option, rule_option_value, options)
|
51
|
+
unless options[rule_option] == rule_option_value
|
52
|
+
raise Escort::UserError.new("Option dependency unsatisfied, '#{option_name}' depends on '#{rule_option}' having value '#{rule_option_value}', '#{option_name}' specified with value '#{options[option_name]}', but '#{rule_option}' is '#{options[rule_option]}'")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_possible_presence_dependency_issue(option_name, rule, options)
|
57
|
+
if option_was_specified?(option_name, options) && option_was_unspecified?(rule, options)
|
58
|
+
raise Escort::UserError.new("Option dependency unsatisfied, '#{option_name}' depends on '#{rule}', '#{option_name}' specified with value '#{options[option_name]}', but '#{rule}' is unspecified")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def option_was_unspecified?(option_name, options)
|
63
|
+
!option_was_specified?(option_name, options)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def option_was_specified?(option_name, options)
|
68
|
+
!options[option_name].nil? && !(options[option_name] == []) && !(options[option_name] == false)
|
69
|
+
end
|
70
|
+
|
71
|
+
def ensure_dependency_for_valid_option(option_name)
|
72
|
+
unless option_exists?(option_name)
|
73
|
+
raise Escort::ClientError.new("Dependency specified for option '#{option_name}', but no such option was defined, perhaps you misspelled it")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def ensure_option_depends_on_valid_option(option_name, rule)
|
78
|
+
unless option_exists?(rule)
|
79
|
+
raise Escort::ClientError.new("'#{option_name}' is set up to depend on '#{rule}', but '#{rule}' does not appear to be a valid option, perhaps it is a spelling error")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/escort/option_parser.rb
CHANGED
@@ -54,6 +54,7 @@ module Escort
|
|
54
54
|
parser.version(setup.version) #set the version if it was provided
|
55
55
|
parser.help_formatter(Escort::Formatter::DefaultHelpFormatter.new(setup, context))
|
56
56
|
parsed_options = parse_options_string(parser, cli_options)
|
57
|
+
Escort::OptionDependencyValidator.for(parser).validate(parsed_options, setup.dependencies_for(context))
|
57
58
|
Escort::Validator.for(parser).validate(parsed_options, setup.validations_for(context))
|
58
59
|
end
|
59
60
|
|
@@ -66,12 +67,21 @@ module Escort
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def add_option_conflicts_to(parser, context = [])
|
69
|
-
setup.conflicting_options_for(context)
|
70
|
+
conflicting_options_for_context = setup.conflicting_options_for(context)
|
71
|
+
conflicting_options_for_context.keys.each do |option_name|
|
72
|
+
conflict_list = [option_name] + conflicting_options_for_context[option_name]
|
73
|
+
conflict_list.each do |option|
|
74
|
+
raise Escort::ClientError.new("Conflict defined with option '#{option}', but this option does not exist, perhaps it is a spelling error.") unless option_exists?(parser, option)
|
75
|
+
end
|
70
76
|
parser.conflicts *conflict_list
|
71
77
|
end
|
72
78
|
parser
|
73
79
|
end
|
74
80
|
|
81
|
+
def option_exists?(parser, option)
|
82
|
+
parser.specs.keys.include?(option)
|
83
|
+
end
|
84
|
+
|
75
85
|
def default_option_values_from_config_for(parser, context)
|
76
86
|
unless configuration.empty?
|
77
87
|
parser.specs.each do |sym, opts|
|
@@ -21,11 +21,8 @@ module Escort
|
|
21
21
|
Action.action(@name, @action, &block)
|
22
22
|
end
|
23
23
|
|
24
|
-
def validations(&block)
|
25
|
-
Validations.validations(@name, @validations, &block)
|
26
|
-
end
|
27
|
-
|
28
24
|
def command(name, options = {}, &block)
|
25
|
+
raise Escort::ClientError.new("Parameter to 'requires_arguments' must be a boolean") unless [true, false].include?(boolean)
|
29
26
|
options[:requires_arguments] = @requires_arguments
|
30
27
|
command = Command.new(name.to_sym, options, &block)
|
31
28
|
aliases = [options[:aliases] || []].flatten + [name]
|
@@ -43,7 +40,7 @@ module Escort
|
|
43
40
|
end
|
44
41
|
|
45
42
|
def conflicting_options(*command_names)
|
46
|
-
|
43
|
+
raise Escort::ClientError.new("This interface for specifying conflicting options is no longer supported, please use 'opts.conflict' in the options block")
|
47
44
|
end
|
48
45
|
|
49
46
|
def summary(summary)
|
@@ -61,11 +58,9 @@ module Escort
|
|
61
58
|
@commands = {}
|
62
59
|
@options = Options.new(name)
|
63
60
|
@action = Action.new(name)
|
64
|
-
@validations = Validations.new(name)
|
65
61
|
@name = nil
|
66
62
|
@description = nil
|
67
63
|
@aliases = []
|
68
|
-
@conflicts = []
|
69
64
|
@summary = nil
|
70
65
|
end
|
71
66
|
end
|
@@ -17,10 +17,6 @@ module Escort
|
|
17
17
|
Action.action(:global, @action, &block)
|
18
18
|
end
|
19
19
|
|
20
|
-
def validations(&block)
|
21
|
-
Validations.validations(:global, @validations, &block)
|
22
|
-
end
|
23
|
-
|
24
20
|
def command(name, options = {}, &block)
|
25
21
|
options[:requires_arguments] = @requires_arguments
|
26
22
|
command = Command.new(name.to_sym, options, &block)
|
@@ -31,7 +27,7 @@ module Escort
|
|
31
27
|
end
|
32
28
|
|
33
29
|
def requires_arguments(boolean = true)
|
34
|
-
|
30
|
+
raise Escort::ClientError.new("Parameter to 'requires_arguments' must be a boolean") unless [true, false].include?(boolean)
|
35
31
|
@requires_arguments = boolean
|
36
32
|
@commands.each do |command|
|
37
33
|
command.requires_arguments(boolean)
|
@@ -54,9 +50,8 @@ module Escort
|
|
54
50
|
@description = description
|
55
51
|
end
|
56
52
|
|
57
|
-
|
58
53
|
def conflicting_options(*command_names)
|
59
|
-
|
54
|
+
raise Escort::ClientError.new("This interface for specifying conflicting options is no longer supported, please use 'opts.conflict' in the options block")
|
60
55
|
end
|
61
56
|
|
62
57
|
private
|
@@ -69,9 +64,7 @@ module Escort
|
|
69
64
|
@requires_arguments = false
|
70
65
|
@options = Options.new
|
71
66
|
@action = Action.new
|
72
|
-
@validations = Validations.new
|
73
67
|
@config_file = nil
|
74
|
-
@conflicts = []
|
75
68
|
end
|
76
69
|
|
77
70
|
def set_instance_variable_on(instance, instance_variable, value)
|
@@ -13,11 +13,67 @@ module Escort
|
|
13
13
|
def initialize(command_name = :global)
|
14
14
|
@command_name = command_name
|
15
15
|
@options = {}
|
16
|
+
@dependencies = {}
|
17
|
+
@conflicts = {}
|
18
|
+
@validations = {}
|
16
19
|
end
|
17
20
|
|
18
21
|
def opt(name, desc="", opts={})
|
19
22
|
opts[:desc] ||= desc
|
20
23
|
@options[name] ||= opts
|
24
|
+
dependency(name, :on => opts[:depends_on]) if opts[:depends_on]
|
25
|
+
conflict(*[name, opts[:conflicts_with]].flatten) if opts[:conflicts_with]
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate(name, description, &block)
|
29
|
+
@validations[name] ||= []
|
30
|
+
@validations[name] << {:desc => description, :block => block}
|
31
|
+
end
|
32
|
+
|
33
|
+
def dependency(option_name, opts = {})
|
34
|
+
ensure_dependency_specification_syntax(opts)
|
35
|
+
@dependencies[option_name] ||= []
|
36
|
+
rules_as_array(opts).each do |rule|
|
37
|
+
ensure_no_self_dependency(option_name, rule)
|
38
|
+
@dependencies[option_name] << rule
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def conflict(*opts)
|
43
|
+
opts.each do |opt|
|
44
|
+
conflicts_for_opt = opts.reject{|value| value == opt}
|
45
|
+
@conflicts[opt] ||= []
|
46
|
+
@conflicts[opt] += conflicts_for_opt
|
47
|
+
@conflicts[opt].uniq!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def ensure_no_self_dependency(option_name, rule)
|
53
|
+
case rule
|
54
|
+
when Hash
|
55
|
+
rule.each_pair do |rule_option, rule_option_value|
|
56
|
+
handle_possible_self_dependency(option_name, rule_option)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
handle_possible_self_dependency(option_name, rule)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def ensure_dependency_specification_syntax(opts)
|
64
|
+
unless opts[:on]
|
65
|
+
raise Escort::ClientError.new("Problem with syntax of dependency specification in #{@command_name} options block, #{option_name} missing ':on' condition")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def rules_as_array(opts)
|
70
|
+
[opts[:on]].flatten
|
71
|
+
end
|
72
|
+
|
73
|
+
def handle_possible_self_dependency(option_name, rule)
|
74
|
+
if option_name == rule
|
75
|
+
raise Escort::ClientError.new("Problem with syntax of dependency specification in #{@command_name} options block, #{option_name} is set to depend on itself")
|
76
|
+
end
|
21
77
|
end
|
22
78
|
end
|
23
79
|
end
|
@@ -14,17 +14,22 @@ module Escort
|
|
14
14
|
|
15
15
|
def conflicting_options_for(context = [])
|
16
16
|
with_context(context) do |current_context|
|
17
|
-
|
17
|
+
conflicts_hash_for(current_context)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
21
|
def validations_for(context = [])
|
23
22
|
with_context(context) do |current_context|
|
24
23
|
validations_hash_from(current_context)
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
27
|
+
def dependencies_for(context = [])
|
28
|
+
with_context(context) do |current_context|
|
29
|
+
dependencies_hash_from(current_context)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
28
33
|
def command_names_for(context = [])
|
29
34
|
with_context(context) do |current_context|
|
30
35
|
command_names_from(current_context)
|
@@ -169,13 +174,25 @@ module Escort
|
|
169
174
|
end
|
170
175
|
end
|
171
176
|
|
172
|
-
def
|
173
|
-
|
177
|
+
def conflicts_hash_for(context_object)
|
178
|
+
ensure_context_object(context_object, {}) do
|
179
|
+
options_object = options_object_from(context_object)
|
180
|
+
fetch_instance_variable_from(options_object, :conflicts)
|
181
|
+
end
|
174
182
|
end
|
175
183
|
|
176
184
|
def validations_hash_from(context_object)
|
177
|
-
|
178
|
-
|
185
|
+
ensure_context_object(context_object, {}) do
|
186
|
+
validations_object = fetch_instance_variable_from(context_object, :options)
|
187
|
+
fetch_instance_variable_from(validations_object, :validations)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def dependencies_hash_from(context_object)
|
192
|
+
ensure_context_object(context_object, {}) do
|
193
|
+
options_object = options_object_from(context_object)
|
194
|
+
fetch_instance_variable_from(options_object, :dependencies)
|
195
|
+
end
|
179
196
|
end
|
180
197
|
|
181
198
|
def fetch_instance_variable_from_setup(instance_variable)
|
data/lib/escort/trollop.rb
CHANGED
@@ -750,9 +750,10 @@ def with_standard_exception_handling(parser)
|
|
750
750
|
begin
|
751
751
|
yield
|
752
752
|
rescue CommandlineError => e
|
753
|
-
|
754
|
-
|
755
|
-
|
753
|
+
raise Escort::UserError.new(e.message, e)
|
754
|
+
#$stderr.puts "Error: #{e.message}."
|
755
|
+
#$stderr.puts "Try --help for help."
|
756
|
+
#exit(1)
|
756
757
|
rescue HelpNeeded
|
757
758
|
parser.current_help_formatter ? parser.current_help_formatter.print(parser) : parser.educate
|
758
759
|
exit
|
data/lib/escort/validator.rb
CHANGED
@@ -31,7 +31,10 @@ module Escort
|
|
31
31
|
|
32
32
|
def validate_option(option, options, validations_array)
|
33
33
|
validations_array.each do |validation_data|
|
34
|
-
|
34
|
+
if invalid?(option, options, validation_data)
|
35
|
+
raise Escort::UserError.new("#{option} #{validation_data[:desc]}")
|
36
|
+
end
|
37
|
+
#parser.die(option, validation_data[:desc]) if invalid?(option, options, validation_data)
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
data/lib/escort/version.rb
CHANGED
data/lib/escort.rb
CHANGED
@@ -6,11 +6,17 @@ require 'escort/logger'
|
|
6
6
|
|
7
7
|
require 'escort/error/error'
|
8
8
|
|
9
|
+
require 'escort/formatter/option'
|
10
|
+
require 'escort/formatter/options'
|
11
|
+
require 'escort/formatter/command'
|
12
|
+
require 'escort/formatter/commands'
|
13
|
+
require 'escort/formatter/global_command'
|
14
|
+
require 'escort/formatter/shell_command_executor'
|
9
15
|
require 'escort/formatter/terminal'
|
10
16
|
require 'escort/formatter/string_splitter'
|
11
17
|
require 'escort/formatter/terminal_formatter'
|
12
18
|
require 'escort/formatter/borderless_table'
|
13
|
-
require 'escort/formatter/common'
|
19
|
+
#require 'escort/formatter/common'
|
14
20
|
require 'escort/formatter/default_help_formatter'
|
15
21
|
|
16
22
|
require 'escort/setup/dsl/options'
|
@@ -31,6 +37,7 @@ require 'escort/setup/configuration/loader'
|
|
31
37
|
|
32
38
|
require 'escort/setup_accessor'
|
33
39
|
|
40
|
+
require 'escort/option_dependency_validator'
|
34
41
|
require 'escort/validator'
|
35
42
|
require 'escort/auto_options'
|
36
43
|
require 'escort/global_pre_parser'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
describe "Escort basic app with conflicting options", :integration => true do
|
2
|
+
subject { Escort::App.create(option_string, &app_configuration) }
|
3
|
+
|
4
|
+
let(:app_configuration) do
|
5
|
+
lambda do |app|
|
6
|
+
app.options do |opts|
|
7
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
8
|
+
opts.opt :flag2, "Flag 2", :short => :none, :long => '--flag2', :type => :boolean
|
9
|
+
|
10
|
+
opts.conflict :flag1, :flag2
|
11
|
+
end
|
12
|
+
|
13
|
+
app.action do |options, arguments|
|
14
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when conflicting options supplied" do
|
20
|
+
let(:option_string) { "--flag1 --flag2" }
|
21
|
+
it("should exit with code 2 or 3") { expect{ subject }.to exit_with_code(2, 3) }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when no conflicting options supplied" do
|
25
|
+
let(:option_string) { "--flag1" }
|
26
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when non-existant option in conflict list" do
|
30
|
+
let(:app_configuration) do
|
31
|
+
lambda do |app|
|
32
|
+
app.options do |opts|
|
33
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
34
|
+
opts.opt :flag2, "Flag 2", :short => :none, :long => '--flag2', :type => :boolean
|
35
|
+
|
36
|
+
opts.conflict :flag1, :flag2, :flag3
|
37
|
+
end
|
38
|
+
|
39
|
+
app.action do |options, arguments|
|
40
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
let(:option_string) { "--flag1" }
|
45
|
+
it("should exit with code 2") { expect{ subject }.to exit_with_code(2) }
|
46
|
+
end
|
47
|
+
end
|