honeybadger 2.7.2 → 3.0.0.beta1
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 +4 -4
 - data/CHANGELOG.md +58 -3
 - data/README.md +8 -15
 - data/lib/honeybadger.rb +9 -232
 - data/lib/honeybadger/agent.rb +292 -134
 - data/lib/honeybadger/backend.rb +6 -6
 - data/lib/honeybadger/backend/base.rb +11 -0
 - data/lib/honeybadger/backend/server.rb +2 -14
 - data/lib/honeybadger/cli.rb +0 -2
 - data/lib/honeybadger/cli/deploy.rb +42 -0
 - data/lib/honeybadger/cli/exec.rb +138 -0
 - data/lib/honeybadger/cli/heroku.rb +1 -22
 - data/lib/honeybadger/cli/install.rb +74 -0
 - data/lib/honeybadger/cli/main.rb +138 -153
 - data/lib/honeybadger/cli/notify.rb +66 -0
 - data/lib/honeybadger/cli/test.rb +266 -0
 - data/lib/honeybadger/config.rb +178 -162
 - data/lib/honeybadger/config/defaults.rb +5 -5
 - data/lib/honeybadger/config/env.rb +8 -6
 - data/lib/honeybadger/config/ruby.rb +100 -0
 - data/lib/honeybadger/config/yaml.rb +18 -19
 - data/lib/honeybadger/const.rb +3 -16
 - data/lib/honeybadger/context_manager.rb +50 -0
 - data/lib/honeybadger/init/rails.rb +9 -21
 - data/lib/honeybadger/init/rake.rb +2 -0
 - data/lib/honeybadger/init/ruby.rb +9 -0
 - data/lib/honeybadger/init/sinatra.rb +13 -6
 - data/lib/honeybadger/notice.rb +29 -14
 - data/lib/honeybadger/plugins/delayed_job/plugin.rb +4 -5
 - data/lib/honeybadger/plugins/passenger.rb +1 -2
 - data/lib/honeybadger/plugins/rails.rb +0 -28
 - data/lib/honeybadger/plugins/resque.rb +2 -5
 - data/lib/honeybadger/plugins/shoryuken.rb +2 -2
 - data/lib/honeybadger/plugins/sidekiq.rb +2 -2
 - data/lib/honeybadger/plugins/sucker_punch.rb +1 -0
 - data/lib/honeybadger/plugins/thor.rb +2 -2
 - data/lib/honeybadger/plugins/warden.rb +1 -0
 - data/lib/honeybadger/rack/error_notifier.rb +11 -9
 - data/lib/honeybadger/rack/user_feedback.rb +6 -4
 - data/lib/honeybadger/rack/user_informer.rb +6 -4
 - data/lib/honeybadger/ruby.rb +2 -0
 - data/lib/honeybadger/singleton.rb +26 -0
 - data/lib/honeybadger/util/http.rb +12 -0
 - data/lib/honeybadger/util/request_hash.rb +71 -0
 - data/lib/honeybadger/util/sanitizer.rb +101 -64
 - data/lib/honeybadger/version.rb +1 -1
 - data/lib/honeybadger/worker.rb +246 -0
 - metadata +17 -13
 - data/lib/honeybadger/agent/batch.rb +0 -50
 - data/lib/honeybadger/agent/null_worker.rb +0 -26
 - data/lib/honeybadger/agent/worker.rb +0 -243
 - data/lib/honeybadger/cli/helpers.rb +0 -160
 - data/lib/honeybadger/config/callbacks.rb +0 -70
 - data/lib/honeybadger/plugins/unicorn.rb +0 -27
 - data/lib/honeybadger/rack/metrics_reporter.rb +0 -16
 - data/lib/honeybadger/rack/request_hash.rb +0 -55
 
    
        data/lib/honeybadger/backend.rb
    CHANGED
    
    | 
         @@ -1,5 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'forwardable'
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'honeybadger/backend/base'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'honeybadger/backend/server'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'honeybadger/backend/test'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'honeybadger/backend/null'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'honeybadger/backend/debug'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       3 
9 
     | 
    
         
             
            module Honeybadger
         
     | 
| 
       4 
10 
     | 
    
         
             
              module Backend
         
     | 
| 
       5 
11 
     | 
    
         
             
                class BackendError < StandardError; end
         
     | 
| 
         @@ -16,11 +22,5 @@ module Honeybadger 
     | 
|
| 
       16 
22 
     | 
    
         
             
                def self.for(backend)
         
     | 
| 
       17 
23 
     | 
    
         
             
                  mapping[backend] or raise(BackendError, "Unable to locate backend: #{backend}")
         
     | 
| 
       18 
24 
     | 
    
         
             
                end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                autoload :Base, 'honeybadger/backend/base'
         
     | 
| 
       21 
     | 
    
         
            -
                autoload :Server, 'honeybadger/backend/server'
         
     | 
| 
       22 
     | 
    
         
            -
                autoload :Test, 'honeybadger/backend/test'
         
     | 
| 
       23 
     | 
    
         
            -
                autoload :Null, 'honeybadger/backend/null'
         
     | 
| 
       24 
     | 
    
         
            -
                autoload :Debug, 'honeybadger/backend/debug'
         
     | 
| 
       25 
25 
     | 
    
         
             
              end
         
     | 
| 
       26 
26 
     | 
    
         
             
            end
         
     | 
| 
         @@ -11,6 +11,13 @@ module Honeybadger 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                  attr_reader :code, :body, :message, :error
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
                  FRIENDLY_ERRORS = {
         
     | 
| 
      
 15 
     | 
    
         
            +
                    429 => "Your project is currently sending too many errors.\nThis issue should resolve itself once error traffic is reduced.".freeze,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    503 => "Your project is currently sending too many errors.\nThis issue should resolve itself once error traffic is reduced.".freeze,
         
     | 
| 
      
 17 
     | 
    
         
            +
                    402 => "The project owner's billing information has expired (or the trial has ended).\nPlease check your payment details or email support@honeybadger.io for help.".freeze,
         
     | 
| 
      
 18 
     | 
    
         
            +
                    403 => "The API key is invalid. Please check your API key and try again.".freeze
         
     | 
| 
      
 19 
     | 
    
         
            +
                  }.freeze
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       14 
21 
     | 
    
         
             
                  # Public: Initializes the Response instance.
         
     | 
| 
       15 
22 
     | 
    
         
             
                  #
         
     | 
| 
       16 
23 
     | 
    
         
             
                  # response - With 1 argument Net::HTTPResponse, the code, body, and
         
     | 
| 
         @@ -37,6 +44,10 @@ module Honeybadger 
     | 
|
| 
       37 
44 
     | 
    
         
             
                    @success
         
     | 
| 
       38 
45 
     | 
    
         
             
                  end
         
     | 
| 
       39 
46 
     | 
    
         | 
| 
      
 47 
     | 
    
         
            +
                  def error_message
         
     | 
| 
      
 48 
     | 
    
         
            +
                    FRIENDLY_ERRORS[code] || message
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       40 
51 
     | 
    
         
             
                  private
         
     | 
| 
       41 
52 
     | 
    
         | 
| 
       42 
53 
     | 
    
         
             
                  def parse_error(body)
         
     | 
| 
         @@ -15,17 +15,7 @@ module Honeybadger 
     | 
|
| 
       15 
15 
     | 
    
         
             
                    deploys: '/v1/deploys'.freeze
         
     | 
| 
       16 
16 
     | 
    
         
             
                  }.freeze
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                  HTTP_ERRORS =  
     | 
| 
       19 
     | 
    
         
            -
                                 Errno::EINVAL,
         
     | 
| 
       20 
     | 
    
         
            -
                                 Errno::ECONNRESET,
         
     | 
| 
       21 
     | 
    
         
            -
                                 Errno::ECONNREFUSED,
         
     | 
| 
       22 
     | 
    
         
            -
                                 Errno::ENETUNREACH,
         
     | 
| 
       23 
     | 
    
         
            -
                                 EOFError,
         
     | 
| 
       24 
     | 
    
         
            -
                                 Net::HTTPBadResponse,
         
     | 
| 
       25 
     | 
    
         
            -
                                 Net::HTTPHeaderSyntaxError,
         
     | 
| 
       26 
     | 
    
         
            -
                                 Net::ProtocolError,
         
     | 
| 
       27 
     | 
    
         
            -
                                 OpenSSL::SSL::SSLError,
         
     | 
| 
       28 
     | 
    
         
            -
                                 SocketError].freeze
         
     | 
| 
      
 18 
     | 
    
         
            +
                  HTTP_ERRORS = Util::HTTP::ERRORS
         
     | 
| 
       29 
19 
     | 
    
         | 
| 
       30 
20 
     | 
    
         
             
                  def initialize(config)
         
     | 
| 
       31 
21 
     | 
    
         
             
                    @http = Util::HTTP.new(config)
         
     | 
| 
         @@ -42,9 +32,7 @@ module Honeybadger 
     | 
|
| 
       42 
32 
     | 
    
         
             
                    ENDPOINTS[feature] or raise(BackendError, "Unknown feature: #{feature}")
         
     | 
| 
       43 
33 
     | 
    
         
             
                    Response.new(@http.post(ENDPOINTS[feature], payload, payload_headers(payload)))
         
     | 
| 
       44 
34 
     | 
    
         
             
                  rescue *HTTP_ERRORS => e
         
     | 
| 
       45 
     | 
    
         
            -
                    Response.new(:error, nil, "HTTP Error: #{e.class}") 
     | 
| 
       46 
     | 
    
         
            -
                      error { sprintf('http error class=%s message=%s', e.class, e.message.dump) }
         
     | 
| 
       47 
     | 
    
         
            -
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    Response.new(:error, nil, "HTTP Error: #{e.class}")
         
     | 
| 
       48 
36 
     | 
    
         
             
                  end
         
     | 
| 
       49 
37 
     | 
    
         | 
| 
       50 
38 
     | 
    
         
             
                  private
         
     | 
    
        data/lib/honeybadger/cli.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'forwardable'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'honeybadger/cli/main'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'honeybadger/util/http'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Honeybadger
         
     | 
| 
      
 6 
     | 
    
         
            +
              module CLI
         
     | 
| 
      
 7 
     | 
    
         
            +
                class Deploy
         
     | 
| 
      
 8 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(options, args, config)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @options = options
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @args = args
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @config = config
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @shell = ::Thor::Base.shell.new
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 18 
     | 
    
         
            +
                    payload = {
         
     | 
| 
      
 19 
     | 
    
         
            +
                      environment: options['environment'],
         
     | 
| 
      
 20 
     | 
    
         
            +
                      revision: options['revision'],
         
     | 
| 
      
 21 
     | 
    
         
            +
                      repository: options['repository'],
         
     | 
| 
      
 22 
     | 
    
         
            +
                      local_username: options['user']
         
     | 
| 
      
 23 
     | 
    
         
            +
                    }
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    http = Util::HTTP.new(config)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    result = http.post('/v1/deploys', payload)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if result.code == '201'
         
     | 
| 
      
 28 
     | 
    
         
            +
                      say("Deploy notification complete.", :green)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    else
         
     | 
| 
      
 30 
     | 
    
         
            +
                      say("Invalid response from server: #{result.code}", :red)
         
     | 
| 
      
 31 
     | 
    
         
            +
                      exit(1)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  private
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  attr_reader :options, :args, :config
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def_delegator :@shell, :say
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,138 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'erb'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'forwardable'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'honeybadger/cli/main'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'honeybadger/util/http'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'honeybadger/util/stats'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'open3'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'ostruct'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'thor/shell'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            module Honeybadger
         
     | 
| 
      
 11 
     | 
    
         
            +
              module CLI
         
     | 
| 
      
 12 
     | 
    
         
            +
                class Exec
         
     | 
| 
      
 13 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  FAILED_TEMPLATE = <<-MSG
         
     | 
| 
      
 16 
     | 
    
         
            +
            Honeybadger detected failure or error output for the command:
         
     | 
| 
      
 17 
     | 
    
         
            +
            `<%= args.join(' ') %>`
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            PROCESS ID: <%= pid %>
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            RESULT CODE: <%= code %>
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ERROR OUTPUT:
         
     | 
| 
      
 24 
     | 
    
         
            +
            <%= stderr %>
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            STANDARD OUTPUT:
         
     | 
| 
      
 27 
     | 
    
         
            +
            <%= stdout %>
         
     | 
| 
      
 28 
     | 
    
         
            +
            MSG
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  NO_EXEC_TEMPLATE = <<-MSG
         
     | 
| 
      
 31 
     | 
    
         
            +
            Honeybadger failed to execute the following command:
         
     | 
| 
      
 32 
     | 
    
         
            +
            `<%= args.join(' ') %>`
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            The command was not executable. Try adjusting permissions on the file.
         
     | 
| 
      
 35 
     | 
    
         
            +
            MSG
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  NOT_FOUND_TEMPLATE = <<-MSG
         
     | 
| 
      
 38 
     | 
    
         
            +
            Honeybadger failed to execute the following command:
         
     | 
| 
      
 39 
     | 
    
         
            +
            `<%= args.join(' ') %>`
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            The command was not found. Make sure it exists in your PATH.
         
     | 
| 
      
 42 
     | 
    
         
            +
            MSG
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def initialize(options, args, config)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    @options = options
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @args = args
         
     | 
| 
      
 47 
     | 
    
         
            +
                    @config = config
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @shell = ::Thor::Base.shell.new
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 52 
     | 
    
         
            +
                    result = exec_cmd
         
     | 
| 
      
 53 
     | 
    
         
            +
                    return if result.success
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    payload = {
         
     | 
| 
      
 56 
     | 
    
         
            +
                      api_key: config.get(:api_key),
         
     | 
| 
      
 57 
     | 
    
         
            +
                      notifier: NOTIFIER,
         
     | 
| 
      
 58 
     | 
    
         
            +
                      error: {
         
     | 
| 
      
 59 
     | 
    
         
            +
                        class: 'honeybdager exec error',
         
     | 
| 
      
 60 
     | 
    
         
            +
                        message: result.msg
         
     | 
| 
      
 61 
     | 
    
         
            +
                      },
         
     | 
| 
      
 62 
     | 
    
         
            +
                      request: {
         
     | 
| 
      
 63 
     | 
    
         
            +
                        context: {
         
     | 
| 
      
 64 
     | 
    
         
            +
                          executable: args.first,
         
     | 
| 
      
 65 
     | 
    
         
            +
                          code: result.code,
         
     | 
| 
      
 66 
     | 
    
         
            +
                          pid: result.pid
         
     | 
| 
      
 67 
     | 
    
         
            +
                        }
         
     | 
| 
      
 68 
     | 
    
         
            +
                      },
         
     | 
| 
      
 69 
     | 
    
         
            +
                      server: {
         
     | 
| 
      
 70 
     | 
    
         
            +
                        project_root: Dir.pwd,
         
     | 
| 
      
 71 
     | 
    
         
            +
                        environment_name: config.get(:env),
         
     | 
| 
      
 72 
     | 
    
         
            +
                        time: Time.now,
         
     | 
| 
      
 73 
     | 
    
         
            +
                        stats: Util::Stats.all
         
     | 
| 
      
 74 
     | 
    
         
            +
                      }
         
     | 
| 
      
 75 
     | 
    
         
            +
                    }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    http = Util::HTTP.new(config)
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 80 
     | 
    
         
            +
                      response = http.post('/v1/notices', payload)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    rescue
         
     | 
| 
      
 82 
     | 
    
         
            +
                      say(result.msg)
         
     | 
| 
      
 83 
     | 
    
         
            +
                      raise
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    if response.code != '201'
         
     | 
| 
      
 87 
     | 
    
         
            +
                      say(result.msg)
         
     | 
| 
      
 88 
     | 
    
         
            +
                      say("\nFailed to notify Honeybadger: #{response.code}", :red)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      exit(1)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    unless quiet?
         
     | 
| 
      
 93 
     | 
    
         
            +
                      say(result.msg)
         
     | 
| 
      
 94 
     | 
    
         
            +
                      say("\nSuccessfully notified Honeybadger")
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    exit(0)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  private
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                  attr_reader :options, :args, :config
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                  def_delegator :@shell, :say
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                  def quiet?
         
     | 
| 
      
 107 
     | 
    
         
            +
                    !!options[:quiet]
         
     | 
| 
      
 108 
     | 
    
         
            +
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                  def exec_cmd
         
     | 
| 
      
 111 
     | 
    
         
            +
                    stdout, stderr, status = Open3.capture3(args.join(' '))
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                    pid = status.pid
         
     | 
| 
      
 114 
     | 
    
         
            +
                    code = status.to_i
         
     | 
| 
      
 115 
     | 
    
         
            +
                    msg = ERB.new(FAILED_TEMPLATE).result(binding) unless status.success?
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                    OpenStruct.new(
         
     | 
| 
      
 118 
     | 
    
         
            +
                      msg: msg,
         
     | 
| 
      
 119 
     | 
    
         
            +
                      pid: pid,
         
     | 
| 
      
 120 
     | 
    
         
            +
                      code: code,
         
     | 
| 
      
 121 
     | 
    
         
            +
                      stdout: stdout,
         
     | 
| 
      
 122 
     | 
    
         
            +
                      stderr: stderr,
         
     | 
| 
      
 123 
     | 
    
         
            +
                      success: status.success? && stderr =~ BLANK
         
     | 
| 
      
 124 
     | 
    
         
            +
                    )
         
     | 
| 
      
 125 
     | 
    
         
            +
                  rescue Errno::EACCES, Errno::ENOEXEC
         
     | 
| 
      
 126 
     | 
    
         
            +
                    OpenStruct.new(
         
     | 
| 
      
 127 
     | 
    
         
            +
                      msg: ERB.new(NO_EXEC_TEMPLATE).result(binding),
         
     | 
| 
      
 128 
     | 
    
         
            +
                      code: 126
         
     | 
| 
      
 129 
     | 
    
         
            +
                    )
         
     | 
| 
      
 130 
     | 
    
         
            +
                  rescue Errno::ENOENT
         
     | 
| 
      
 131 
     | 
    
         
            +
                    OpenStruct.new(
         
     | 
| 
      
 132 
     | 
    
         
            +
                      msg: ERB.new(NOT_FOUND_TEMPLATE).result(binding),
         
     | 
| 
      
 133 
     | 
    
         
            +
                      code: 127
         
     | 
| 
      
 134 
     | 
    
         
            +
                    )
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,10 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'honeybadger/cli/helpers'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            module Honeybadger
         
     | 
| 
       4 
2 
     | 
    
         
             
              module CLI
         
     | 
| 
       5 
3 
     | 
    
         
             
                class Heroku < Thor
         
     | 
| 
       6 
     | 
    
         
            -
                  include Helpers
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
4 
     | 
    
         
             
                  class_option :app, aliases: :'-a', type: :string, default: nil, desc: 'Specify optional Heroku APP'
         
     | 
| 
       9 
5 
     | 
    
         | 
| 
       10 
6 
     | 
    
         
             
                  desc 'install_deploy_notification', 'Install Heroku deploy notifications addon'
         
     | 
| 
         @@ -37,19 +33,10 @@ module Honeybadger 
     | 
|
| 
       37 
33 
     | 
    
         
             
                  def install(api_key)
         
     | 
| 
       38 
34 
     | 
    
         
             
                    say("Installing Honeybadger #{VERSION} for Heroku")
         
     | 
| 
       39 
35 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                    load_rails(verbose: true)
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_LEVEL']     = '2'
         
     | 
| 
       43 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
         
     | 
| 
       44 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_PATH']      = 'STDOUT'
         
     | 
| 
       45 
     | 
    
         
            -
                    ENV['HONEYBADGER_REPORT_DATA']       = 'true'
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                    ENV['HONEYBADGER_API_KEY'] = api_key
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
36 
     | 
    
         
             
                    app = options[:app] || detect_heroku_app(false)
         
     | 
| 
       50 
37 
     | 
    
         
             
                    say("Adding config HONEYBADGER_API_KEY=#{api_key} to Heroku.", :magenta)
         
     | 
| 
       51 
38 
     | 
    
         
             
                    unless write_heroku_env({'HONEYBADGER_API_KEY' => api_key}, app)
         
     | 
| 
       52 
     | 
    
         
            -
                      say('Unable to update heroku config.  
     | 
| 
      
 39 
     | 
    
         
            +
                      say('Unable to update heroku config. You may need to specify an app name with --app APP', :red)
         
     | 
| 
       53 
40 
     | 
    
         
             
                      exit(1)
         
     | 
| 
       54 
41 
     | 
    
         
             
                    end
         
     | 
| 
       55 
42 
     | 
    
         | 
| 
         @@ -61,14 +48,6 @@ module Honeybadger 
     | 
|
| 
       61 
48 
     | 
    
         
             
                      say("To install manually, try `honeybadger heroku install_deploy_notification#{app ? " -a #{app}" : ""} -k #{api_key} --environment ENVIRONMENT`", :yellow)
         
     | 
| 
       62 
49 
     | 
    
         
             
                    end
         
     | 
| 
       63 
50 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
                    config = Config.new(rails_framework_opts)
         
     | 
| 
       65 
     | 
    
         
            -
                    Honeybadger.start(config) unless load_rails_env(verbose: true)
         
     | 
| 
       66 
     | 
    
         
            -
                    say('Sending test notice')
         
     | 
| 
       67 
     | 
    
         
            -
                    unless Agent.instance && send_test(false)
         
     | 
| 
       68 
     | 
    
         
            -
                      say("Honeybadger is installed, but failed to send a test notice. Try `HONEYBADGER_API_KEY=#{api_key} honeybadger test`.", :red)
         
     | 
| 
       69 
     | 
    
         
            -
                      exit(1)
         
     | 
| 
       70 
     | 
    
         
            -
                    end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
51 
     | 
    
         
             
                    say("Installation complete. Happy 'badgering!", :green)
         
     | 
| 
       73 
52 
     | 
    
         
             
                  end
         
     | 
| 
       74 
53 
     | 
    
         | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'forwardable'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'honeybadger/cli/main'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'honeybadger/cli/test'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'pathname'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Honeybadger
         
     | 
| 
      
 7 
     | 
    
         
            +
              module CLI
         
     | 
| 
      
 8 
     | 
    
         
            +
                class Install
         
     | 
| 
      
 9 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(options, api_key)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @options = options
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @api_key = api_key
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @shell = ::Thor::Base.shell.new
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 18 
     | 
    
         
            +
                    say("Installing Honeybadger #{VERSION}")
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 21 
     | 
    
         
            +
                      require File.join(Dir.pwd, 'config', 'application.rb')
         
     | 
| 
      
 22 
     | 
    
         
            +
                    rescue LoadError
         
     | 
| 
      
 23 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    root = defined?(Rails.root) ? Rails.root : Pathname.new(Dir.pwd)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    config_root = defined?(Rails.root) ? root.join('config') : root
         
     | 
| 
      
 28 
     | 
    
         
            +
                    config_path = config_root.join('honeybadger.yml')
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    if config_path.exist?
         
     | 
| 
      
 31 
     | 
    
         
            +
                      say("You're already on Honeybadger, so you're all set.", :yellow)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    else
         
     | 
| 
      
 33 
     | 
    
         
            +
                      say("Writing configuration to: #{config_path}", :yellow)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                      path = config_path
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      if path.exist?
         
     | 
| 
      
 38 
     | 
    
         
            +
                        say("The configuration file #{config_path} already exists.", :red)
         
     | 
| 
      
 39 
     | 
    
         
            +
                        exit(1)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      elsif !path.dirname.writable?
         
     | 
| 
      
 41 
     | 
    
         
            +
                        say("The configuration path #{config_path.dirname} is not writable.", :red)
         
     | 
| 
      
 42 
     | 
    
         
            +
                        exit(1)
         
     | 
| 
      
 43 
     | 
    
         
            +
                      end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                      File.open(path, 'w+') do |file|
         
     | 
| 
      
 46 
     | 
    
         
            +
                        file.write(<<-CONFIG)
         
     | 
| 
      
 47 
     | 
    
         
            +
            ---
         
     | 
| 
      
 48 
     | 
    
         
            +
            api_key: '#{api_key}'
         
     | 
| 
      
 49 
     | 
    
         
            +
            CONFIG
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    if (capfile = root.join('Capfile')).exist?
         
     | 
| 
      
 54 
     | 
    
         
            +
                      if capfile.read.match(/honeybadger/)
         
     | 
| 
      
 55 
     | 
    
         
            +
                        say("Detected Honeybadger in Capfile; skipping Capistrano installation.", :yellow)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      else
         
     | 
| 
      
 57 
     | 
    
         
            +
                        say("Appending Capistrano tasks to: #{capfile}", :yellow)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        File.open(capfile, 'a') do |f|
         
     | 
| 
      
 59 
     | 
    
         
            +
                          f.puts("\nrequire 'capistrano/honeybadger'")
         
     | 
| 
      
 60 
     | 
    
         
            +
                        end
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                    Test.new({install: true}.freeze).run
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  private
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  attr_reader :options, :api_key
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  def_delegator :@shell, :say
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/honeybadger/cli/main.rb
    CHANGED
    
    | 
         @@ -1,195 +1,180 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require ' 
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require 'honeybadger/cli/ 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'honeybadger/cli/deploy'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'honeybadger/cli/exec'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'honeybadger/cli/heroku'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'honeybadger/cli/install'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'honeybadger/cli/notify'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'honeybadger/cli/test'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'honeybadger/config'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'honeybadger/config/defaults'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'honeybadger/util/http'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'honeybadger/version'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'logger'
         
     | 
| 
       4 
12 
     | 
    
         | 
| 
       5 
13 
     | 
    
         
             
            module Honeybadger
         
     | 
| 
       6 
14 
     | 
    
         
             
              module CLI
         
     | 
| 
      
 15 
     | 
    
         
            +
                BLANK = /\A\s*\z/
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                NOTIFIER = {
         
     | 
| 
      
 18 
     | 
    
         
            +
                  name: 'honeybadger-ruby (cli)'.freeze,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  url: 'https://github.com/honeybadger-io/honeybadger-ruby'.freeze,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  version: VERSION,
         
     | 
| 
      
 21 
     | 
    
         
            +
                  language: nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       7 
24 
     | 
    
         
             
                class Main < Thor
         
     | 
| 
       8 
     | 
    
         
            -
                   
     | 
| 
      
 25 
     | 
    
         
            +
                  def self.project_options
         
     | 
| 
      
 26 
     | 
    
         
            +
                    option :api_key,     required: false, aliases: :'-k', type: :string, desc: 'Api key of your Honeybadger application'
         
     | 
| 
      
 27 
     | 
    
         
            +
                    option :environment, required: false, aliases: [:'-e', :'-env'], type: :string, desc: 'Environment this command is being executed in (i.e. "production", "staging")'
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
       9 
29 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
      
 30 
     | 
    
         
            +
                  desc 'install API_KEY', 'Install Honeybadger into a new project'
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def install(api_key)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    Install.new(options, api_key).run
         
     | 
| 
      
 33 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 34 
     | 
    
         
            +
                    log_error(e)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    exit(1)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
       11 
37 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                   
     | 
| 
      
 38 
     | 
    
         
            +
                  desc 'test', 'Send a test notification from Honeybadger'
         
     | 
| 
      
 39 
     | 
    
         
            +
                  option :dry_run, type: :boolean, aliases: :'-d', default: false, desc: 'Skip sending data to Honeybadger'
         
     | 
| 
      
 40 
     | 
    
         
            +
                  option :file,    type: :string,  aliases: :'-f', default: nil, desc: 'Write the output to FILE'
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def test
         
     | 
| 
      
 42 
     | 
    
         
            +
                    Test.new(options).run
         
     | 
| 
      
 43 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 44 
     | 
    
         
            +
                    log_error(e)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    exit(1)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
       13 
47 
     | 
    
         | 
| 
       14 
48 
     | 
    
         
             
                  desc 'deploy', 'Notify Honeybadger of deployment'
         
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
       16 
     | 
    
         
            -
                  option : 
     | 
| 
       17 
     | 
    
         
            -
                  option : 
     | 
| 
       18 
     | 
    
         
            -
                  option :user, aliases: :'-u',  
     | 
| 
       19 
     | 
    
         
            -
                  option :api_key, aliases: :'-k', type: :string, desc: 'Api key of your Honeybadger application'
         
     | 
| 
      
 49 
     | 
    
         
            +
                  project_options
         
     | 
| 
      
 50 
     | 
    
         
            +
                  option :repository, required: true, type: :string, aliases: :'-r', desc: 'The address of your repository'
         
     | 
| 
      
 51 
     | 
    
         
            +
                  option :revision,   required: true, type: :string, aliases: :'-s', desc: 'The revision/sha that is being deployed'
         
     | 
| 
      
 52 
     | 
    
         
            +
                  option :user,       required: true, type: :string, aliases: :'-u', default: ENV['USER'] || ENV['USERNAME'], desc: 'The local user who is deploying'
         
     | 
| 
       20 
53 
     | 
    
         
             
                  def deploy
         
     | 
| 
       21 
     | 
    
         
            -
                     
     | 
| 
      
 54 
     | 
    
         
            +
                    config = build_config(options)
         
     | 
| 
       22 
55 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_LEVEL']     = '2'
         
     | 
| 
       27 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
         
     | 
| 
       28 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_PATH']      = 'STDOUT'
         
     | 
| 
       29 
     | 
    
         
            -
                    ENV['HONEYBADGER_REPORT_DATA']       = 'true'
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                    say('Loading configuration')
         
     | 
| 
       32 
     | 
    
         
            -
                    config = Config.new(rails_framework_opts)
         
     | 
| 
       33 
     | 
    
         
            -
                    config.update(api_key: options[:api_key]) if options[:api_key] =~ NOT_BLANK
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                    unless (payload[:environment] ||= config[:env]) =~ NOT_BLANK
         
     | 
| 
       36 
     | 
    
         
            -
                      say('Unable to determine environment. (see: `honeybadger help deploy`)', :red)
         
     | 
| 
       37 
     | 
    
         
            -
                      exit(1)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    if config.get(:api_key).to_s =~ BLANK
         
     | 
| 
      
 57 
     | 
    
         
            +
                      say("No value provided for required options '--api-key'")
         
     | 
| 
      
 58 
     | 
    
         
            +
                      return
         
     | 
| 
       38 
59 
     | 
    
         
             
                    end
         
     | 
| 
       39 
60 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                     
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                     
     | 
| 
      
 61 
     | 
    
         
            +
                    Deploy.new(options, [], config).run
         
     | 
| 
      
 62 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 63 
     | 
    
         
            +
                    log_error(e)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    exit(1)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
       44 
66 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
                  desc 'notify', 'Notify Honeybadger of an error'
         
     | 
| 
      
 68 
     | 
    
         
            +
                  project_options
         
     | 
| 
      
 69 
     | 
    
         
            +
                  option :class,       required: true, type: :string, aliases: :'-c', default: 'CLI Notification', desc: 'The class name of the error. (Default: CLI Notification)'
         
     | 
| 
      
 70 
     | 
    
         
            +
                  option :message,     required: true, type: :string, aliases: :'-m', desc: 'The error message.'
         
     | 
| 
      
 71 
     | 
    
         
            +
                  option :action,      required: false, type: :string, aliases: :'-a', desc: 'The action.'
         
     | 
| 
      
 72 
     | 
    
         
            +
                  option :component,   required: false, type: :string, aliases: :'-C', desc: 'The component.'
         
     | 
| 
      
 73 
     | 
    
         
            +
                  option :fingerprint, required: false, type: :string, aliases: :'-f', desc: 'The component.'
         
     | 
| 
      
 74 
     | 
    
         
            +
                  option :tags,        required: false, type: :string, aliases: :'-t', desc: 'The tags.'
         
     | 
| 
      
 75 
     | 
    
         
            +
                  option :url,         required: false, type: :string, aliases: :'-u', desc: 'The URL.'
         
     | 
| 
      
 76 
     | 
    
         
            +
                  def notify
         
     | 
| 
      
 77 
     | 
    
         
            +
                    config = build_config(options)
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    if config.get(:api_key).to_s =~ BLANK
         
     | 
| 
      
 80 
     | 
    
         
            +
                      say("No value provided for required options '--api-key'")
         
     | 
| 
      
 81 
     | 
    
         
            +
                      return
         
     | 
| 
       51 
82 
     | 
    
         
             
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    Notify.new(options, [], config).run
         
     | 
| 
       52 
85 
     | 
    
         
             
                  rescue => e
         
     | 
| 
       53 
     | 
    
         
            -
                     
     | 
| 
      
 86 
     | 
    
         
            +
                    log_error(e)
         
     | 
| 
       54 
87 
     | 
    
         
             
                    exit(1)
         
     | 
| 
       55 
88 
     | 
    
         
             
                  end
         
     | 
| 
       56 
89 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                  desc ' 
     | 
| 
       58 
     | 
    
         
            -
                   
     | 
| 
       59 
     | 
    
         
            -
                   
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                    config =  
     | 
| 
       62 
     | 
    
         
            -
                    output_config(config.to_hash(options[:default]))
         
     | 
| 
       63 
     | 
    
         
            -
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
                  desc 'exec', 'Execute a command. If the exit status is not 0, report the result to Honeybadger'
         
     | 
| 
      
 91 
     | 
    
         
            +
                  project_options
         
     | 
| 
      
 92 
     | 
    
         
            +
                  option :quiet, required: false, type: :boolean, aliases: :'-q', default: false, desc: 'Suppress all output unless Honeybdager notification fails.'
         
     | 
| 
      
 93 
     | 
    
         
            +
                  def exec(*args)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    config = build_config(options)
         
     | 
| 
       64 
95 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                  def test
         
     | 
| 
       69 
     | 
    
         
            -
                    if options[:file]
         
     | 
| 
       70 
     | 
    
         
            -
                      out = StringIO.new
         
     | 
| 
       71 
     | 
    
         
            -
                      $stdout = out
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                      flush = Proc.new do
         
     | 
| 
       74 
     | 
    
         
            -
                        $stdout = STDOUT
         
     | 
| 
       75 
     | 
    
         
            -
                        File.open(options[:file], 'w+') do |f|
         
     | 
| 
       76 
     | 
    
         
            -
                          out.rewind
         
     | 
| 
       77 
     | 
    
         
            -
                          out.each_line {|l| f.write(l) }
         
     | 
| 
       78 
     | 
    
         
            -
                        end
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                        say("Output written to #{options[:file]}", :green)
         
     | 
| 
       81 
     | 
    
         
            -
                      end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                      Agent.at_exit(&flush)
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                      at_exit do
         
     | 
| 
       86 
     | 
    
         
            -
                        # If the agent couldn't be started, the callback should happen here
         
     | 
| 
       87 
     | 
    
         
            -
                        # instead.
         
     | 
| 
       88 
     | 
    
         
            -
                        flush.() unless Agent.running?
         
     | 
| 
       89 
     | 
    
         
            -
                      end
         
     | 
| 
      
 96 
     | 
    
         
            +
                    if config.get(:api_key).to_s =~ BLANK
         
     | 
| 
      
 97 
     | 
    
         
            +
                      say("No value provided for required options '--api-key'")
         
     | 
| 
      
 98 
     | 
    
         
            +
                      return
         
     | 
| 
       90 
99 
     | 
    
         
             
                    end
         
     | 
| 
       91 
100 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                     
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
                     
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_PATH']      = 'STDOUT'
         
     | 
| 
       98 
     | 
    
         
            -
                    ENV['HONEYBADGER_DEBUG']             = 'true'
         
     | 
| 
       99 
     | 
    
         
            -
                    ENV['HONEYBADGER_REPORT_DATA']       = options[:dry_run] ? 'false' : 'true'
         
     | 
| 
      
 101 
     | 
    
         
            +
                    Exec.new(options, args, config).run
         
     | 
| 
      
 102 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 103 
     | 
    
         
            +
                    log_error(e)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    exit(1)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
       100 
106 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
                    output_config(config.to_hash)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  desc 'heroku SUBCOMMAND ...ARGS', 'Manage Honeybadger on Heroku'
         
     | 
| 
      
 108 
     | 
    
         
            +
                  subcommand 'heroku', Heroku
         
     | 
| 
       104 
109 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
                    Honeybadger.start(config) unless load_rails_env(verbose: true)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  private
         
     | 
| 
       107 
111 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                     
     | 
| 
      
 112 
     | 
    
         
            +
                  def fetch_value(options, key)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    options[key] == key ? nil : options[key]
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
       110 
115 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
      
 116 
     | 
    
         
            +
                  def build_config(options)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    config = Config.new(logger: Logger.new('/dev/null'))
         
     | 
| 
      
 118 
     | 
    
         
            +
                    config.set(:api_key, fetch_value(options, 'api_key')) if options.has_key?('api_key')
         
     | 
| 
      
 119 
     | 
    
         
            +
                    config.set(:env, fetch_value(options, 'environment')) if options.has_key?('environment')
         
     | 
| 
      
 120 
     | 
    
         
            +
                    config.init!({
         
     | 
| 
      
 121 
     | 
    
         
            +
                      framework: :cli
         
     | 
| 
      
 122 
     | 
    
         
            +
                    })
         
     | 
| 
      
 123 
     | 
    
         
            +
                    config
         
     | 
| 
       112 
124 
     | 
    
         
             
                  end
         
     | 
| 
       113 
125 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                   
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def log_error(e)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    case e
         
     | 
| 
      
 128 
     | 
    
         
            +
                    when *Util::HTTP::ERRORS
         
     | 
| 
      
 129 
     | 
    
         
            +
                      say(<<-MSG, :red)
         
     | 
| 
      
 130 
     | 
    
         
            +
            !! --- Failed to notify Honeybadger ------------------------------------------- !!
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            # What happened?
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
              We encountered an HTTP error while contacting our service. Issues like this are
         
     | 
| 
      
 135 
     | 
    
         
            +
              usually temporary.
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            # Error details
         
     | 
| 
       118 
138 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 139 
     | 
    
         
            +
              #{e.class}: #{e.message}\n    at #{e.backtrace && e.backtrace.first}
         
     | 
| 
       120 
140 
     | 
    
         | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
         
     | 
| 
       123 
     | 
    
         
            -
                    ENV['HONEYBADGER_LOGGING_PATH']      = 'STDOUT'
         
     | 
| 
       124 
     | 
    
         
            -
                    ENV['HONEYBADGER_REPORT_DATA']       = 'true'
         
     | 
| 
      
 141 
     | 
    
         
            +
            # What can I do?
         
     | 
| 
       125 
142 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
      
 143 
     | 
    
         
            +
              - Retry the command.
         
     | 
| 
      
 144 
     | 
    
         
            +
              - Make sure you can connect to api.honeybadger.io (`ping api.honeybadger.io`).
         
     | 
| 
      
 145 
     | 
    
         
            +
              - If you continue to see this message, email us at support@honeybadger.io
         
     | 
| 
      
 146 
     | 
    
         
            +
                (don't forget to attach this output!)
         
     | 
| 
       128 
147 
     | 
    
         | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
      
 148 
     | 
    
         
            +
            !! --- End -------------------------------------------------------------------- !!
         
     | 
| 
      
 149 
     | 
    
         
            +
            MSG
         
     | 
| 
       131 
150 
     | 
    
         
             
                    else
         
     | 
| 
       132 
     | 
    
         
            -
                      say( 
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
                      begin
         
     | 
| 
       135 
     | 
    
         
            -
                        config.write
         
     | 
| 
       136 
     | 
    
         
            -
                      rescue Config::ConfigError => e
         
     | 
| 
       137 
     | 
    
         
            -
                        error("Error: Unable to write configuration file:\n\t#{e}")
         
     | 
| 
       138 
     | 
    
         
            -
                        return
         
     | 
| 
       139 
     | 
    
         
            -
                      rescue StandardError => e
         
     | 
| 
       140 
     | 
    
         
            -
                        error("Error: Unable to write configuration file:\n\t#{e.class} -- #{e.message}\n\t#{e.backtrace.join("\n\t")}")
         
     | 
| 
       141 
     | 
    
         
            -
                        return
         
     | 
| 
       142 
     | 
    
         
            -
                      end
         
     | 
| 
       143 
     | 
    
         
            -
                    end
         
     | 
| 
      
 151 
     | 
    
         
            +
                      say(<<-MSG, :red)
         
     | 
| 
      
 152 
     | 
    
         
            +
            !! --- Honeybadger command failed --------------------------------------------- !!
         
     | 
| 
       144 
153 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                      if capfile.read.match(/honeybadger/)
         
     | 
| 
       147 
     | 
    
         
            -
                        say("Detected Honeybadger in Capfile; skipping Capistrano installation.", :yellow)
         
     | 
| 
       148 
     | 
    
         
            -
                      else
         
     | 
| 
       149 
     | 
    
         
            -
                        say("Appending Capistrano tasks to: #{capfile}", :yellow)
         
     | 
| 
       150 
     | 
    
         
            -
                        File.open(capfile, 'a') do |f|
         
     | 
| 
       151 
     | 
    
         
            -
                          f.puts("\nrequire 'capistrano/honeybadger'")
         
     | 
| 
       152 
     | 
    
         
            -
                        end
         
     | 
| 
       153 
     | 
    
         
            -
                      end
         
     | 
| 
       154 
     | 
    
         
            -
                    end
         
     | 
| 
      
 154 
     | 
    
         
            +
            # What did you try to do?
         
     | 
| 
       155 
155 
     | 
    
         | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
                      say('Sending test notice', :yellow)
         
     | 
| 
       159 
     | 
    
         
            -
                      unless Agent.instance && send_test(false)
         
     | 
| 
       160 
     | 
    
         
            -
                        say('Honeybadger is installed, but failed to send a test notice. Try `honeybadger test`.', :red)
         
     | 
| 
       161 
     | 
    
         
            -
                        exit(1)
         
     | 
| 
       162 
     | 
    
         
            -
                      end
         
     | 
| 
       163 
     | 
    
         
            -
                    end
         
     | 
| 
      
 156 
     | 
    
         
            +
              You tried to execute the following command:
         
     | 
| 
      
 157 
     | 
    
         
            +
              `honeybadger #{ARGV.join(' ')}`
         
     | 
| 
       164 
158 
     | 
    
         | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
            # What actually happend?
         
     | 
| 
       167 
160 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
                  subcommand 'heroku', Heroku
         
     | 
| 
      
 161 
     | 
    
         
            +
              We encountered a Ruby exception and were forced to cancel your request.
         
     | 
| 
       170 
162 
     | 
    
         | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
      
 163 
     | 
    
         
            +
            # Error details
         
     | 
| 
       172 
164 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
                        say(indent + "Type: #{Config::OPTIONS[dotted_key].fetch(:type, String).name.split('::').last}")
         
     | 
| 
       184 
     | 
    
         
            -
                        say(indent + "Default: #{Config::OPTIONS[dotted_key][:default].inspect}")
         
     | 
| 
       185 
     | 
    
         
            -
                        say(indent + "Current: #{value.inspect}")
         
     | 
| 
       186 
     | 
    
         
            -
                      end
         
     | 
| 
       187 
     | 
    
         
            -
                    end
         
     | 
| 
       188 
     | 
    
         
            -
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
              #{e.class}: #{e.message}
         
     | 
| 
      
 166 
     | 
    
         
            +
                #{e.backtrace && e.backtrace.join("\n    ")}
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
            # What can I do?
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
              - If you're calling the `install` or `test` command in a Rails app, make sure
         
     | 
| 
      
 171 
     | 
    
         
            +
                you can boot the Rails console: `bundle exec rails console`.
         
     | 
| 
      
 172 
     | 
    
         
            +
              - Retry the command.
         
     | 
| 
      
 173 
     | 
    
         
            +
              - If you continue to see this message, email us at support@honeybadger.io
         
     | 
| 
      
 174 
     | 
    
         
            +
                (don't forget to attach this output!)
         
     | 
| 
       189 
175 
     | 
    
         | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                      number.times { s << "\s\s" }
         
     | 
| 
      
 176 
     | 
    
         
            +
            !! --- End -------------------------------------------------------------------- !!
         
     | 
| 
      
 177 
     | 
    
         
            +
            MSG
         
     | 
| 
       193 
178 
     | 
    
         
             
                    end
         
     | 
| 
       194 
179 
     | 
    
         
             
                  end
         
     | 
| 
       195 
180 
     | 
    
         
             
                end
         
     |