honeybadger 2.0.0.beta.7 → 2.0.0.beta.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea4729431078cbb1e542a22bbb1ac422a038be32
4
- data.tar.gz: 7da4b010726bd765840424ad160a8235e04ad5b8
3
+ metadata.gz: 1a57bb4b188eb1c866df596b60e56288022e2675
4
+ data.tar.gz: 4c7ab93efe775debf27db90834f8bb7b62254b19
5
5
  SHA512:
6
- metadata.gz: 685b29b9328d62dda5c9b5bfda43968601d9f6f7861060c2ad8531c9afcb650e386e1bcf82785ff37a630957b21eeebe8d07ac8b80d406d9d391e52c9b672d3b
7
- data.tar.gz: 6c503a35df7698efa690e1c8552c8f2c6b829ccdeeca7263ae20ed3b0f4eb3afd20f8fbc4375907fb49587f51c75905c3517b2b8b3b437c8d2acfa20c658dfe9
6
+ metadata.gz: abbaad38758b52e9924165df1165a353ac9230ee376521aae49842395ae15555f6c59cf1e501bba9ac556d349bfaf8ea515fe57104c95f225f63b8ad92b9ee1b
7
+ data.tar.gz: 409202d020dd45634e5b53855e2cda92a28c73dd1f3c7daf19fdd463918daa2dcc58beb93e0100cc21da34dc7ee94f4846f57fe1817fd2a200381ccf86c18554
data/lib/honeybadger.rb CHANGED
@@ -205,6 +205,11 @@ module Honeybadger
205
205
  def flush(&block)
206
206
  Agent.flush(&block)
207
207
  end
208
+
209
+ def configure(*args)
210
+ warn('UPGRADE WARNING: Honeybadger.configure was removed in v2.0 and has no effect. Please upgrade: https://www.honeybadger.io/s/gem-upgrade')
211
+ nil
212
+ end
208
213
  end
209
214
 
210
215
  if defined?(::Rails::Railtie)
@@ -1,381 +1,15 @@
1
1
  $:.unshift(File.expand_path('../../../vendor/thor/lib', __FILE__))
2
2
 
3
3
  require 'thor'
4
+
4
5
  require 'honeybadger'
5
- require 'stringio'
6
- require 'logger'
6
+ require 'honeybadger/cli/heroku'
7
+ require 'honeybadger/cli/main'
7
8
 
8
9
  module Honeybadger
9
- class CLI < Thor
10
- class HoneybadgerTestingException < RuntimeError; end
11
-
12
- NOT_BLANK = Regexp.new('\S').freeze
13
-
14
- class_option :platform, aliases: :'-p', type: :string, default: nil, desc: 'Specify optional PLATFORM (e.g. "heroku")'
15
- class_option :app, aliases: :'-a', type: :string, default: nil, desc: 'Specify optional APP with PLATFORM'
16
-
17
- desc 'deploy', 'Notify Honeybadger of deployment'
18
- option :environment, aliases: [:'-e', :'--env'], type: :string, desc: 'Environment of the deploy (i.e. "production", "staging")'
19
- option :revision, aliases: [:'-r', :'--rev', :'--sha'], type: :string, desc: 'The revision/sha that is being deployed'
20
- option :repository, aliases: :'--repo', type: :string, desc: 'The address of your repository'
21
- option :local_username, aliases: [:'--user', :'-u'], type: :string, default: ENV['USER'] || ENV['USERNAME'], desc: 'The local user who is deploying'
22
- option :api_key, aliases: [:'-k', :'--key'], type: :string, desc: 'Api key of your Honeybadger application'
23
- def deploy
24
- load_rails(verbose: true)
25
- exit(1) unless !options[:platform] || load_platform(options[:platform], options[:app])
26
-
27
- payload = Hash[[:environment, :revision, :repository, :local_username].map {|k| [k, options[k]] }]
28
-
29
- say('Loading configuration')
30
- config = Config.new(rails_framework_opts)
31
- config.update(api_key: options[:api_key]) if options[:api_key] =~ NOT_BLANK
32
-
33
- unless (payload[:environment] ||= config[:env]) =~ NOT_BLANK
34
- say('Unable to determine environment. (see: `honeybadger help deploy`)', :red)
35
- exit(1)
36
- end
37
-
38
- unless config.valid?
39
- say("Invalid configuration: #{config.inspect}", :red)
40
- exit(1)
41
- end
42
-
43
- response = config.backend.notify(:deploys, payload)
44
- if response.success?
45
- say("Deploy notification for #{payload[:environment]} complete.", :green)
46
- else
47
- say("Deploy notification failed: #{response.code}", :red)
48
- end
49
- rescue => e
50
- say("An error occurred during deploy notification: #{e}\n\t#{e.backtrace.join("\n\t")}", :red)
51
- exit(1)
52
- end
53
-
54
- desc 'config', 'List configuration options'
55
- option :default, aliases: :'-d', type: :boolean, default: true, desc: 'Output default options'
56
- def config
57
- exit(1) unless !options[:platform] || load_platform(options[:platform], options[:app])
58
- load_rails
59
- config = Config.new(rails_framework_opts)
60
- output_config(config.to_hash(options[:default]))
61
- end
62
-
63
- desc 'debug', 'Output debug information'
64
- option :test, aliases: :'-t', type: :boolean, default: false, desc: 'Send a test error'
65
- option :file, aliases: :'-f', type: :string, default: nil, desc: 'Write the output to FILE.'
66
- def debug
67
- if options[:file]
68
- out = StringIO.new
69
- $stdout = out
70
-
71
- flush = Proc.new do
72
- $stdout = STDOUT
73
- File.open(options[:file], 'w+') do |f|
74
- out.rewind
75
- out.each_line {|l| f.write(l) }
76
- end
77
-
78
- say("Output written to #{options[:file]}", :green)
79
- end
80
-
81
- Agent.at_exit(&flush)
82
-
83
- at_exit do
84
- # If the agent couldn't be started, the callback should happen here
85
- # instead.
86
- flush.() unless Agent.running?
87
- end
88
- end
89
-
90
- exit(1) unless !options[:platform] || load_platform(options[:platform], options[:app])
91
- say("\n") if options[:platform] # Print a blank line if we just logged the platform.
92
-
93
- say("Detecting framework\n\n", :bold)
94
- load_rails(verbose: true)
95
-
96
- ENV['HONEYBADGER_LOGGING_LEVEL'] = '0'
97
- ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
98
- ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
99
- ENV['HONEYBADGER_DEBUG'] = 'true'
100
- ENV['HONEYBADGER_REPORT_DATA'] = 'true'
101
-
102
- config = Config.new(rails_framework_opts)
103
- say("\nConfiguration\n\n", :bold)
104
- output_config(config.to_hash)
105
-
106
- say("\nStarting Honeybadger\n\n", :bold)
107
- Honeybadger.start(config) unless load_rails_env(verbose: true)
108
-
109
- if options[:test]
110
- say("\nSending test notice\n\n", :bold)
111
- send_test
112
- end
113
-
114
- say("\nRunning at exit hooks\n\n", :bold)
115
- end
116
-
117
- desc 'install API_KEY', 'Install Honeybadger into the current directory using API_KEY'
118
- option :test, aliases: :'-t', type: :boolean, default: nil, desc: 'Send a test error'
119
- def install(api_key)
120
- say("Installing Honeybadger #{VERSION}")
121
-
122
- exit(1) unless !options[:platform] || load_platform(options[:platform], options[:app])
123
-
124
- load_rails(verbose: true)
125
-
126
- ENV['HONEYBADGER_LOGGING_LEVEL'] = '2'
127
- ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
128
- ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
129
- ENV['HONEYBADGER_REPORT_DATA'] = 'true'
130
-
131
- config = Config.new(rails_framework_opts)
132
- config[:api_key] = api_key
133
-
134
- if options[:platform]
135
- if options[:platform] == 'heroku'
136
- say("Adding config HONEYBADGER_API_KEY=#{api_key} to heroku.", :magenta)
137
- unless write_heroku_env({'HONEYBADGER_API_KEY' => api_key}, options[:app])
138
- say('Unable to update heroku config. Do you need to specify an app name?', :red)
139
- return
140
- end
141
- end
142
- elsif (path = config.config_path).exist?
143
- say("You're already on Honeybadger, so you're all set.", :yellow)
144
- skip_test = true if options[:test].nil? # Only if it wasn't specified.
145
- else
146
- say("Writing configuration to: #{path}", :yellow)
147
-
148
- begin
149
- config.write
150
- rescue Config::ConfigError => e
151
- error("Error: Unable to write configuration file:\n\t#{e}")
152
- return
153
- rescue StandardError => e
154
- error("Error: Unable to write configuration file:\n\t#{e.class} -- #{e.message}\n\t#{e.backtrace.join("\n\t")}")
155
- return
156
- end
157
- end
158
-
159
- if !skip_test && (options[:test].nil? || options[:test])
160
- Honeybadger.start(config) unless load_rails_env(verbose: true)
161
- say('Sending test notice', :yellow)
162
- unless Agent.instance && send_test(false)
163
- say('Honeybadger is installed, but failed to send a test notice. Try `honeybadger debug --test`.', :red)
164
- return
165
- end
166
- end
167
-
168
- say("Installation complete. Happy 'badgering!", :green)
169
- end
170
-
171
- private
172
-
173
- def rails?(opts = {})
174
- @rails ||= load_rails(opts)
175
- end
176
-
177
- def load_rails(opts = {})
178
- begin
179
- require 'honeybadger/init/rails'
180
- if ::Rails::VERSION::MAJOR >= 3
181
- say("Detected Rails #{::Rails::VERSION::STRING}") if opts[:verbose]
182
- else
183
- say("Error: Rails #{::Rails::VERSION::STRING} is unsupported.", :red)
184
- exit(1)
185
- end
186
- rescue LoadError
187
- say("Rails was not detected, loading standalone.") if opts[:verbose]
188
- return @rails = false
189
- rescue StandardError => e
190
- say("Error while detecting Rails: #{e.class} -- #{e.message}", :red)
191
- exit(1)
192
- end
193
-
194
- begin
195
- require File.expand_path('config/application')
196
- rescue LoadError
197
- say('Error: could not load Rails application. Please ensure you run this command from your project root.', :red)
198
- exit(1)
199
- end
200
-
201
- @rails = true
202
- end
203
-
204
- def load_rails_env(opts = {})
205
- return false unless rails?(opts)
206
-
207
- puts('Loading Rails environment') if opts[:verbose]
208
- begin
209
- require File.expand_path('config/environment')
210
- rescue LoadError
211
- say('Error: could not load Rails environment. Please ensure you run this command from your project root.', :red)
212
- exit(1)
213
- end
214
-
215
- true
216
- end
217
-
218
- def rails_framework_opts
219
- return {} unless defined?(::Rails)
220
-
221
- {
222
- :root => ::Rails.root,
223
- :env => ::Rails.env,
224
- :'config.path' => ::Rails.root.join('config', 'honeybadger.yml'),
225
- :framework_name => "Rails #{::Rails::VERSION::STRING}",
226
- :api_key => rails_secrets_api_key
227
- }
228
- end
229
-
230
- def rails_secrets_api_key
231
- if defined?(::Rails.application.secrets)
232
- ::Rails.application.secrets.honeybadger_api_key
233
- end
234
- end
235
-
236
- def output_config(nested_hash, hierarchy = [])
237
- nested_hash.each_pair do |key, value|
238
- if value.kind_of?(Hash)
239
- say(tab_indent(hierarchy.size) << "#{key}:")
240
- output_config(value, hierarchy + [key])
241
- else
242
- dotted_key = (hierarchy + [key]).join('.').to_sym
243
- say(tab_indent(hierarchy.size) << "#{key}:")
244
- indent = tab_indent(hierarchy.size+1)
245
- say(indent + "Description: #{Config::OPTIONS[dotted_key][:description]}")
246
- say(indent + "Default: #{Config::OPTIONS[dotted_key][:default].inspect}")
247
- say(indent + "Current: #{value.inspect}")
248
- end
249
- end
250
- end
251
-
252
- def tab_indent(number)
253
- ''.tap do |s|
254
- number.times { s << "\s\s" }
255
- end
256
- end
257
-
258
- def load_platform(platform, app = nil)
259
- if platform.to_sym == :heroku
260
- say("Using platform: #{platform}" << (app ? " (app: #{app})" : ""))
261
- unless set_env_from_heroku(app)
262
- say("Unable to load ENV from Heroku. Do you need to specify an app name?", :red)
263
- return false
264
- end
265
- end
266
-
267
- true
268
- end
269
-
270
- def read_heroku_env(app = nil)
271
- cmd = ['heroku config']
272
- cmd << "--app #{app}" if app
273
- output = Bundler.with_clean_env { `#{cmd.join("\s")}` }
274
- return false unless $?.to_i == 0
275
- Hash[output.scan(/(HONEYBADGER_[^:]+):\s*(\S.*)\s*$/)]
276
- end
277
-
278
- def set_env_from_heroku(app = nil)
279
- return false unless env = read_heroku_env(app)
280
- env.each_pair do |k,v|
281
- ENV[k] ||= v
282
- end
283
- end
284
-
285
- def write_heroku_env(env, app = nil)
286
- cmd = ["heroku config:set"]
287
- Hash(env).each_pair {|k,v| cmd << "#{k}=#{v}" }
288
- cmd << "--app #{app}" if app
289
- Bundler.with_clean_env { `#{cmd.join("\s")}` }
290
- $?.to_i == 0
291
- end
292
-
293
- def test_exception_class
294
- exception_name = ENV['EXCEPTION'] || 'HoneybadgerTestingException'
295
- Object.const_get(exception_name)
296
- rescue
297
- Object.const_set(exception_name, Class.new(Exception))
298
- end
299
-
300
- def send_test(verbose = true)
301
- if defined?(::Rails)
302
- rails_test(verbose)
303
- else
304
- standalone_test
305
- end
306
- end
307
-
308
- def standalone_test
309
- Honeybadger.notify(test_exception_class.new('Testing honeybadger via "honeybadger test". If you can see this, it works.'))
310
- end
311
-
312
- def rails_test(verbose = true)
313
- if verbose
314
- ::Rails.logger = if defined?(::ActiveSupport::TaggedLogging)
315
- ::ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
316
- else
317
- Logger.new(STDOUT)
318
- end
319
- ::Rails.logger.level = Logger::INFO
320
- end
321
-
322
- # Suppress error logging in Rails' exception handling middleware. Rails 3.0
323
- # uses ActionDispatch::ShowExceptions to rescue/show exceptions, but does
324
- # not log anything but application trace. Rails 3.2 now falls back to
325
- # logging the framework trace (moved to ActionDispatch::DebugExceptions),
326
- # which caused cluttered output while running the test task.
327
- defined?(::ActionDispatch::DebugExceptions) and
328
- ::ActionDispatch::DebugExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
329
- defined?(::ActionDispatch::ShowExceptions) and
330
- ::ActionDispatch::ShowExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
331
-
332
- # Detect and disable the better_errors gem
333
- if defined?(::BetterErrors::Middleware)
334
- say('Better Errors detected: temporarily disabling middleware.', :yellow)
335
- ::BetterErrors::Middleware.class_eval { def call(env) @app.call(env); end }
336
- end
337
-
338
- begin
339
- require './app/controllers/application_controller'
340
- rescue LoadError
341
- nil
342
- end
343
-
344
- unless defined?(::ApplicationController)
345
- say('Error: No ApplicationController found.', :red)
346
- return false
347
- end
348
-
349
- say('Setting up the Controller.')
350
- ::ApplicationController.class_eval do
351
- # This is to bypass any filters that may prevent access to the action.
352
- prepend_before_filter :test_honeybadger
353
- def test_honeybadger
354
- puts "Raising '#{exception_class.name}' to simulate application failure."
355
- raise exception_class.new, 'Testing honeybadger via "rake honeybadger:test". If you can see this, it works.'
356
- end
357
-
358
- # Ensure we actually have an action to go to.
359
- def verify; end
360
-
361
- def exception_class
362
- exception_name = ENV['EXCEPTION'] || 'HoneybadgerTestingException'
363
- Object.const_get(exception_name)
364
- rescue
365
- Object.const_set(exception_name, Class.new(Exception))
366
- end
367
- end
368
-
369
- ::Rails.application.routes.draw do
370
- match 'verify' => 'application#verify', :as => 'verify', :via => :get
371
- end
372
-
373
- say('Processing request.')
374
-
375
- ssl = defined?(::Rails.configuration.force_ssl) && ::Rails.configuration.force_ssl
376
- env = ::Rack::MockRequest.env_for("http#{ ssl ? 's' : nil }://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')
377
-
378
- ::Rails.application.call(env)
10
+ module CLI
11
+ def self.start(*args)
12
+ Main.start(*args)
379
13
  end
380
14
  end
381
15
  end
@@ -0,0 +1,158 @@
1
+ require 'logger'
2
+
3
+ module Honeybadger
4
+ module CLI
5
+ module Helpers
6
+ def rails?(opts = {})
7
+ @rails ||= load_rails(opts)
8
+ end
9
+
10
+ def load_rails(opts = {})
11
+ begin
12
+ require 'honeybadger/init/rails'
13
+ if ::Rails::VERSION::MAJOR >= 3
14
+ say("Detected Rails #{::Rails::VERSION::STRING}") if opts[:verbose]
15
+ else
16
+ say("Error: Rails #{::Rails::VERSION::STRING} is unsupported.", :red)
17
+ exit(1)
18
+ end
19
+ rescue LoadError
20
+ say("Rails was not detected, loading standalone.") if opts[:verbose]
21
+ return @rails = false
22
+ rescue StandardError => e
23
+ say("Error while detecting Rails: #{e.class} -- #{e.message}", :red)
24
+ exit(1)
25
+ end
26
+
27
+ begin
28
+ require File.expand_path('config/application')
29
+ rescue LoadError
30
+ say('Error: could not load Rails application. Please ensure you run this command from your project root.', :red)
31
+ exit(1)
32
+ end
33
+
34
+ @rails = true
35
+ end
36
+
37
+ def load_rails_env(opts = {})
38
+ return false unless rails?(opts)
39
+
40
+ puts('Loading Rails environment') if opts[:verbose]
41
+ begin
42
+ require File.expand_path('config/environment')
43
+ rescue LoadError
44
+ say('Error: could not load Rails environment. Please ensure you run this command from your project root.', :red)
45
+ exit(1)
46
+ end
47
+
48
+ true
49
+ end
50
+
51
+ def rails_framework_opts
52
+ return {} unless defined?(::Rails)
53
+
54
+ {
55
+ :root => ::Rails.root,
56
+ :env => ::Rails.env,
57
+ :'config.path' => ::Rails.root.join('config', 'honeybadger.yml'),
58
+ :framework_name => "Rails #{::Rails::VERSION::STRING}",
59
+ :api_key => rails_secrets_api_key
60
+ }
61
+ end
62
+
63
+ def rails_secrets_api_key
64
+ if defined?(::Rails.application.secrets)
65
+ ::Rails.application.secrets.honeybadger_api_key
66
+ end
67
+ end
68
+
69
+ def test_exception_class
70
+ exception_name = ENV['EXCEPTION'] || 'HoneybadgerTestingException'
71
+ Object.const_get(exception_name)
72
+ rescue
73
+ Object.const_set(exception_name, Class.new(Exception))
74
+ end
75
+
76
+ def send_test(verbose = true)
77
+ if defined?(::Rails)
78
+ rails_test(verbose)
79
+ else
80
+ standalone_test
81
+ end
82
+ end
83
+
84
+ def standalone_test
85
+ Honeybadger.notify(test_exception_class.new('Testing honeybadger via "honeybadger test". If you can see this, it works.'))
86
+ end
87
+
88
+ def rails_test(verbose = true)
89
+ if verbose
90
+ ::Rails.logger = if defined?(::ActiveSupport::TaggedLogging)
91
+ ::ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
92
+ else
93
+ Logger.new(STDOUT)
94
+ end
95
+ ::Rails.logger.level = Logger::INFO
96
+ end
97
+
98
+ # Suppress error logging in Rails' exception handling middleware. Rails 3.0
99
+ # uses ActionDispatch::ShowExceptions to rescue/show exceptions, but does
100
+ # not log anything but application trace. Rails 3.2 now falls back to
101
+ # logging the framework trace (moved to ActionDispatch::DebugExceptions),
102
+ # which caused cluttered output while running the test task.
103
+ defined?(::ActionDispatch::DebugExceptions) and
104
+ ::ActionDispatch::DebugExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
105
+ defined?(::ActionDispatch::ShowExceptions) and
106
+ ::ActionDispatch::ShowExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
107
+
108
+ # Detect and disable the better_errors gem
109
+ if defined?(::BetterErrors::Middleware)
110
+ say('Better Errors detected: temporarily disabling middleware.', :yellow)
111
+ ::BetterErrors::Middleware.class_eval { def call(env) @app.call(env); end }
112
+ end
113
+
114
+ begin
115
+ require './app/controllers/application_controller'
116
+ rescue LoadError
117
+ nil
118
+ end
119
+
120
+ unless defined?(::ApplicationController)
121
+ say('Error: No ApplicationController found.', :red)
122
+ return false
123
+ end
124
+
125
+ say('Setting up the Controller.')
126
+ ::ApplicationController.class_eval do
127
+ # This is to bypass any filters that may prevent access to the action.
128
+ prepend_before_filter :test_honeybadger
129
+ def test_honeybadger
130
+ puts "Raising '#{exception_class.name}' to simulate application failure."
131
+ raise exception_class.new, 'Testing honeybadger via "rake honeybadger:test". If you can see this, it works.'
132
+ end
133
+
134
+ # Ensure we actually have an action to go to.
135
+ def verify; end
136
+
137
+ def exception_class
138
+ exception_name = ENV['EXCEPTION'] || 'HoneybadgerTestingException'
139
+ Object.const_get(exception_name)
140
+ rescue
141
+ Object.const_set(exception_name, Class.new(Exception))
142
+ end
143
+ end
144
+
145
+ ::Rails.application.routes.draw do
146
+ match 'verify' => 'application#verify', :as => 'verify', :via => :get
147
+ end
148
+
149
+ say('Processing request.')
150
+
151
+ ssl = defined?(::Rails.configuration.force_ssl) && ::Rails.configuration.force_ssl
152
+ env = ::Rack::MockRequest.env_for("http#{ ssl ? 's' : nil }://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')
153
+
154
+ ::Rails.application.call(env)
155
+ end
156
+ end
157
+ end
158
+ end