honeybadger 5.27.0 → 6.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +168 -0
  3. data/lib/honeybadger/agent.rb +108 -33
  4. data/lib/honeybadger/backend/base.rb +11 -11
  5. data/lib/honeybadger/backend/debug.rb +4 -4
  6. data/lib/honeybadger/backend/null.rb +2 -2
  7. data/lib/honeybadger/backend/server.rb +11 -11
  8. data/lib/honeybadger/backend/test.rb +2 -2
  9. data/lib/honeybadger/backend.rb +6 -6
  10. data/lib/honeybadger/backtrace.rb +27 -22
  11. data/lib/honeybadger/breadcrumbs/active_support.rb +10 -10
  12. data/lib/honeybadger/breadcrumbs/breadcrumb.rb +1 -2
  13. data/lib/honeybadger/breadcrumbs/collector.rb +4 -4
  14. data/lib/honeybadger/breadcrumbs/logging.rb +13 -14
  15. data/lib/honeybadger/breadcrumbs.rb +3 -3
  16. data/lib/honeybadger/cli/deploy.rb +7 -7
  17. data/lib/honeybadger/cli/exec.rb +41 -41
  18. data/lib/honeybadger/cli/helpers.rb +18 -18
  19. data/lib/honeybadger/cli/heroku.rb +36 -36
  20. data/lib/honeybadger/cli/install.rb +44 -44
  21. data/lib/honeybadger/cli/main.rb +107 -107
  22. data/lib/honeybadger/cli/notify.rb +13 -13
  23. data/lib/honeybadger/cli/test.rb +109 -94
  24. data/lib/honeybadger/cli.rb +3 -3
  25. data/lib/honeybadger/config/defaults.rb +252 -216
  26. data/lib/honeybadger/config/env.rb +5 -5
  27. data/lib/honeybadger/config/ruby.rb +19 -19
  28. data/lib/honeybadger/config/yaml.rb +12 -12
  29. data/lib/honeybadger/config.rb +116 -95
  30. data/lib/honeybadger/const.rb +4 -4
  31. data/lib/honeybadger/context_manager.rb +59 -11
  32. data/lib/honeybadger/conversions.rb +9 -6
  33. data/lib/honeybadger/counter.rb +4 -4
  34. data/lib/honeybadger/event.rb +4 -4
  35. data/lib/honeybadger/events_worker.rb +34 -33
  36. data/lib/honeybadger/gauge.rb +2 -2
  37. data/lib/honeybadger/histogram.rb +4 -4
  38. data/lib/honeybadger/init/hanami.rb +5 -5
  39. data/lib/honeybadger/init/rails.rb +14 -14
  40. data/lib/honeybadger/init/rake.rb +19 -21
  41. data/lib/honeybadger/init/ruby.rb +4 -4
  42. data/lib/honeybadger/init/sinatra.rb +11 -12
  43. data/lib/honeybadger/instrumentation.rb +26 -31
  44. data/lib/honeybadger/instrumentation_helper.rb +11 -12
  45. data/lib/honeybadger/karafka.rb +64 -65
  46. data/lib/honeybadger/logging.rb +22 -21
  47. data/lib/honeybadger/metric.rb +2 -2
  48. data/lib/honeybadger/metrics_worker.rb +12 -10
  49. data/lib/honeybadger/notice.rb +55 -58
  50. data/lib/honeybadger/notification_subscriber.rb +74 -51
  51. data/lib/honeybadger/plugin.rb +16 -18
  52. data/lib/honeybadger/plugins/active_agent.rb +38 -0
  53. data/lib/honeybadger/plugins/active_job.rb +11 -9
  54. data/lib/honeybadger/plugins/autotuner.rb +7 -7
  55. data/lib/honeybadger/plugins/breadcrumbs.rb +7 -7
  56. data/lib/honeybadger/plugins/delayed_job/plugin.rb +36 -37
  57. data/lib/honeybadger/plugins/delayed_job.rb +4 -4
  58. data/lib/honeybadger/plugins/faktory.rb +10 -10
  59. data/lib/honeybadger/plugins/flipper.rb +33 -0
  60. data/lib/honeybadger/plugins/karafka.rb +3 -3
  61. data/lib/honeybadger/plugins/lambda.rb +9 -11
  62. data/lib/honeybadger/plugins/local_variables.rb +4 -4
  63. data/lib/honeybadger/plugins/net_http.rb +12 -12
  64. data/lib/honeybadger/plugins/passenger.rb +4 -4
  65. data/lib/honeybadger/plugins/rails.rb +15 -9
  66. data/lib/honeybadger/plugins/resque.rb +7 -7
  67. data/lib/honeybadger/plugins/shoryuken.rb +6 -6
  68. data/lib/honeybadger/plugins/sidekiq.rb +79 -65
  69. data/lib/honeybadger/plugins/solid_queue.rb +8 -7
  70. data/lib/honeybadger/plugins/sucker_punch.rb +5 -5
  71. data/lib/honeybadger/plugins/system.rb +3 -3
  72. data/lib/honeybadger/plugins/thor.rb +5 -5
  73. data/lib/honeybadger/plugins/warden.rb +5 -8
  74. data/lib/honeybadger/rack/error_notifier.rb +14 -14
  75. data/lib/honeybadger/rack/user_feedback.rb +11 -12
  76. data/lib/honeybadger/rack/user_informer.rb +6 -6
  77. data/lib/honeybadger/registry.rb +2 -2
  78. data/lib/honeybadger/registry_execution.rb +1 -1
  79. data/lib/honeybadger/ruby.rb +2 -2
  80. data/lib/honeybadger/singleton.rb +49 -46
  81. data/lib/honeybadger/tasks.rb +3 -3
  82. data/lib/honeybadger/timer.rb +1 -1
  83. data/lib/honeybadger/util/http.rb +27 -27
  84. data/lib/honeybadger/util/request_hash.rb +11 -11
  85. data/lib/honeybadger/util/request_payload.rb +2 -2
  86. data/lib/honeybadger/util/revision.rb +14 -6
  87. data/lib/honeybadger/util/sanitizer.rb +29 -23
  88. data/lib/honeybadger/util/stats.rb +6 -3
  89. data/lib/honeybadger/version.rb +1 -1
  90. data/lib/honeybadger/worker.rb +31 -29
  91. data/lib/honeybadger.rb +5 -5
  92. data/lib/puma/plugin/honeybadger.rb +14 -10
  93. metadata +10 -6
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require "json"
2
2
 
3
3
  module Honeybadger
4
4
  # @api private
@@ -8,7 +8,7 @@ module Honeybadger
8
8
  class Line
9
9
  # Backtrace line regexp (optionally allowing leading X: for windows support).
10
10
  # Capture quoted strings either with leading backtick (pre Ruby 3.4) or single quote.
11
- INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in (?:`|')([^']+)')?$}.freeze
11
+ INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in (?:`|')([^']+)')?$}
12
12
 
13
13
  # The file portion of the line (such as app/models/user.rb).
14
14
  attr_reader :file
@@ -45,21 +45,19 @@ module Honeybadger
45
45
  file, number, method = match[1], match[2], match[3]
46
46
  filtered_args = [fmatch[1], fmatch[2], fmatch[3]]
47
47
  new(file, number, method, *filtered_args, opts.fetch(:source_radius, 2))
48
- else
49
- nil
50
48
  end
51
49
  end
52
50
 
53
51
  def initialize(file, number, method, filtered_file = file,
54
- filtered_number = number, filtered_method = method,
55
- source_radius = 2)
56
- self.filtered_file = filtered_file
52
+ filtered_number = number, filtered_method = method,
53
+ source_radius = 2)
54
+ self.filtered_file = filtered_file
57
55
  self.filtered_number = filtered_number
58
56
  self.filtered_method = filtered_method
59
- self.file = file
60
- self.number = number
61
- self.method = method
62
- self.source_radius = source_radius
57
+ self.file = file
58
+ self.number = number
59
+ self.method = method
60
+ self.source_radius = source_radius
63
61
  end
64
62
 
65
63
  # Reconstructs the line in a readable fashion.
@@ -72,7 +70,7 @@ module Honeybadger
72
70
  end
73
71
 
74
72
  def inspect
75
- "<Line:#{to_s}>"
73
+ "<Line:#{self}>"
76
74
  end
77
75
 
78
76
  # Determines if this line is part of the application trace or not.
@@ -102,8 +100,11 @@ module Honeybadger
102
100
 
103
101
  l = 0
104
102
  File.open(file) do |f|
105
- start.times { f.gets ; l += 1 }
106
- return Hash[duration.times.map { (line = f.gets) ? [(l += 1), line] : nil }.compact]
103
+ start.times {
104
+ f.gets
105
+ l += 1
106
+ }
107
+ return duration.times.map { (line = f.gets) ? [(l += 1), line] : nil }.compact.to_h
107
108
  end
108
109
  else
109
110
  {}
@@ -121,7 +122,7 @@ module Honeybadger
121
122
  Line.parse(unparsed_line.to_s, opts)
122
123
  end.compact
123
124
 
124
- instance = new(lines)
125
+ new(lines)
125
126
  end
126
127
 
127
128
  def initialize(lines)
@@ -133,9 +134,9 @@ module Honeybadger
133
134
  #
134
135
  # Returns array containing backtrace lines.
135
136
  def to_ary
136
- lines.take(1000).map { |l| { :number => l.filtered_number, :file => l.filtered_file, :method => l.filtered_method, :source => l.source } }
137
+ lines.take(1000).map { |l| {number: l.filtered_number, file: l.filtered_file, method: l.filtered_method, source: l.source} }
137
138
  end
138
- alias :to_a :to_ary
139
+ alias_method :to_a, :to_ary
139
140
 
140
141
  # JSON support.
141
142
  #
@@ -171,11 +172,15 @@ module Honeybadger
171
172
 
172
173
  attr_writer :lines, :application_lines
173
174
 
174
- def self.split_multiline_backtrace(backtrace)
175
- if backtrace.size == 1
176
- backtrace.first.to_s.split(/\n\s*/)
177
- else
178
- backtrace
175
+ class << self
176
+ private
177
+
178
+ def split_multiline_backtrace(backtrace)
179
+ if backtrace.size == 1
180
+ backtrace.first.to_s.split(/\n\s*/)
181
+ else
182
+ backtrace
183
+ end
179
184
  end
180
185
  end
181
186
  end
@@ -1,4 +1,4 @@
1
- require 'honeybadger/util/sql'
1
+ require "honeybadger/util/sql"
2
2
 
3
3
  module Honeybadger
4
4
  module Breadcrumbs
@@ -10,7 +10,7 @@ module Honeybadger
10
10
  "sql.active_record" => {
11
11
  message: lambda do |data|
12
12
  # Disregard empty string names
13
- name = data[:name] if data[:name] && !data[:name].strip.empty?
13
+ name = data[:name] if data[:name] && !data[:name].to_s.strip.empty?
14
14
 
15
15
  ["Active Record", name].compact.join(" - ")
16
16
  end,
@@ -19,7 +19,7 @@ module Honeybadger
19
19
  transform: lambda do |data|
20
20
  if data[:sql]
21
21
  connection = data.delete(:connection)
22
- adapter = (connection && connection.adapter_name.downcase) || active_record_connection_db_config[:adapter]
22
+ adapter = connection&.adapter_name&.downcase || active_record_connection_db_config[:adapter]
23
23
  data[:sql] = Util::SQL.obfuscate(data[:sql], adapter)
24
24
  end
25
25
  data
@@ -49,7 +49,7 @@ module Honeybadger
49
49
  "perform_start.active_job" => {
50
50
  message: "Active Job Perform Start",
51
51
  select_keys: [],
52
- category: "job",
52
+ category: "job"
53
53
  },
54
54
 
55
55
  # ActiveSupport Actions
@@ -67,32 +67,32 @@ module Honeybadger
67
67
  #
68
68
  "halted_callback.action_controller" => {
69
69
  message: "Action Controller Callback Halted",
70
- category: "request",
70
+ category: "request"
71
71
  },
72
72
  "process_action.action_controller" => {
73
73
  message: "Action Controller Action Process",
74
74
  select_keys: [:controller, :action, :format, :method, :path, :status, :view_runtime, :db_runtime],
75
- category: "request",
75
+ category: "request"
76
76
  },
77
77
  "start_processing.action_controller" => {
78
78
  message: "Action Controller Start Process",
79
79
  select_keys: [:controller, :action, :format, :method, :path],
80
- category: "request",
80
+ category: "request"
81
81
  },
82
82
  "redirect_to.action_controller" => {
83
83
  message: "Action Controller Redirect",
84
- category: "request",
84
+ category: "request"
85
85
  },
86
86
 
87
87
  # View Actions
88
88
  #
89
89
  "render_template.action_view" => {
90
90
  message: "Action View Template Render",
91
- category: "render",
91
+ category: "render"
92
92
  },
93
93
  "render_partial.action_view" => {
94
94
  message: "Action View Partial Render",
95
- category: "render",
95
+ category: "render"
96
96
  },
97
97
 
98
98
  # Mailer actions
@@ -1,4 +1,4 @@
1
- require 'time'
1
+ require "time"
2
2
 
3
3
  module Honeybadger
4
4
  module Breadcrumbs
@@ -32,7 +32,6 @@ module Honeybadger
32
32
  to_h <=> other.to_h
33
33
  end
34
34
 
35
-
36
35
  # Is the Breadcrumb active or not. Inactive Breadcrumbs not be included
37
36
  # with any outgoing payloads.
38
37
  #
@@ -1,4 +1,4 @@
1
- require 'forwardable'
1
+ require "forwardable"
2
2
 
3
3
  module Honeybadger
4
4
  module Breadcrumbs
@@ -35,7 +35,7 @@ module Honeybadger
35
35
  #
36
36
  # @return [self] Filtered breadcrumbs
37
37
  def add!(breadcrumb)
38
- return unless @config[:'breadcrumbs.enabled']
38
+ return unless @config[:"breadcrumbs.enabled"]
39
39
  @buffer.add!(breadcrumb)
40
40
 
41
41
  self
@@ -48,7 +48,7 @@ module Honeybadger
48
48
  # block returns a falsy value
49
49
  #
50
50
  def drop_previous_breadcrumb_if
51
- @buffer.drop if (previous && block_given? && yield(previous))
51
+ @buffer.drop if previous && block_given? && yield(previous)
52
52
  end
53
53
 
54
54
  # All active breadcrumbs you want to remove a breadcrumb from the trail,
@@ -61,7 +61,7 @@ module Honeybadger
61
61
 
62
62
  def to_h
63
63
  {
64
- enabled: @config[:'breadcrumbs.enabled'],
64
+ enabled: @config[:"breadcrumbs.enabled"],
65
65
  trail: trail.map(&:to_h)
66
66
  }
67
67
  end
@@ -1,3 +1,5 @@
1
+ require "honeybadger/util/sanitizer"
2
+
1
3
  module Honeybadger
2
4
  module Breadcrumbs
3
5
  # @api private
@@ -7,10 +9,10 @@ module Honeybadger
7
9
  org_severity, org_message, org_progname = severity, message, progname
8
10
  if defined?(Dry::Logger::Entry) && progname.is_a?(Dry::Logger::Entry) # Hanami uses dry-logger
9
11
  message, progname = progname.message || progname.exception, progname.progname
10
- else
11
- message, progname = [progname, nil] if message.nil?
12
+ elsif message.nil?
13
+ message, progname = [progname, nil]
12
14
  end
13
- message = message && message.to_s.strip
15
+ message &&= Util::Sanitizer.sanitize(message.to_s)&.strip
14
16
  unless should_ignore_log?(message, progname)
15
17
  Honeybadger.add_breadcrumb(message, category: :log, metadata: {
16
18
  severity: format_severity(severity),
@@ -25,9 +27,9 @@ module Honeybadger
25
27
 
26
28
  def should_ignore_log?(message, progname)
27
29
  message.nil? ||
28
- message == "" ||
29
- Thread.current[:__hb_within_log_subscriber] ||
30
- progname == "honeybadger"
30
+ message == "" ||
31
+ Thread.current[:__hb_within_log_subscriber] ||
32
+ progname == "honeybadger"
31
33
  end
32
34
  end
33
35
 
@@ -39,17 +41,14 @@ module Honeybadger
39
41
  # class that provides LogSubscriber events, we want to filter out those
40
42
  # logs as they just become noise.
41
43
  module LogSubscriberInjector
42
- %w(info debug warn error fatal unknown).each do |level|
44
+ %w[info debug warn error fatal unknown].each do |level|
43
45
  define_method(level) do |*args, &block|
44
- begin
45
- Thread.current[:__hb_within_log_subscriber] = true
46
- super(*args, &block)
47
- ensure
48
- Thread.current[:__hb_within_log_subscriber] = false
49
- end
46
+ Thread.current[:__hb_within_log_subscriber] = true
47
+ super(*args, &block)
48
+ ensure
49
+ Thread.current[:__hb_within_log_subscriber] = false
50
50
  end
51
51
  end
52
52
  end
53
53
  end
54
54
  end
55
-
@@ -1,6 +1,6 @@
1
- require 'honeybadger/breadcrumbs/ring_buffer'
2
- require 'honeybadger/breadcrumbs/breadcrumb'
3
- require 'honeybadger/breadcrumbs/collector'
1
+ require "honeybadger/breadcrumbs/ring_buffer"
2
+ require "honeybadger/breadcrumbs/breadcrumb"
3
+ require "honeybadger/breadcrumbs/collector"
4
4
 
5
5
  module Honeybadger
6
6
  module Breadcrumbs
@@ -1,7 +1,7 @@
1
- require 'forwardable'
2
- require 'honeybadger/cli/main'
3
- require 'honeybadger/cli/helpers'
4
- require 'honeybadger/util/http'
1
+ require "forwardable"
2
+ require "honeybadger/cli/main"
3
+ require "honeybadger/cli/helpers"
4
+ require "honeybadger/util/http"
5
5
 
6
6
  module Honeybadger
7
7
  module CLI
@@ -19,9 +19,9 @@ module Honeybadger
19
19
  def run
20
20
  payload = {
21
21
  environment: config.get(:env),
22
- revision: options['revision'],
23
- repository: options['repository'],
24
- local_username: options['user']
22
+ revision: options["revision"],
23
+ repository: options["repository"],
24
+ local_username: options["user"]
25
25
  }
26
26
 
27
27
  response = config.backend.notify(:deploys, payload)
@@ -1,12 +1,12 @@
1
- require 'erb'
2
- require 'forwardable'
3
- require 'honeybadger/cli/main'
4
- require 'honeybadger/cli/helpers'
5
- require 'honeybadger/util/http'
6
- require 'honeybadger/util/stats'
7
- require 'open3'
8
- require 'ostruct'
9
- require 'thor/shell'
1
+ require "erb"
2
+ require "forwardable"
3
+ require "honeybadger/cli/main"
4
+ require "honeybadger/cli/helpers"
5
+ require "honeybadger/util/http"
6
+ require "honeybadger/util/stats"
7
+ require "open3"
8
+ require "ostruct"
9
+ require "thor/shell"
10
10
 
11
11
  module Honeybadger
12
12
  module CLI
@@ -14,34 +14,34 @@ module Honeybadger
14
14
  extend Forwardable
15
15
  include Helpers::BackendCmd
16
16
 
17
- FAILED_TEMPLATE = <<-MSG
18
- Honeybadger detected failure or error output for the command:
19
- `<%= args.join(' ') %>`
20
-
21
- PROCESS ID: <%= pid %>
22
-
23
- RESULT CODE: <%= code %>
24
-
25
- ERROR OUTPUT:
26
- <%= stderr %>
27
-
28
- STANDARD OUTPUT:
29
- <%= stdout %>
30
- MSG
31
-
32
- NO_EXEC_TEMPLATE = <<-MSG
33
- Honeybadger failed to execute the following command:
34
- `<%= args.join(' ') %>`
35
-
36
- The command was not executable. Try adjusting permissions on the file.
37
- MSG
38
-
39
- NOT_FOUND_TEMPLATE = <<-MSG
40
- Honeybadger failed to execute the following command:
41
- `<%= args.join(' ') %>`
42
-
43
- The command was not found. Make sure it exists in your PATH.
44
- MSG
17
+ FAILED_TEMPLATE = <<~MSG
18
+ Honeybadger detected failure or error output for the command:
19
+ `<%= args.join(' ') %>`
20
+
21
+ PROCESS ID: <%= pid %>
22
+
23
+ RESULT CODE: <%= code %>
24
+
25
+ ERROR OUTPUT:
26
+ <%= stderr %>
27
+
28
+ STANDARD OUTPUT:
29
+ <%= stdout %>
30
+ MSG
31
+
32
+ NO_EXEC_TEMPLATE = <<~MSG
33
+ Honeybadger failed to execute the following command:
34
+ `<%= args.join(' ') %>`
35
+
36
+ The command was not executable. Try adjusting permissions on the file.
37
+ MSG
38
+
39
+ NOT_FOUND_TEMPLATE = <<~MSG
40
+ Honeybadger failed to execute the following command:
41
+ `<%= args.join(' ') %>`
42
+
43
+ The command was not found. Make sure it exists in your PATH.
44
+ MSG
45
45
 
46
46
  def initialize(options, args, config)
47
47
  @options = options
@@ -59,17 +59,17 @@ MSG
59
59
  api_key: config.get(:api_key),
60
60
  notifier: NOTIFIER,
61
61
  error: {
62
- class: 'honeybadger exec error',
62
+ class: "honeybadger exec error",
63
63
  message: result.msg
64
64
  },
65
65
  request: {
66
66
  component: executable,
67
67
  context: {
68
- command: args.join(' '),
68
+ command: args.join(" "),
69
69
  code: result.code,
70
70
  pid: result.pid,
71
71
  pwd: Dir.pwd,
72
- path: ENV['PATH']
72
+ path: ENV["PATH"]
73
73
  }
74
74
  },
75
75
  server: {
@@ -112,7 +112,7 @@ MSG
112
112
  end
113
113
 
114
114
  def exec_cmd
115
- stdout, stderr, status = Open3.capture3(args.join(' '))
115
+ stdout, stderr, status = Open3.capture3(args.join(" "))
116
116
 
117
117
  success = status.success? && stderr =~ BLANK
118
118
  pid = status.pid
@@ -3,24 +3,24 @@ module Honeybadger
3
3
  module Helpers
4
4
  module BackendCmd
5
5
  def error_message(response)
6
- host = config.get(:'connection.host')
7
- <<-MSG
8
- !! --- Honeybadger request failed --------------------------------------------- !!
9
-
10
- We encountered an error when contacting the server:
11
-
12
- #{response.error_message}
13
-
14
- To fix this issue, please try the following:
15
-
16
- - Make sure the gem is configured properly.
17
- - Retry executing this command a few times.
18
- - Make sure you can connect to #{host} (`curl https://#{host}/v1/notices`).
19
- - Email support@honeybadger.io for help. Include as much debug info as you
20
- can for a faster resolution!
21
-
22
- !! --- End -------------------------------------------------------------------- !!
23
- MSG
6
+ host = config.get(:"connection.host")
7
+ <<~MSG
8
+ !! --- Honeybadger request failed --------------------------------------------- !!
9
+
10
+ We encountered an error when contacting the server:
11
+
12
+ #{response.error_message}
13
+
14
+ To fix this issue, please try the following:
15
+
16
+ - Make sure the gem is configured properly.
17
+ - Retry executing this command a few times.
18
+ - Make sure you can connect to #{host} (`curl https://#{host}/v1/notices`).
19
+ - Email support@honeybadger.io for help. Include as much debug info as you
20
+ can for a faster resolution!
21
+
22
+ !! --- End -------------------------------------------------------------------- !!
23
+ MSG
24
24
  end
25
25
  end
26
26
  end
@@ -1,50 +1,50 @@
1
1
  module Honeybadger
2
2
  module CLI
3
3
  class Heroku < Thor
4
- class_option :app, aliases: :'-a', type: :string, default: nil, desc: 'Specify optional Heroku APP'
4
+ class_option :app, aliases: :"-a", type: :string, default: nil, desc: "Specify optional Heroku APP"
5
5
 
6
- desc 'install_deploy_notification', 'Install Heroku deploy notifications addon'
7
- option :api_key, aliases: :'-k', type: :string, desc: 'Api key of your Honeybadger application'
8
- option :environment, aliases: :'-e', type: :string, desc: 'Environment of your Heroku application (i.e. "production", "staging")'
6
+ desc "install_deploy_notification", "Install Heroku deploy notifications addon"
7
+ option :api_key, aliases: :"-k", type: :string, desc: "Api key of your Honeybadger application"
8
+ option :environment, aliases: :"-e", type: :string, desc: 'Environment of your Heroku application (i.e. "production", "staging")'
9
9
  def install_deploy_notification
10
- app = options.has_key?('app') ? options['app'] : detect_heroku_app(false)
11
- rails_env = options['environment'] || heroku_var('RAILS_ENV', app)
12
- api_key = options['api_key'] || heroku_var('HONEYBADGER_API_KEY', app)
10
+ app = options.has_key?("app") ? options["app"] : detect_heroku_app(false)
11
+ rails_env = options["environment"] || heroku_var("RAILS_ENV", app)
12
+ api_key = options["api_key"] || heroku_var("HONEYBADGER_API_KEY", app)
13
13
 
14
- unless api_key =~ /\S/
14
+ unless /\S/.match?(api_key)
15
15
  say("Unable to detect your API key from Heroku.", :red)
16
- say('Have you configured multiple Heroku apps? Try using --app APP', :red) unless app
16
+ say("Have you configured multiple Heroku apps? Try using --app APP", :red) unless app
17
17
  exit(1)
18
18
  end
19
19
 
20
- unless rails_env =~ /\S/
20
+ unless /\S/.match?(rails_env)
21
21
  say("Unable to detect your environment from Heroku. Use --environment ENVIRONMENT.", :red)
22
- say('Have you configured multiple Heroku apps? Try using --app APP', :red) unless app
22
+ say("Have you configured multiple Heroku apps? Try using --app APP", :red) unless app
23
23
  exit(1)
24
24
  end
25
25
 
26
- cmd = %Q(heroku webhooks:add -i api:release -l notify -u "https://api.honeybadger.io/v1/deploys/heroku?environment=#{rails_env}&api_key=#{api_key}"#{app ? " --app #{app}" : ''})
26
+ cmd = %(heroku webhooks:add -i api:release -l notify -u "https://api.honeybadger.io/v1/deploys/heroku?environment=#{rails_env}&api_key=#{api_key}"#{app ? " --app #{app}" : ""})
27
27
 
28
28
  say("Running: `#{cmd}`")
29
29
  say(run(cmd))
30
30
  end
31
31
 
32
- desc 'install API_KEY', 'Install Honeybadger on Heroku using API_KEY'
32
+ desc "install API_KEY", "Install Honeybadger on Heroku using API_KEY"
33
33
  def install(api_key)
34
34
  say("Installing Honeybadger #{VERSION} for Heroku")
35
35
 
36
36
  app = options[:app] || detect_heroku_app(false)
37
37
  say("Adding config HONEYBADGER_API_KEY=#{api_key} to Heroku.", :magenta)
38
- unless write_heroku_env({'HONEYBADGER_API_KEY' => api_key}, app)
39
- say('Unable to update heroku config. You may need to specify an app name with --app APP', :red)
38
+ unless write_heroku_env({"HONEYBADGER_API_KEY" => api_key}, app)
39
+ say("Unable to update heroku config. You may need to specify an app name with --app APP", :red)
40
40
  exit(1)
41
41
  end
42
42
 
43
- if env = heroku_var('RAILS_ENV', app, heroku_var('RACK_ENV', app))
44
- say('Installing deploy notification addon', :magenta)
45
- invoke :install_deploy_notification, [], { app: app, api_key: api_key, environment: env }
43
+ if (env = heroku_var("RAILS_ENV", app, heroku_var("RACK_ENV", app)))
44
+ say("Installing deploy notification addon", :magenta)
45
+ invoke :install_deploy_notification, [], {app: app, api_key: api_key, environment: env}
46
46
  else
47
- say('Skipping deploy notification installation: we were unable to determine the environment name from your Heroku app.', :yellow)
47
+ say("Skipping deploy notification installation: we were unable to determine the environment name from your Heroku app.", :yellow)
48
48
  say("To install manually, try `honeybadger heroku install_deploy_notification#{app ? " -a #{app}" : ""} -k #{api_key} --environment ENVIRONMENT`", :yellow)
49
49
  end
50
50
 
@@ -60,14 +60,14 @@ module Honeybadger
60
60
  #
61
61
  # Returns the String app name if detected, otherwise nil.
62
62
  def detect_heroku_app(prompt_on_default = true)
63
- apps, git_config = {}, File.join(Dir.pwd, '.git', 'config')
63
+ apps, git_config = {}, File.join(Dir.pwd, ".git", "config")
64
64
  if File.exist?(git_config)
65
- require 'inifile'
65
+ require "inifile"
66
66
  ini = IniFile.load(git_config)
67
67
  ini.each_section do |section|
68
- if match = section.match(/remote \"(?<remote>.+)\"/)
69
- url = ini[section]['url']
70
- if url_match = url.match(/heroku\.com:(?<app>.+)\.git$/)
68
+ if (match = section.match(/remote "(?<remote>.+)"/))
69
+ url = ini[section]["url"]
70
+ if (url_match = url.match(/heroku\.com:(?<app>.+)\.git$/))
71
71
  apps[match[:remote]] = url_match[:app]
72
72
  end
73
73
  end
@@ -78,16 +78,16 @@ module Honeybadger
78
78
  apps.values.first
79
79
  else
80
80
  say "We detected a Heroku app named #{apps.values.first}. Do you want to load the config? (y/yes or n/no)"
81
- if STDIN.gets.chomp =~ /(y|yes)/i
81
+ if /(y|yes)/i.match?($stdin.gets.chomp)
82
82
  apps.values.first
83
83
  end
84
84
  end
85
85
  elsif apps.size > 1
86
86
  say "We detected the following Heroku apps:"
87
- apps.each_with_index {|a,i| say "\s\s#{i+1}. #{a[1]}" }
88
- say "\s\s#{apps.size+1}. Use default"
89
- say "Please select an option (1-#{apps.size+1}):"
90
- apps.values[STDIN.gets.chomp.to_i-1]
87
+ apps.each_with_index { |a, i| say "\s\s#{i + 1}. #{a[1]}" }
88
+ say "\s\s#{apps.size + 1}. Use default"
89
+ say "Please select an option (1-#{apps.size + 1}):"
90
+ apps.values[$stdin.gets.chomp.to_i - 1]
91
91
  end
92
92
  end
93
93
  end
@@ -97,29 +97,29 @@ module Honeybadger
97
97
  end
98
98
 
99
99
  def heroku_var(var, app_name, default = nil)
100
- app = app_name ? "--app #{app_name}" : ''
100
+ app = app_name ? "--app #{app_name}" : ""
101
101
  result = run("heroku config:get #{var} #{app} 2> /dev/null").strip
102
- result.split.find(lambda { default }) {|x| x =~ /\S/ }
102
+ result.split.find(lambda { default }) { |x| x =~ /\S/ }
103
103
  end
104
104
 
105
105
  def read_heroku_env(app = nil)
106
- cmd = ['heroku config']
106
+ cmd = ["heroku config"]
107
107
  cmd << "--app #{app}" if app
108
108
  output = run(cmd.join("\s"))
109
109
  return false unless $?.to_i == 0
110
- Hash[output.scan(/(HONEYBADGER_[^:]+):\s*(\S.*)\s*$/)]
110
+ output.scan(/(HONEYBADGER_[^:]+):\s*(\S.*)\s*$/).to_h
111
111
  end
112
112
 
113
113
  def set_env_from_heroku(app = nil)
114
- return false unless env = read_heroku_env(app)
115
- env.each_pair do |k,v|
114
+ return false unless (env = read_heroku_env(app))
115
+ env.each_pair do |k, v|
116
116
  ENV[k] ||= v
117
117
  end
118
118
  end
119
119
 
120
120
  def write_heroku_env(env, app = nil)
121
121
  cmd = ["heroku config:set"]
122
- Hash(env).each_pair {|k,v| cmd << "#{k}=#{v}" }
122
+ Hash(env).each_pair { |k, v| cmd << "#{k}=#{v}" }
123
123
  cmd << "--app #{app}" if app
124
124
  run(cmd.join("\s"))
125
125
  $?.to_i == 0