convoy 1.0.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 +7 -0
- data/.gitignore +20 -0
- data/.irbrc +3 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +705 -0
- data/Rakefile +1 -0
- data/convoy.gemspec +24 -0
- data/examples/.my_apprc +24 -0
- data/examples/basic +10 -0
- data/examples/basic_config_file +16 -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/basic_with_everything +30 -0
- data/examples/commands/example_command.rb +13 -0
- data/examples/suite_complex +65 -0
- data/examples/suite_simple +19 -0
- data/examples/suite_with_sub_commands +94 -0
- data/lib/convoy.rb +83 -0
- data/lib/convoy/action_command/base.rb +85 -0
- data/lib/convoy/action_command/escort_utility_command.rb +53 -0
- data/lib/convoy/app.rb +127 -0
- data/lib/convoy/arguments.rb +20 -0
- data/lib/convoy/auto_options.rb +71 -0
- data/lib/convoy/error/error.rb +33 -0
- data/lib/convoy/formatter/command.rb +87 -0
- data/lib/convoy/formatter/commands.rb +37 -0
- data/lib/convoy/formatter/cursor_position.rb +29 -0
- data/lib/convoy/formatter/default_help_formatter.rb +117 -0
- data/lib/convoy/formatter/global_command.rb +17 -0
- data/lib/convoy/formatter/option.rb +152 -0
- data/lib/convoy/formatter/options.rb +28 -0
- data/lib/convoy/formatter/shell_command_executor.rb +49 -0
- data/lib/convoy/formatter/stream_output_formatter.rb +88 -0
- data/lib/convoy/formatter/string_grid.rb +108 -0
- data/lib/convoy/formatter/string_splitter.rb +50 -0
- data/lib/convoy/formatter/terminal.rb +30 -0
- data/lib/convoy/global_pre_parser.rb +43 -0
- data/lib/convoy/logger.rb +75 -0
- data/lib/convoy/option_dependency_validator.rb +82 -0
- data/lib/convoy/option_parser.rb +155 -0
- data/lib/convoy/setup/configuration/generator.rb +75 -0
- data/lib/convoy/setup/configuration/instance.rb +34 -0
- data/lib/convoy/setup/configuration/loader.rb +43 -0
- data/lib/convoy/setup/configuration/locator/base.rb +19 -0
- data/lib/convoy/setup/configuration/locator/chaining.rb +29 -0
- data/lib/convoy/setup/configuration/locator/descending_to_home.rb +23 -0
- data/lib/convoy/setup/configuration/locator/executing_script_directory.rb +15 -0
- data/lib/convoy/setup/configuration/locator/specified_directory.rb +21 -0
- data/lib/convoy/setup/configuration/merge_tool.rb +38 -0
- data/lib/convoy/setup/configuration/reader.rb +36 -0
- data/lib/convoy/setup/configuration/writer.rb +46 -0
- data/lib/convoy/setup/dsl/action.rb +17 -0
- data/lib/convoy/setup/dsl/command.rb +67 -0
- data/lib/convoy/setup/dsl/config_file.rb +13 -0
- data/lib/convoy/setup/dsl/global.rb +29 -0
- data/lib/convoy/setup/dsl/options.rb +81 -0
- data/lib/convoy/setup_accessor.rb +206 -0
- data/lib/convoy/trollop.rb +861 -0
- data/lib/convoy/utils.rb +21 -0
- data/lib/convoy/validator.rb +45 -0
- data/spec/integration/basic_config_file_spec.rb +126 -0
- 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 +41 -0
- data/spec/integration/basic_options_with_multi_spec.rb +30 -0
- data/spec/integration/basic_spec.rb +38 -0
- data/spec/integration/basic_validations_spec.rb +77 -0
- data/spec/integration/basic_with_arguments_spec.rb +35 -0
- data/spec/integration/basic_with_text_fields_spec.rb +21 -0
- data/spec/integration/suite_simple_spec.rb +45 -0
- data/spec/integration/suite_sub_command_spec.rb +51 -0
- data/spec/lib/convoy/action_command/base_spec.rb +200 -0
- data/spec/lib/convoy/formatter/command_spec.rb +238 -0
- data/spec/lib/convoy/formatter/global_command_spec.rb +50 -0
- data/spec/lib/convoy/formatter/option_spec.rb +300 -0
- data/spec/lib/convoy/formatter/shell_command_executor_spec.rb +59 -0
- data/spec/lib/convoy/formatter/stream_output_formatter_spec.rb +214 -0
- data/spec/lib/convoy/formatter/string_grid_spec.rb +59 -0
- data/spec/lib/convoy/formatter/string_splitter_spec.rb +50 -0
- data/spec/lib/convoy/formatter/terminal_spec.rb +19 -0
- data/spec/lib/convoy/setup/configuration/generator_spec.rb +101 -0
- data/spec/lib/convoy/setup/configuration/loader_spec.rb +79 -0
- data/spec/lib/convoy/setup/configuration/locator/chaining_spec.rb +81 -0
- data/spec/lib/convoy/setup/configuration/locator/descending_to_home_spec.rb +57 -0
- data/spec/lib/convoy/setup/configuration/locator/executing_script_directory_spec.rb +29 -0
- data/spec/lib/convoy/setup/configuration/locator/specified_directory_spec.rb +33 -0
- data/spec/lib/convoy/setup/configuration/merge_tool_spec.rb +41 -0
- data/spec/lib/convoy/setup/configuration/reader_spec.rb +41 -0
- data/spec/lib/convoy/setup/configuration/writer_spec.rb +75 -0
- data/spec/lib/convoy/setup_accessor_spec.rb +226 -0
- data/spec/lib/convoy/utils_spec.rb +30 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/integration_helpers.rb +2 -0
- data/spec/support/matchers/execute_action_for_command_matcher.rb +21 -0
- 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 +292 -0
data/lib/convoy/utils.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
3
|
+
module Convoy
|
|
4
|
+
class Utils
|
|
5
|
+
class << self
|
|
6
|
+
def symbolize_keys(hash)
|
|
7
|
+
hash.inject({}) do |result, (key, value)|
|
|
8
|
+
new_key = (key.kind_of?(String) ? key.to_sym : key)
|
|
9
|
+
new_value = (value.kind_of?(Hash) ? symbolize_keys(value) : value)
|
|
10
|
+
result[new_key] = new_value
|
|
11
|
+
result
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def tokenize_option_string(option_string)
|
|
16
|
+
option_string ||= ''
|
|
17
|
+
Shellwords.shellwords(option_string)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Convoy
|
|
2
|
+
class Validator
|
|
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, validations)
|
|
16
|
+
validations.each do |option, validations_array|
|
|
17
|
+
if option_exists?(option)
|
|
18
|
+
validate_option(option, options, validations_array)
|
|
19
|
+
else
|
|
20
|
+
raise Convoy::ClientError.new("Unable to create validation for '#{option}' as no such option was defined, maybe you misspelled it")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
options
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def option_exists?(option)
|
|
29
|
+
parser.specs.keys.include?(option)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def validate_option(option, options, validations_array)
|
|
33
|
+
validations_array.each do |validation_data|
|
|
34
|
+
if invalid?(option, options, validation_data)
|
|
35
|
+
raise Convoy::UserError.new("#{option} #{validation_data[:desc]}")
|
|
36
|
+
end
|
|
37
|
+
#parser.die(option, validation_data[:desc]) if invalid?(option, options, validation_data)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def invalid?(option, options, validation_data)
|
|
42
|
+
options[option] && !validation_data[:block].call(options[option])
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
describe "Convoy basic app with config file defined", :integration => true do
|
|
2
|
+
include FakeFS::SpecHelpers
|
|
3
|
+
|
|
4
|
+
subject { Convoy::App.create(option_string, &app_configuration) }
|
|
5
|
+
|
|
6
|
+
let(:path) { File.join(File.expand_path('~'), '.test_apprc') }
|
|
7
|
+
let(:app_configuration) do
|
|
8
|
+
lambda do |app|
|
|
9
|
+
app.config_file ".test_apprc", :autocreate => autocreate
|
|
10
|
+
|
|
11
|
+
app.options do |opts|
|
|
12
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
app.action do |options, arguments|
|
|
16
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "when config file is autocreatable" do
|
|
22
|
+
context "and config file does not yet exist" do
|
|
23
|
+
before do
|
|
24
|
+
begin
|
|
25
|
+
subject
|
|
26
|
+
rescue SystemExit => e
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
let(:autocreate) { true }
|
|
30
|
+
let(:option_string) { "" }
|
|
31
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
32
|
+
it("should have created a config file in default location") { File.should exist path }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "and config file already exists" do
|
|
36
|
+
before do
|
|
37
|
+
FileUtils.mkdir_p(File.dirname path)
|
|
38
|
+
File.open(path, 'w') { |f| f.write(JSON.pretty_generate({:global => {:commands => {}, :options => {:option1 => 'hello'}}, :user => {}})) }
|
|
39
|
+
|
|
40
|
+
begin
|
|
41
|
+
subject
|
|
42
|
+
rescue SystemExit => e
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
let(:autocreate) { true }
|
|
46
|
+
let(:option_string) { "" }
|
|
47
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
48
|
+
it("should have picked up the existing config file") { result[:command_options][:option1].should == 'hello' }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when config file is not autocreatable" do
|
|
53
|
+
context "and config file already exists" do
|
|
54
|
+
let(:autocreate) { false }
|
|
55
|
+
let(:option_string) { "" }
|
|
56
|
+
before do
|
|
57
|
+
FileUtils.mkdir_p(File.dirname path)
|
|
58
|
+
File.open(path, 'w') { |f| f.write(JSON.pretty_generate({:global => {:commands => {}, :options => {:option1 => 'hello'}}, :user => {}})) }
|
|
59
|
+
|
|
60
|
+
begin
|
|
61
|
+
subject
|
|
62
|
+
rescue SystemExit => e
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
66
|
+
it("should have picked up the existing config file") { result[:command_options][:option1].should == 'hello' }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "and config file does not yet exist" do
|
|
70
|
+
let(:autocreate) { false }
|
|
71
|
+
let(:option_string) { "" }
|
|
72
|
+
before do
|
|
73
|
+
begin
|
|
74
|
+
subject
|
|
75
|
+
rescue SystemExit => e
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
79
|
+
it("should not have created a config file in default location") { File.should_not exist path }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "when config file specified" do
|
|
84
|
+
let(:autocreate) { false }
|
|
85
|
+
|
|
86
|
+
before do
|
|
87
|
+
FileUtils.mkdir_p(File.dirname path)
|
|
88
|
+
File.open(path, 'w') { |f| f.write(JSON.pretty_generate({:global => {:commands => {}, :options => {:option1 => 'hello'}}, :user => {}})) }
|
|
89
|
+
|
|
90
|
+
begin
|
|
91
|
+
subject
|
|
92
|
+
rescue SystemExit => e
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "--config global option should exist" do
|
|
97
|
+
let(:option_string) { "--config=#{path}" }
|
|
98
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "convoy command should exist" do
|
|
102
|
+
let(:option_string) { "convoy -h" }
|
|
103
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
104
|
+
|
|
105
|
+
context "--create-config option for convoy command should exist" do
|
|
106
|
+
let(:option_string) { "convoy --create-config=#{path}" }
|
|
107
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "--create-default-config option for convoy command should exist" do
|
|
111
|
+
let(:option_string) { "convoy --create-default-config" }
|
|
112
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context "--update-config option for convoy command should exist" do
|
|
116
|
+
let(:option_string) { "convoy --update-config=#{path}" }
|
|
117
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "--update-default-config option for convoy command should exist" do
|
|
121
|
+
let(:option_string) { "convoy --update-default-config" }
|
|
122
|
+
it("should exit with code 0") { expect { subject }.to exit_with_code(0) }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
describe "Convoy basic app with conflicting options", :integration => true do
|
|
2
|
+
subject { Convoy::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
|
+
Convoy::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
|
+
Convoy::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
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
describe "Convoy basic app with dependent options", :integration => true do
|
|
2
|
+
subject { Convoy::App.create(option_string, &app_configuration) }
|
|
3
|
+
|
|
4
|
+
context "when dependency specification has no 'on' parameter" do
|
|
5
|
+
let(:app_configuration) do
|
|
6
|
+
lambda do |app|
|
|
7
|
+
app.options do |opts|
|
|
8
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
9
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
10
|
+
|
|
11
|
+
opts.dependency :option1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
app.action do |options, arguments|
|
|
15
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
let(:option_string) { "-f" }
|
|
20
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "when option dependent on presence of flag" do
|
|
24
|
+
let(:app_configuration) do
|
|
25
|
+
lambda do |app|
|
|
26
|
+
app.options do |opts|
|
|
27
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
28
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
29
|
+
|
|
30
|
+
opts.dependency :option1, :on => :flag1
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
app.action do |options, arguments|
|
|
34
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "and flag is not present" do
|
|
40
|
+
let(:option_string) { "-o foo" }
|
|
41
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "and flag is present" do
|
|
45
|
+
let(:option_string) { "-f -o foo" }
|
|
46
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "when flag depends on another flag" do
|
|
51
|
+
let(:app_configuration) do
|
|
52
|
+
lambda do |app|
|
|
53
|
+
app.options do |opts|
|
|
54
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
55
|
+
opts.opt :flag2, "Flag 2", :short => :none, :long => '--flag2', :type => :boolean, :default => true
|
|
56
|
+
opts.opt :flag3, "Flag 3", :short => :none, :long => '--flag3', :type => :boolean
|
|
57
|
+
opts.opt :flag4, "Flag 4", :short => :none, :long => '--flag4', :type => :boolean
|
|
58
|
+
|
|
59
|
+
opts.dependency :flag3, :on => :flag1
|
|
60
|
+
opts.dependency :flag4, :on => :flag2
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
app.action do |options, arguments|
|
|
64
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "and other flag has a default value of false" do
|
|
70
|
+
context "and other flag is present" do
|
|
71
|
+
let(:option_string) { "--flag1 --flag3" }
|
|
72
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "and other flag is not present" do
|
|
76
|
+
let(:option_string) { "--flag3" }
|
|
77
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "and other flag has a default value of true" do
|
|
82
|
+
context "and other flag is present" do
|
|
83
|
+
let(:option_string) { "--flag2 --flag4" }
|
|
84
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "and other flag is not present" do
|
|
88
|
+
let(:option_string) { "--flag4" }
|
|
89
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context "and other flag negative option is used" do
|
|
93
|
+
let(:option_string) { "--no-flag2 --flag4" }
|
|
94
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
context "when option dependent on presence of multiple other options" do
|
|
100
|
+
let(:app_configuration) do
|
|
101
|
+
lambda do |app|
|
|
102
|
+
app.options do |opts|
|
|
103
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
104
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
105
|
+
opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
|
|
106
|
+
|
|
107
|
+
opts.dependency :option2, :on => [:flag1, :option1]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
app.action do |options, arguments|
|
|
111
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "and one of the other options is not present" do
|
|
117
|
+
let(:option_string) { "-f --option2=foo" }
|
|
118
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "and none of the other options are present" do
|
|
122
|
+
let(:option_string) { "--option2=foo" }
|
|
123
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context "and all of the other options are present" do
|
|
127
|
+
let(:option_string) { "-f -o bar --option2=foo" }
|
|
128
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "when option dependent on other option value" do
|
|
133
|
+
let(:app_configuration) do
|
|
134
|
+
lambda do |app|
|
|
135
|
+
app.options do |opts|
|
|
136
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
137
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
138
|
+
opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
|
|
139
|
+
|
|
140
|
+
opts.dependency :option2, :on => {:option1 => 'bar'}
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
app.action do |options, arguments|
|
|
144
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "and other option is supplied with this value" do
|
|
150
|
+
let(:option_string) { "-o bar --option2=foo" }
|
|
151
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context "and other option is supplied with different value" do
|
|
155
|
+
let(:option_string) { "-o baz --option2=foo" }
|
|
156
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context "and other option is not supplied" do
|
|
160
|
+
let(:option_string) { "--option2=foo" }
|
|
161
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context "when option dependent on other option value and presence of yet another option" do
|
|
166
|
+
let(:app_configuration) do
|
|
167
|
+
lambda do |app|
|
|
168
|
+
app.options do |opts|
|
|
169
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
170
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
171
|
+
opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
|
|
172
|
+
|
|
173
|
+
opts.dependency :option2, :on => [:flag1, {:option1 => 'bar'}]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
app.action do |options, arguments|
|
|
177
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context "and yet another option is not present" do
|
|
183
|
+
let(:option_string) { "-o bar --option2=foo" }
|
|
184
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context "and other option has different value" do
|
|
188
|
+
let(:option_string) { "-o baz -f --option2=foo" }
|
|
189
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context "and other option has the right value and yet another option is present" do
|
|
193
|
+
let(:option_string) { "-o bar -f --option2=foo" }
|
|
194
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
context "when option dependent on itself" do
|
|
199
|
+
let(:app_configuration) do
|
|
200
|
+
lambda do |app|
|
|
201
|
+
app.options do |opts|
|
|
202
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
203
|
+
|
|
204
|
+
opts.dependency :option1, :on => :option1
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
app.action do |options, arguments|
|
|
208
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
let(:option_string) { "-o bar" }
|
|
213
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context "when dependency specified for non-existant option" do
|
|
217
|
+
let(:app_configuration) do
|
|
218
|
+
lambda do |app|
|
|
219
|
+
app.options do |opts|
|
|
220
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
221
|
+
|
|
222
|
+
opts.dependency :option2, :on => :option1
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
app.action do |options, arguments|
|
|
226
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
let(:option_string) { "-o bar" }
|
|
231
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
context "when option dependent on non-existant option" do
|
|
235
|
+
let(:app_configuration) do
|
|
236
|
+
lambda do |app|
|
|
237
|
+
app.options do |opts|
|
|
238
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
|
|
239
|
+
|
|
240
|
+
opts.dependency :option1, :on => :option2
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
app.action do |options, arguments|
|
|
244
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
let(:option_string) { "-o bar" }
|
|
249
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
context "when dependency is specified inline" do
|
|
253
|
+
let(:app_configuration) do
|
|
254
|
+
lambda do |app|
|
|
255
|
+
app.options do |opts|
|
|
256
|
+
opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
|
|
257
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :depends_on => :flag1
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
app.action do |options, arguments|
|
|
261
|
+
Convoy::IntegrationTestCommand.new(options, arguments).execute(result)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
context "and dependency is satisfied" do
|
|
266
|
+
let(:option_string) { "-f -o bar" }
|
|
267
|
+
it("it should exit successfully") { expect { subject }.to exit_with_code(0) }
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
context "and dependency is not satisfied" do
|
|
271
|
+
let(:option_string) { "-o bar" }
|
|
272
|
+
it("it should not exit successfully") { expect { subject }.to_not exit_with_code(0) }
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|