convoy 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
autoload :Nesty, "nesty"
|
2
|
+
|
3
|
+
module Convoy
|
4
|
+
autoload :Trollop, "convoy/trollop"
|
5
|
+
autoload :Utils, "convoy/utils"
|
6
|
+
autoload :Arguments, "convoy/arguments"
|
7
|
+
autoload :Logger, "convoy/logger"
|
8
|
+
autoload :SetupAccessor, "convoy/setup_accessor"
|
9
|
+
autoload :OptionDependencyValidator, "convoy/option_dependency_validator"
|
10
|
+
autoload :Validator, "convoy/validator"
|
11
|
+
autoload :AutoOptions, "convoy/auto_options"
|
12
|
+
autoload :GlobalPreParser, "convoy/global_pre_parser"
|
13
|
+
autoload :OptionParser, "convoy/option_parser"
|
14
|
+
autoload :App, "convoy/app"
|
15
|
+
|
16
|
+
autoload :Error, "convoy/error/error"
|
17
|
+
autoload :BaseError, "convoy/error/error"
|
18
|
+
autoload :UserError, "convoy/error/error"
|
19
|
+
autoload :InternalError, "convoy/error/error"
|
20
|
+
autoload :ClientError, "convoy/error/error"
|
21
|
+
autoload :TransientError, "convoy/error/error"
|
22
|
+
|
23
|
+
module Formatter
|
24
|
+
autoload :Option, "convoy/formatter/option"
|
25
|
+
autoload :Options, "convoy/formatter/options"
|
26
|
+
autoload :Command, "convoy/formatter/command"
|
27
|
+
autoload :Commands, "convoy/formatter/commands"
|
28
|
+
autoload :GlobalCommand, "convoy/formatter/global_command"
|
29
|
+
autoload :ShellCommandExecutor, "convoy/formatter/shell_command_executor"
|
30
|
+
autoload :Terminal, "convoy/formatter/terminal"
|
31
|
+
autoload :StringSplitter, "convoy/formatter/string_splitter"
|
32
|
+
autoload :CursorPosition, "convoy/formatter/cursor_position"
|
33
|
+
autoload :StreamOutputFormatter, "convoy/formatter/stream_output_formatter"
|
34
|
+
autoload :StringGrid, "convoy/formatter/string_grid"
|
35
|
+
autoload :DefaultHelpFormatter, "convoy/formatter/default_help_formatter"
|
36
|
+
end
|
37
|
+
|
38
|
+
module Setup
|
39
|
+
module Dsl
|
40
|
+
autoload :Options, "convoy/setup/dsl/options"
|
41
|
+
autoload :Action, "convoy/setup/dsl/action"
|
42
|
+
autoload :Command, "convoy/setup/dsl/command"
|
43
|
+
autoload :ConfigFile, "convoy/setup/dsl/config_file"
|
44
|
+
autoload :Global, "convoy/setup/dsl/global"
|
45
|
+
end
|
46
|
+
|
47
|
+
module Configuration
|
48
|
+
module Locator
|
49
|
+
autoload :Base, "convoy/setup/configuration/locator/base"
|
50
|
+
autoload :DescendingToHome, "convoy/setup/configuration/locator/descending_to_home"
|
51
|
+
autoload :ExecutingScriptDirectory, "convoy/setup/configuration/locator/executing_script_directory"
|
52
|
+
autoload :SpecifiedDirectory, "convoy/setup/configuration/locator/specified_directory"
|
53
|
+
autoload :Chaining, "convoy/setup/configuration/locator/chaining"
|
54
|
+
end
|
55
|
+
|
56
|
+
autoload :MergeTool, "convoy/setup/configuration/merge_tool"
|
57
|
+
autoload :Instance, "convoy/setup/configuration/instance"
|
58
|
+
autoload :Reader, "convoy/setup/configuration/reader"
|
59
|
+
autoload :Writer, "convoy/setup/configuration/writer"
|
60
|
+
autoload :Generator, "convoy/setup/configuration/generator"
|
61
|
+
autoload :Loader, "convoy/setup/configuration/loader"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module ActionCommand
|
66
|
+
autoload :Base, "convoy/action_command/base"
|
67
|
+
autoload :ConvoyUtilityCommand, "convoy/action_command/convoy_utility_command"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
at_exit do
|
72
|
+
Convoy::Logger.close
|
73
|
+
end
|
74
|
+
|
75
|
+
def error_logger
|
76
|
+
Convoy::Logger.error
|
77
|
+
end
|
78
|
+
|
79
|
+
def output_logger
|
80
|
+
Convoy::Logger.output
|
81
|
+
end
|
82
|
+
|
83
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Convoy
|
2
|
+
module ActionCommand
|
3
|
+
class Base
|
4
|
+
attr_reader :options, :arguments, :config
|
5
|
+
|
6
|
+
def initialize(options, arguments, config={})
|
7
|
+
@options = options
|
8
|
+
@arguments = arguments
|
9
|
+
@config = config
|
10
|
+
@command_context = nil
|
11
|
+
@command_options = nil
|
12
|
+
@parent_options = nil
|
13
|
+
@grandparent_options = nil
|
14
|
+
@global_options = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def command_context
|
20
|
+
return @command_context if @command_context
|
21
|
+
@command_context = []
|
22
|
+
options[:global] ||= {}
|
23
|
+
current_command_hash = options[:global][:commands] || {}
|
24
|
+
until current_command_hash.keys.empty?
|
25
|
+
key = current_command_hash.keys.first
|
26
|
+
@command_context << key
|
27
|
+
current_command_hash = current_command_hash[key][:commands] || {}
|
28
|
+
end
|
29
|
+
@command_context
|
30
|
+
end
|
31
|
+
|
32
|
+
def command_name
|
33
|
+
command_context.last || :global
|
34
|
+
end
|
35
|
+
|
36
|
+
def command_options
|
37
|
+
@command_options ||= context_hash(command_context)[:options] || {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def global_options
|
41
|
+
@global_options ||= (options[:global] || {})[:options] || {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def parent_options
|
45
|
+
@parent_options ||= ensure_parent { |parent_context| context_hash(parent_context)[:options] || {} }
|
46
|
+
end
|
47
|
+
|
48
|
+
def grandparent_options
|
49
|
+
@grandparent_options ||= ensure_grandparent { |grandparent_context| context_hash(grandparent_context)[:options] || {} }
|
50
|
+
end
|
51
|
+
|
52
|
+
#generation_number 1 is parent, 2 is grandparent and so on
|
53
|
+
#default is 3 for great grandparent
|
54
|
+
def ancestor_options(generation_number = 3)
|
55
|
+
ensure_ancestor(generation_number) { |ancestor_context| context_hash(ancestor_context)[:options] || {} }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def context_hash(context)
|
61
|
+
context_hash = options[:global]
|
62
|
+
context.each do |command_name|
|
63
|
+
context_hash = context_hash[:commands][command_name]
|
64
|
+
end
|
65
|
+
context_hash
|
66
|
+
end
|
67
|
+
|
68
|
+
def ensure_parent(&block)
|
69
|
+
ensure_ancestor(1, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def ensure_grandparent(&block)
|
73
|
+
ensure_ancestor(2, &block)
|
74
|
+
end
|
75
|
+
|
76
|
+
def ensure_ancestor(generation_number, &block)
|
77
|
+
return {} if generation_number < 0
|
78
|
+
#return {} if generation_number == 0
|
79
|
+
return {} unless command_context.size >= generation_number
|
80
|
+
ancestor_context = command_context.dup.slice(0, command_context.size - generation_number)
|
81
|
+
block.call(ancestor_context)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Convoy
|
2
|
+
module ActionCommand
|
3
|
+
class ConvoyUtilityCommand < Base
|
4
|
+
attr_reader :setup
|
5
|
+
|
6
|
+
def initialize(setup, options, arguments, config = {})
|
7
|
+
super(options, arguments, config)
|
8
|
+
@setup = setup
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
current_command_options = command_options
|
13
|
+
if current_command_options[:create_config_given]
|
14
|
+
create_config(current_command_options[:create_config])
|
15
|
+
elsif current_command_options[:create_default_config_given]
|
16
|
+
create_default_config
|
17
|
+
elsif current_command_options[:update_config_given]
|
18
|
+
update_config(current_command_options[:update_config])
|
19
|
+
elsif current_command_options[:update_default_config_given]
|
20
|
+
update_default_config
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def create_config(path)
|
27
|
+
config_path = absolute_path(path)
|
28
|
+
Convoy::Setup::Configuration::Writer.new(config_path, Convoy::Setup::Configuration::Generator.new(setup).default_data).write
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_default_config
|
32
|
+
Convoy::Setup::Configuration::Writer.new(default_config_path, Convoy::Setup::Configuration::Generator.new(setup).default_data).write
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_config(path)
|
36
|
+
config_path = absolute_path(path)
|
37
|
+
Convoy::Setup::Configuration::Writer.new(config_path, Convoy::Setup::Configuration::Generator.new(setup).default_data).update
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_default_config
|
41
|
+
Convoy::Setup::Configuration::Writer.new(default_config_path, Convoy::Setup::Configuration::Generator.new(setup).default_data).update
|
42
|
+
end
|
43
|
+
|
44
|
+
def absolute_path(path)
|
45
|
+
File.expand_path(path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_config_path
|
49
|
+
Convoy::Setup::Configuration::Loader.new(setup, nil).default_config_path
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/convoy/app.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
module Convoy
|
2
|
+
class App
|
3
|
+
#TODO ensure that every command must have an action
|
4
|
+
class << self
|
5
|
+
def create(option_string = '', &block)
|
6
|
+
self.new(option_string, &block).setup_application.execute
|
7
|
+
exit(0)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :setup, :option_string
|
12
|
+
|
13
|
+
def initialize(option_string, &block)
|
14
|
+
@option_string = option_string
|
15
|
+
@setup = nil
|
16
|
+
@block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_application
|
20
|
+
old_error_sev_threshold = error_logger.sev_threshold
|
21
|
+
begin
|
22
|
+
error_logger.sev_threshold = ::Logger::DEBUG
|
23
|
+
cli_app_configuration = Convoy::Setup::Dsl::Global.new(&@block)
|
24
|
+
@setup = Convoy::SetupAccessor.new(cli_app_configuration)
|
25
|
+
self
|
26
|
+
rescue => e
|
27
|
+
handle_convoy_error(e)
|
28
|
+
ensure
|
29
|
+
error_logger.sev_threshold = old_error_sev_threshold
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute
|
34
|
+
begin
|
35
|
+
AutoOptions.augment(setup)
|
36
|
+
|
37
|
+
cli_options = current_cli_options(option_string)
|
38
|
+
|
39
|
+
auto_options = Convoy::GlobalPreParser.new(setup).parse(cli_options.dup)
|
40
|
+
Convoy::Logger.setup_error_logger(auto_options)
|
41
|
+
|
42
|
+
#now we can start doing error logging everything above here has to be rock solid
|
43
|
+
|
44
|
+
configuration = Convoy::Setup::Configuration::Loader.new(setup, auto_options).configuration
|
45
|
+
|
46
|
+
invoked_options, arguments = Convoy::OptionParser.new(configuration, setup).parse(cli_options)
|
47
|
+
context = context_from_options(invoked_options[:global])
|
48
|
+
action = setup.action_for(context)
|
49
|
+
current_command = context.empty? ? :global : context.last
|
50
|
+
raise Convoy::ClientError.new("No action defined for command '#{current_command}'") unless action
|
51
|
+
actual_arguments = Convoy::Arguments.read(arguments, setup.arguments_required_for(context))
|
52
|
+
rescue => e
|
53
|
+
handle_convoy_error(e)
|
54
|
+
end
|
55
|
+
execute_action(action, invoked_options, actual_arguments, configuration.user)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def current_cli_options(option_string)
|
61
|
+
passed_in_options = Convoy::Utils.tokenize_option_string(option_string)
|
62
|
+
passed_in_options.empty? ? ARGV.dup : passed_in_options
|
63
|
+
end
|
64
|
+
|
65
|
+
def execute_action(action, options, arguments, user_config)
|
66
|
+
begin
|
67
|
+
#execute before servants here
|
68
|
+
action.call(options, arguments, user_config)
|
69
|
+
#execute after servants here
|
70
|
+
rescue => e
|
71
|
+
handle_action_error(e)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def context_from_options(options)
|
76
|
+
commands_in_order(options)
|
77
|
+
end
|
78
|
+
|
79
|
+
def commands_in_order(options, commands = [])
|
80
|
+
if options[:commands].keys.empty?
|
81
|
+
commands
|
82
|
+
else
|
83
|
+
command = options[:commands].keys.first
|
84
|
+
commands << command
|
85
|
+
commands_in_order(options[:commands][command], commands)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def handle_convoy_error(e)
|
90
|
+
if e.kind_of?(Convoy::UserError)
|
91
|
+
print_stacktrace(e)
|
92
|
+
error_logger.debug {'Convoy app failed to execute successfully, due to user error'}
|
93
|
+
exit(Convoy::USER_ERROR_EXIT_CODE)
|
94
|
+
elsif e.kind_of?(Convoy::ClientError)
|
95
|
+
print_stacktrace(e)
|
96
|
+
error_logger.debug {'Convoy app failed to execute successfully, due to client setup error'}
|
97
|
+
exit(Convoy::CLIENT_ERROR_EXIT_CODE)
|
98
|
+
else
|
99
|
+
print_convoy_error_message(e)
|
100
|
+
error_logger.debug {'Convoy app failed to execute successfully, due to internal error'}
|
101
|
+
exit(Convoy::INTERNAL_ERROR_EXIT_CODE)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def handle_action_error(e)
|
106
|
+
if e.kind_of?(Convoy::Error)
|
107
|
+
print_convoy_error_message(e)
|
108
|
+
error_logger.debug {'Convoy app failed to execute successfully, due to internal error'}
|
109
|
+
exit(Convoy::INTERNAL_ERROR_EXIT_CODE)
|
110
|
+
else
|
111
|
+
print_stacktrace(e)
|
112
|
+
error_logger.debug {'Convoy app failed to execute successfully, due to unknown error'}
|
113
|
+
exit(Convoy::EXTERNAL_ERROR_EXIT_CODE)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def print_stacktrace(e)
|
118
|
+
error_logger.error { e.message }
|
119
|
+
error_logger.debug { e }
|
120
|
+
end
|
121
|
+
|
122
|
+
def print_convoy_error_message(e)
|
123
|
+
print_stacktrace(e)
|
124
|
+
error_logger.warn {"\n \x1B[48;5;196m ERROR \x1B[0m An internal Convoy error occurred.\n\n You should probably report it to \x1B[38;5;222mAlbert Rannetsperger\x1B[0m or create an issue on his \x1B[38;5;222mGitHub\x1B[0m page (https://github.com/alb3rtuk).\n Make sure to include the stacktrace above (although it probably won't be very helpful).bp\n\n"}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'readline'
|
2
|
+
|
3
|
+
module Convoy
|
4
|
+
class Arguments
|
5
|
+
class << self
|
6
|
+
def read(arguments, requires_arguments=false)
|
7
|
+
if arguments.empty? && requires_arguments
|
8
|
+
while command = Readline.readline("> ", true)
|
9
|
+
arguments << command
|
10
|
+
end
|
11
|
+
arguments = arguments.compact.keep_if { |value| value.length > 0 }
|
12
|
+
if arguments.empty?
|
13
|
+
raise Convoy::UserError.new("You must provide some arguments to this script")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
arguments
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Convoy
|
2
|
+
class AutoOptions
|
3
|
+
class << self
|
4
|
+
def augment(setup)
|
5
|
+
if setup.has_config_file?
|
6
|
+
setup.add_global_option :config, "Configuration file to use for this execution", :short => :none, :long => '--config', :type => :string
|
7
|
+
|
8
|
+
setup.add_global_command :convoy, :aliases => [] do |command|
|
9
|
+
command.summary "Auto created utility command"
|
10
|
+
command.description "Auto created utility command"
|
11
|
+
command.requires_arguments false
|
12
|
+
|
13
|
+
command.options do |opts|
|
14
|
+
opts.opt :create_config, "Create configuration file at specified location", :short => :none, :long => '--create-config', :type => :string
|
15
|
+
opts.opt :create_default_config, "Create a default configuration file", :short => :none, :long => '--create-default-config', :type => :boolean, :default => false
|
16
|
+
opts.opt :update_config, "Update configuration file at specified location", :short => :none, :long => '--update-config', :type => :string
|
17
|
+
opts.opt :update_default_config, "Update the default configuration file", :short => :none, :long => '--update-default-config', :type => :boolean, :default => false
|
18
|
+
|
19
|
+
opts.conflict :create_config, :create_default_config, :update_config, :update_default_config
|
20
|
+
end
|
21
|
+
|
22
|
+
command.action do |options, arguments|
|
23
|
+
ActionCommand::ConvoyUtilityCommand.new(setup, options, arguments).execute
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
setup.add_global_option :verbosity, 'Verbosity level of output for current execution (e.g. INFO, DEBUG)', :short => :none, :long => '--verbosity', :type => :string, :default => 'WARN'
|
28
|
+
setup.add_global_option :error_output_format, 'The format to use when outputting errors (e.g. basic, advanced)', :short => :none, :long => '--error-output-format', :type => :string, :default => 'basic'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :options
|
33
|
+
|
34
|
+
def initialize(options)
|
35
|
+
@options = options
|
36
|
+
end
|
37
|
+
|
38
|
+
def non_default_config_path
|
39
|
+
if options[:config_given] && File.exists?(config_path)
|
40
|
+
config_path
|
41
|
+
elsif !options[:config_given]
|
42
|
+
nil
|
43
|
+
else
|
44
|
+
error_logger.warn "The given config file '#{options[:config]}' does not exist, falling back to default"
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def verbosity
|
50
|
+
error_verbosity.upcase
|
51
|
+
end
|
52
|
+
|
53
|
+
def error_formatter
|
54
|
+
error_output_format.to_sym
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def config_path
|
60
|
+
File.expand_path(options[:config])
|
61
|
+
end
|
62
|
+
|
63
|
+
def error_output_format
|
64
|
+
options[:error_output_format]
|
65
|
+
end
|
66
|
+
|
67
|
+
def error_verbosity
|
68
|
+
options[:verbosity]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Convoy
|
2
|
+
INTERNAL_ERROR_EXIT_CODE = 1
|
3
|
+
CLIENT_ERROR_EXIT_CODE = 2
|
4
|
+
USER_ERROR_EXIT_CODE = 3
|
5
|
+
EXTERNAL_ERROR_EXIT_CODE = 10
|
6
|
+
|
7
|
+
#module to tag all exceptions coming out of Convoy with
|
8
|
+
module Error
|
9
|
+
end
|
10
|
+
|
11
|
+
#all our exceptions will supported nesting other exceptions
|
12
|
+
#also all our exception will be a kind_of? Convoy::Error
|
13
|
+
class BaseError < StandardError
|
14
|
+
include Nesty::NestedError
|
15
|
+
include Error
|
16
|
+
end
|
17
|
+
|
18
|
+
#user did something invalid
|
19
|
+
class UserError < BaseError
|
20
|
+
end
|
21
|
+
|
22
|
+
#for errors with convoy itself
|
23
|
+
class InternalError < BaseError
|
24
|
+
end
|
25
|
+
|
26
|
+
#for errors with how convoy is being used
|
27
|
+
class ClientError < BaseError
|
28
|
+
end
|
29
|
+
|
30
|
+
#a dependency is temporarily unavailable
|
31
|
+
class TransientError < BaseError
|
32
|
+
end
|
33
|
+
end
|