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.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
|