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.
Files changed (86) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +365 -14
  4. data/TODO.md +157 -44
  5. data/escort.gemspec +1 -0
  6. data/examples/{1_1_basic.rb → attic/1_1_basic.rb} +0 -0
  7. data/examples/{1_2_basic_requires_arguments.rb → attic/1_2_basic_requires_arguments.rb} +0 -0
  8. data/examples/{2_2_command.rb → attic/2_2_command.rb} +0 -0
  9. data/examples/{2_2_command_requires_arguments.rb → attic/2_2_command_requires_arguments.rb} +0 -0
  10. data/examples/{2_3_nested_commands.rb → attic/2_3_nested_commands.rb} +0 -0
  11. data/examples/{3_validations.rb → attic/3_validations.rb} +0 -0
  12. data/examples/{4_1_config_file.rb → attic/4_1_config_file.rb} +0 -0
  13. data/examples/{argument_handling → attic/argument_handling}/basic.rb +0 -0
  14. data/examples/{argument_handling → attic/argument_handling}/basic_command.rb +0 -0
  15. data/examples/{argument_handling → attic/argument_handling}/no_arguments.rb +0 -0
  16. data/examples/{argument_handling → attic/argument_handling}/no_arguments_command.rb +0 -0
  17. data/examples/{command_aliases → attic/command_aliases}/app.rb +0 -0
  18. data/examples/{config_file → attic/config_file}/.apprc2 +0 -0
  19. data/examples/{config_file → attic/config_file}/app.rb +0 -0
  20. data/examples/{config_file → attic/config_file}/sub_commands.rb +0 -0
  21. data/examples/{default_command → attic/default_command}/app.rb +0 -0
  22. data/examples/{sub_commands → attic/sub_commands}/app.rb +0 -0
  23. data/examples/{validation_basic → attic/validation_basic}/app.rb +0 -0
  24. data/examples/basic +10 -0
  25. data/examples/basic_conflicts +17 -0
  26. data/examples/basic_depends_on +25 -0
  27. data/examples/basic_flags +15 -0
  28. data/examples/basic_options +14 -0
  29. data/examples/basic_options_multi +15 -0
  30. data/examples/basic_require_arguments +17 -0
  31. data/examples/basic_texts +21 -0
  32. data/examples/basic_validations +21 -0
  33. data/examples/command +19 -0
  34. data/examples/commands/example_command.rb +13 -0
  35. data/lib/escort/action_command/base.rb +4 -0
  36. data/lib/escort/app.rb +33 -11
  37. data/lib/escort/formatter/borderless_table.rb +4 -0
  38. data/lib/escort/formatter/command.rb +87 -0
  39. data/lib/escort/formatter/commands.rb +36 -0
  40. data/lib/escort/formatter/default_help_formatter.rb +68 -73
  41. data/lib/escort/formatter/global_command.rb +17 -0
  42. data/lib/escort/formatter/option.rb +138 -0
  43. data/lib/escort/formatter/options.rb +17 -3
  44. data/lib/escort/formatter/shell_command_executor.rb +49 -0
  45. data/lib/escort/formatter/terminal.rb +17 -9
  46. data/lib/escort/formatter/terminal_formatter.rb +6 -0
  47. data/lib/escort/logger.rb +4 -4
  48. data/lib/escort/option_dependency_validator.rb +83 -0
  49. data/lib/escort/option_parser.rb +11 -1
  50. data/lib/escort/setup/configuration/reader.rb +0 -2
  51. data/lib/escort/setup/configuration/writer.rb +0 -2
  52. data/lib/escort/setup/dsl/command.rb +2 -7
  53. data/lib/escort/setup/dsl/global.rb +2 -9
  54. data/lib/escort/setup/dsl/options.rb +56 -0
  55. data/lib/escort/setup_accessor.rb +23 -6
  56. data/lib/escort/trollop.rb +4 -3
  57. data/lib/escort/validator.rb +4 -1
  58. data/lib/escort/version.rb +1 -1
  59. data/lib/escort.rb +8 -1
  60. data/spec/integration/basic_conflicts_spec.rb +47 -0
  61. data/spec/integration/basic_depends_on_spec.rb +275 -0
  62. data/spec/integration/basic_options_spec.rb +9 -21
  63. data/spec/integration/basic_options_with_multi_spec.rb +30 -0
  64. data/spec/integration/basic_spec.rb +5 -6
  65. data/spec/integration/basic_validations_spec.rb +77 -0
  66. data/spec/integration/basic_with_arguments_spec.rb +33 -0
  67. data/spec/integration/basic_with_text_fields_spec.rb +21 -0
  68. data/spec/lib/escort/formatter/command_spec.rb +238 -0
  69. data/spec/lib/escort/formatter/global_command_spec.rb +50 -0
  70. data/spec/lib/escort/formatter/option_spec.rb +300 -0
  71. data/spec/lib/escort/formatter/shell_command_executor_spec.rb +59 -0
  72. data/spec/lib/escort/formatter/string_splitter_spec.rb +12 -0
  73. data/spec/lib/escort/formatter/terminal_spec.rb +19 -0
  74. data/spec/lib/escort/setup_accessor_spec.rb +1 -0
  75. data/spec/spec_helper.rb +9 -3
  76. data/spec/support/integration_helpers.rb +2 -0
  77. data/spec/{helpers/execute_action_matcher.rb → support/matchers/execute_action_for_command_matcher.rb} +3 -3
  78. data/spec/support/matchers/execute_action_with_arguments_matcher.rb +25 -0
  79. data/spec/support/matchers/execute_action_with_options_matcher.rb +29 -0
  80. data/spec/support/matchers/exit_with_code_matcher.rb +29 -0
  81. data/spec/support/shared_contexts/integration_setup.rb +34 -0
  82. metadata +86 -28
  83. data/examples/basic/app.rb +0 -16
  84. data/lib/escort/formatter/common.rb +0 -58
  85. data/spec/helpers/exit_with_code_matcher.rb +0 -21
  86. data/spec/helpers/give_option_to_action_with_value_matcher.rb +0 -22
@@ -0,0 +1,87 @@
1
+ module Escort
2
+ module Formatter
3
+ class Command
4
+ attr_reader :setup, :context, :name
5
+
6
+ def initialize(command_name, setup, context)
7
+ @setup = setup
8
+ @context = context
9
+ @name = command_name.to_sym
10
+ end
11
+
12
+ def name_with_aliases
13
+ [name, aliases].flatten.join(", ")
14
+ end
15
+
16
+ def outline
17
+ summary.empty? ? description : summary
18
+ end
19
+
20
+ def description
21
+ @description ||= setup.command_description_for(name, context) || ""
22
+ end
23
+
24
+ def summary
25
+ @summary ||= setup.command_summary_for(name, context) || ""
26
+ end
27
+
28
+ def aliases
29
+ @aliases ||= setup.command_aliases_for(name, context)
30
+ end
31
+
32
+ def has_aliases?
33
+ aliases && aliases.size > 0 ? true : false
34
+ end
35
+
36
+ def script_name
37
+ [canonical_script_name, context].flatten.join(" ")
38
+ end
39
+
40
+ def child_commands
41
+ @child_commands ||= setup.canonical_command_names_for(context) || []
42
+ end
43
+
44
+ def has_child_commands?
45
+ child_commands.length > 0
46
+ end
47
+
48
+ def requires_arguments?
49
+ @requires_arguments ||= setup.arguments_required_for(context)
50
+ end
51
+
52
+ def usage
53
+ [script_name_usage_string, parent_commands_usage_string, child_command_usage_string, arguments_usage_string].flatten.reject(&:empty?).join(" ")
54
+ end
55
+
56
+ private
57
+
58
+ def script_name_usage_string
59
+ "#{canonical_script_name} [options]"
60
+ end
61
+
62
+ def parent_commands_usage_string
63
+ context.map{|command_name| command_with_options(command_name)}.join(" ")
64
+ end
65
+
66
+ def child_command_usage_string
67
+ has_child_commands? ? "command [command_options]" : ""
68
+ end
69
+
70
+ def arguments_usage_string
71
+ requires_arguments? ? "arguments" : "[arguments]"
72
+ end
73
+
74
+ def command_with_options(command_name)
75
+ "#{command_name} [#{command_name}_options]"
76
+ end
77
+
78
+ def canonical_script_name
79
+ File.basename($0)
80
+ end
81
+
82
+ def alias_string
83
+ @alias_string ||= aliases.join(", ") if has_aliases?
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,36 @@
1
+ module Escort
2
+ module Formatter
3
+ class Commands
4
+ include Enumerable
5
+
6
+ class << self
7
+ def command_for(setup, context)
8
+ if context.empty?
9
+ GlobalCommand.new(setup)
10
+ else
11
+ Command.new(context.last, setup, context)
12
+ end
13
+ end
14
+ end
15
+
16
+ attr_reader :setup, :context
17
+
18
+ def initialize(setup, context)
19
+ @setup = setup
20
+ @context = context
21
+ end
22
+
23
+ def each(&block)
24
+ setup.canonical_command_names_for(context).each do |command_name|
25
+ command = Command.new(command_name, setup, context)
26
+ block.call(command)
27
+ end
28
+ end
29
+
30
+ def count
31
+ setup.canonical_command_names_for(context).size
32
+ end
33
+ alias_method :size, :count
34
+ end
35
+ end
36
+ end
@@ -1,8 +1,6 @@
1
1
  module Escort
2
2
  module Formatter
3
3
  class DefaultHelpFormatter
4
- include Escort::Formatter::Common
5
-
6
4
  attr_reader :setup, :context
7
5
 
8
6
  def initialize(setup, context)
@@ -11,95 +9,92 @@ module Escort
11
9
  end
12
10
 
13
11
  def print(parser)
14
- option_strings = option_output_strings(parser)
15
- command_strings = command_output_strings
12
+ options = Options.new(parser, setup, context)
13
+ commands = Commands.new(setup, context)
14
+ current_command = Commands.command_for(setup, context)
16
15
 
17
16
  TerminalFormatter.display($stdout, Terminal.width) do |d|
18
- d.puts "NAME"
19
- d.indent(4) do
20
- d.table(:columns => 3, :newlines => 1) do |t|
21
- t.row script_name_with_command, '-', current_command_summary
22
- end
23
- d.put(setup.description_for(context), :newlines => 2) if setup.description_for(context)
24
- end
25
- d.puts "USAGE"
26
- d.indent(4) do
27
- context_usage_part = context.map { |command_name| "#{command_name} [#{command_name} options]" }.join(" ")
28
- context_usage_part ||= ""
29
- nested_command_part = "command [command options]" if !setup.canonical_command_names_for(context).nil? && setup.canonical_command_names_for(context).length > 0
30
- nested_command_part ||= ""
31
- usage_string = "#{script_name} [options] #{context_usage_part} #{nested_command_part} [arguments...]".gsub(/\s+/, ' ')
32
- d.put usage_string, :newlines => 2
33
- end
34
- if setup.version
35
- d.puts "VERSION"
36
- d.indent(4) {
37
- d.put setup.version, :newlines => 2
38
- }
39
- end
40
- if option_strings.keys.size > 0
41
- d.puts "OPTIONS"
42
- d.indent(4) {
43
- d.table(:columns => 3, :newlines => 1) do |t|
44
- option_strings.each_pair do |key, value|
45
- t.row value[:string], '-', value[:desc] || ''
46
- end
47
- end
48
- }
49
- end
50
- if command_strings.keys.size > 0
51
- d.puts "COMMANDS"
52
- d.indent(4) {
53
- d.table(:columns => 3, :newlines => 1) do |t|
54
- command_strings.each_pair do |command_name, values_array|
55
- t.row values_array[0], '-', command_outline(values_array)
56
- end
57
- end
58
- }
59
- end
17
+ name_help(current_command, d)
18
+ usage_help(current_command, d)
19
+ version_help(current_command, d)
20
+ options_help(options, d)
21
+ commands_help(commands, d)
60
22
  end
61
23
  end
62
24
 
63
-
64
25
  private
65
26
 
66
- def script_name_with_command
67
- result = []
68
- result << script_name
69
- result << current_command unless context.empty?
70
- result.join(" ")
27
+ def name_help(current_command, d)
28
+ d.puts "NAME"
29
+ d.indent(4) do
30
+ d.table(:columns => 3, :newlines => 1) do |t|
31
+ t.row current_command.script_name, '-', current_command.summary
32
+ end
33
+ d.put(setup.description_for(context), :newlines => 2) if setup.description_for(context)
34
+ end
71
35
  end
72
36
 
73
- def script_name
74
- File.basename($0)
37
+ def usage_help(current_command, d)
38
+ d.puts "USAGE"
39
+ d.indent(4) do
40
+ d.put current_command.usage, :newlines => 2
41
+ end
75
42
  end
76
43
 
77
- def current_command
78
- context.last || :global
44
+ def version_help(current_command, d)
45
+ if setup.version
46
+ d.puts "VERSION"
47
+ d.indent(4) {
48
+ d.put setup.version, :newlines => 2
49
+ }
50
+ end
79
51
  end
80
52
 
81
- def command_outline(command_data)
82
- result = command_data[1] || ''
83
- result = command_data[2] || '' if result.nil? || result.empty?
84
- result
53
+ def options_help(options, d)
54
+ if options.count > 0
55
+ d.puts "OPTIONS"
56
+ d.indent(4) {
57
+ d.table(:columns => 3, :newlines => 1) do |t|
58
+ options.each do |option|
59
+ t.row option.usage, '-', option.description
60
+ option_conflicts_help(option, t)
61
+ option_dependencies_help(option, t)
62
+ option_validations_help(option, t)
63
+ end
64
+ end
65
+ }
66
+ end
67
+ end
68
+
69
+ def option_conflicts_help(option, t)
70
+ if option.has_conflicts?
71
+ t.row '', '', "- #{option.conflicts}"
72
+ end
85
73
  end
86
74
 
87
- def current_command_summary
88
- setup.summary_for(context) || ''
75
+ def option_dependencies_help(option, t)
76
+ if option.has_dependencies?
77
+ t.row '', '', "- #{option.dependencies}"
78
+ end
79
+ end
80
+
81
+ def option_validations_help(option, t)
82
+ if option.has_validations?
83
+ t.row '', '', "- #{option.validations}"
84
+ end
89
85
  end
90
86
 
91
- def command_output_strings
92
- commands = {}
93
- setup.canonical_command_names_for(context).each do |command_name|
94
- command_description = setup.command_description_for(command_name, context) || ""
95
- command_summary = setup.command_summary_for(command_name, context) || ""
96
- command_aliases = setup.command_aliases_for(command_name, context)
97
- command_alias_string = command_aliases.join(", ") if command_aliases && command_aliases.size > 0
98
- command_string = (command_aliases && command_aliases.size > 0 ? "#{command_name}, #{command_alias_string}" : "#{command_name}" )
99
- command_name = command_name.to_s
100
- commands[command_name] = [command_string, command_summary, command_description]
87
+ def commands_help(commands, d)
88
+ if commands.count > 0
89
+ d.puts "COMMANDS"
90
+ d.indent(4) {
91
+ d.table(:columns => 3, :newlines => 1) do |t|
92
+ commands.each do |command|
93
+ t.row command.name_with_aliases, '-', command.outline
94
+ end
95
+ end
96
+ }
101
97
  end
102
- commands
103
98
  end
104
99
  end
105
100
  end
@@ -0,0 +1,17 @@
1
+ module Escort
2
+ module Formatter
3
+ class GlobalCommand < Command
4
+ def initialize(setup)
5
+ super(:global, setup, [])
6
+ end
7
+
8
+ def summary
9
+ @summary ||= setup.summary_for(context) || ""
10
+ end
11
+
12
+ def description
13
+ @description ||= setup.description_for(context) || ""
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,138 @@
1
+ module Escort
2
+ module Formatter
3
+ class Option
4
+ attr_reader :name, :details, :setup, :context
5
+
6
+ def initialize(name, details, setup, context)
7
+ @name = name.to_sym
8
+ @details = details
9
+ @setup = setup
10
+ @context = context
11
+ end
12
+
13
+ def usage
14
+ [long_string, short_string, type_string].select{|item| !item.empty?}.join(" ")
15
+ end
16
+
17
+ def description
18
+ [base_description_string, description_default_string].select{|item| !item.empty?}.join(" ")
19
+ end
20
+
21
+ def has_conflicts?
22
+ !conflicts_list.empty?
23
+ end
24
+
25
+ def conflicts
26
+ has_conflicts? ? "conflicts with: #{conflicts_list.map{|option| "--#{option}"}.join(', ')}" : ''
27
+ end
28
+
29
+ def has_dependencies?
30
+ !dependencies_list.empty?
31
+ end
32
+
33
+ def dependencies
34
+ has_dependencies? ? "depends on: #{format_dependency_list(dependencies_list).join(', ')}" : ''
35
+ end
36
+
37
+ def has_validations?
38
+ !validations_list.empty?
39
+ end
40
+
41
+ def validations
42
+ has_validations? ? "#{validation_messages.join("\n- ")}" : ''
43
+ end
44
+
45
+ private
46
+ def validation_messages
47
+ validations_list.map{|validation| validation[:desc]}
48
+ end
49
+
50
+ def validations_list
51
+ setup.validations_for(context)[name] || []
52
+ end
53
+
54
+ def format_dependency_list(dependency_list)
55
+ dependencies_list.map do |option|
56
+ case option
57
+ when Hash
58
+ option.inject([]){|acc, (key, value)| acc << "--#{key}=#{value}"}.join(', ')
59
+ else
60
+ "--#{option}"
61
+ end
62
+ end
63
+ end
64
+
65
+ def dependencies_list
66
+ setup.dependencies_for(context)[name] || []
67
+ end
68
+
69
+ def conflicts_list
70
+ setup.conflicting_options_for(context)[name] || []
71
+ end
72
+
73
+ def base_description_string
74
+ details[:desc] || details[:description] || ''
75
+ end
76
+
77
+ def description_default_string
78
+ if details[:default]
79
+ base_description_string =~ /\.$/ ? "(Default: #{default_string})" : "(default: #{default_string})"
80
+ else
81
+ ""
82
+ end
83
+ end
84
+
85
+ def default_string
86
+ case details[:default]
87
+ when $stdout; "<stdout>"
88
+ when $stdin; "<stdin>"
89
+ when $stderr; "<stderr>"
90
+ when Array
91
+ details[:default].join(", ")
92
+ else
93
+ details[:default].to_s
94
+ end
95
+ end
96
+
97
+ def short_string
98
+ details[:short] && details[:short] != :none ? "-#{details[:short]}" : ""
99
+ end
100
+
101
+ def long_string
102
+ if flag_with_default_true?
103
+ "#{base_long_string}, --no-#{details[:long]}"
104
+ else
105
+ base_long_string
106
+ end
107
+ end
108
+
109
+ def base_long_string
110
+ "--#{details[:long]}"
111
+ end
112
+
113
+ def type_string
114
+ case details[:type]
115
+ when :flag; ""
116
+ when :int; "<i>"
117
+ when :ints; "<i+>"
118
+ when :string; "<s>"
119
+ when :strings; "<s+>"
120
+ when :float; "<f>"
121
+ when :floats; "<f+>"
122
+ when :io; "<filename/uri>"
123
+ when :ios; "<filename/uri+>"
124
+ when :date; "<date>"
125
+ when :dates; "<date+>"
126
+ end
127
+ end
128
+
129
+ def flag_with_default_true?
130
+ flag? && details[:default]
131
+ end
132
+
133
+ def flag?
134
+ details[:type] == :flag
135
+ end
136
+ end
137
+ end
138
+ end
@@ -1,13 +1,27 @@
1
1
  module Escort
2
2
  module Formatter
3
3
  class Options
4
- attr_reader :setup, :context, :parser
4
+ include Enumerable
5
5
 
6
- def initialize(setup, context, parser)
6
+ attr_reader :parser, :setup, :context
7
+
8
+ def initialize(parser, setup, context)
9
+ @parser = parser
7
10
  @setup = setup
8
11
  @context = context
9
- @parser = parser
10
12
  end
13
+
14
+ def each(&block)
15
+ parser.specs.each do |option_name, details|
16
+ option = Option.new(option_name, details, setup, context)
17
+ block.call(option)
18
+ end
19
+ end
20
+
21
+ def count
22
+ parser.specs.keys.size
23
+ end
24
+ alias_method :size, :count
11
25
  end
12
26
  end
13
27
  end
@@ -0,0 +1,49 @@
1
+ require 'open3'
2
+
3
+ module Escort
4
+ module Formatter
5
+ class ShellCommandExecutor
6
+ attr_reader :command
7
+
8
+ def initialize(command)
9
+ @command = command
10
+ end
11
+
12
+ def execute_in_current_shell(success_callback = nil, error_callback = nil)
13
+ begin
14
+ result = `#{command}`
15
+ process_status = $?
16
+ raise Escort::InternalError.new("Shell command exited with a non-zero (#{process_status.exitstatus}) exit code") if process_status.exitstatus != 0
17
+ success_callback.call(command, result) if success_callback
18
+ rescue => e
19
+ error_callback.call(command, e) if error_callback
20
+ nil
21
+ end
22
+ end
23
+
24
+ #def execute_in_new_shell(success_callback = nil, error_callback = nil)
25
+ #stdin, stdout, stderr = nil, nil, nil
26
+ #begin
27
+ #stdin, stdout, stderr, thread = ensure_successful_exit do
28
+ #Open3.popen3(command)
29
+ #end
30
+ #success_callback.call(command, stdin, stdout, stderr) if success_callback
31
+ #rescue => e
32
+ #error_callback.call(command, e) if error_callback
33
+ #nil
34
+ #ensure
35
+ #[stdin, stdout, stderr].each {|io| io.close if io}
36
+ #end
37
+ #end
38
+
39
+ #private
40
+
41
+ #def ensure_successful_exit(&block)
42
+ #stdin, stdout, stderr, thread = block.call
43
+ #process_status = thread.value
44
+ #raise Escort::InternalError.new("Shell command exited with a non-zero (#{process_status.exitstatus}) exit code") if process_status.exitstatus != 0
45
+ #[stdin, stdout, stderr, thread]
46
+ #end
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,3 @@
1
- require 'curses'
2
-
3
1
  module Escort
4
2
  module Formatter
5
3
  class Terminal
@@ -7,14 +5,24 @@ module Escort
7
5
 
8
6
  class << self
9
7
  def width
10
- screen_size = self::DEFAULT_WIDTH
11
- Curses.init_screen
12
- begin
13
- screen_size = Curses.cols
14
- ensure
15
- Curses.close_screen
8
+ tput_width
9
+ end
10
+
11
+ private
12
+
13
+ def tput_width
14
+ ShellCommandExecutor.new('/usr/bin/env tput cols').execute_in_current_shell(tput_cols_command_success_callback, tput_cols_command_error_callback) || DEFAULT_WIDTH
15
+ end
16
+
17
+ def tput_cols_command_success_callback
18
+ lambda {|command, result| result.to_i}
19
+ end
20
+
21
+ def tput_cols_command_error_callback
22
+ lambda do |command, e|
23
+ error_logger.debug {e}
24
+ error_logger.info {"Unable to find terminal width via '#{command}', using default of #{DEFAULT_WIDTH}"}
16
25
  end
17
- screen_size
18
26
  end
19
27
  end
20
28
  end
@@ -1,3 +1,9 @@
1
+ #TODO rename to StreamOutputFormatter
2
+ #get rid of the display method, it doesn't really add anything
3
+ #the max_width should be max_line_width not terminal_columns, there should be no default max_width
4
+ #indent_count should be indent_width
5
+ #probably don't really need indent_char, we can assume it is a space
6
+ #this will only work well with ASCII chars only!!!
1
7
  module Escort
2
8
  module Formatter
3
9
  class TerminalFormatter
data/lib/escort/logger.rb CHANGED
@@ -41,20 +41,20 @@ module Escort
41
41
 
42
42
  def basic_error_formatter
43
43
  proc do |severity, datetime, progname, msg|
44
- "\"#{msg2str(msg)}\"\n"
44
+ "#{msg2str(msg)}\n"
45
45
  end
46
46
  end
47
47
 
48
48
  #"#{severity} [#{datetime.strftime("%d/%b/%Y %H:%M:%S")}] \"#{msg}\"\n"
49
49
  def advanced_error_formatter
50
50
  proc do |severity, datetime, progname, msg|
51
- sprintf("%-8s \"#{msg2str(msg, 10)}\"\n", severity)
51
+ sprintf("%-8s #{msg2str(msg, 10)}\n", severity)
52
52
  end
53
53
  end
54
54
 
55
55
  def output_formatter
56
56
  proc do |severity, datetime, progname, msg|
57
- "\"#{msg}\"\n"
57
+ "#{msg}\n"
58
58
  end
59
59
  end
60
60
 
@@ -64,7 +64,7 @@ module Escort
64
64
  msg
65
65
  when ::Exception
66
66
  "#{msg.message} (#{ msg.class })\n" <<
67
- (msg.backtrace || []).map{|line| sprintf("%#{backtrace_indent}s#{line}", " ")}.join("\n")
67
+ (msg.backtrace || []).map{|line| sprintf("%#{backtrace_indent}s#{line}", "")}.join("\n")
68
68
  else
69
69
  msg.inspect
70
70
  end