airbrake 4.3.8 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake/capistrano/tasks.rb +64 -0
  3. data/lib/airbrake/delayed_job/plugin.rb +48 -0
  4. data/lib/airbrake/rack/middleware.rb +45 -0
  5. data/lib/airbrake/rack/notice_builder.rb +80 -0
  6. data/lib/airbrake/rack/user.rb +51 -0
  7. data/lib/airbrake/rails/action_controller.rb +35 -0
  8. data/lib/airbrake/rails/active_job.rb +23 -0
  9. data/lib/airbrake/rails/active_record.rb +40 -0
  10. data/lib/airbrake/rails/railtie.rb +61 -0
  11. data/lib/airbrake/rake/task_ext.rb +61 -0
  12. data/lib/airbrake/rake/tasks.rb +93 -0
  13. data/lib/airbrake/resque/failure.rb +19 -0
  14. data/lib/airbrake/sidekiq/error_handler.rb +35 -0
  15. data/lib/airbrake/version.rb +4 -1
  16. data/lib/airbrake.rb +16 -185
  17. data/lib/generators/airbrake_generator.rb +25 -0
  18. data/lib/generators/airbrake_initializer.rb.erb +55 -0
  19. data/spec/airbrake_spec.rb +0 -0
  20. data/spec/apps/rack/dummy_app.rb +17 -0
  21. data/spec/apps/rails/dummy_app.rb +150 -0
  22. data/spec/apps/rails/dummy_task.rake +20 -0
  23. data/spec/apps/rails/logs/32.log +13358 -0
  24. data/spec/apps/rails/logs/40.log +6854 -0
  25. data/spec/apps/rails/logs/41.log +3170 -0
  26. data/spec/apps/rails/logs/42.log +23919 -0
  27. data/spec/apps/rails/logs/50.log +10976 -0
  28. data/spec/apps/sinatra/dummy_app.rb +12 -0
  29. data/spec/integration/rack/rack_spec.rb +17 -0
  30. data/spec/integration/rails/rails_spec.rb +135 -0
  31. data/spec/integration/rails/rake_spec.rb +160 -0
  32. data/spec/integration/shared_examples/rack_examples.rb +106 -0
  33. data/spec/integration/sinatra/sinatra_spec.rb +15 -0
  34. data/spec/spec_helper.rb +127 -0
  35. data/spec/unit/rack/middleware_spec.rb +80 -0
  36. data/spec/unit/rack/notice_builder_spec.rb +35 -0
  37. data/spec/unit/rack/user_spec.rb +78 -0
  38. data/spec/unit/rake/tasks_spec.rb +40 -0
  39. data/spec/unit/sidekiq/error_handler_spec.rb +29 -0
  40. metadata +108 -323
  41. data/CHANGELOG +0 -1716
  42. data/Gemfile +0 -3
  43. data/Guardfile +0 -6
  44. data/INSTALL +0 -20
  45. data/LICENSE +0 -61
  46. data/README.md +0 -148
  47. data/README_FOR_HEROKU_ADDON.md +0 -102
  48. data/Rakefile +0 -179
  49. data/TESTED_AGAINST +0 -7
  50. data/airbrake.gemspec +0 -41
  51. data/bin/airbrake +0 -12
  52. data/features/metal.feature +0 -34
  53. data/features/rack.feature +0 -60
  54. data/features/rails.feature +0 -324
  55. data/features/rake.feature +0 -33
  56. data/features/sinatra.feature +0 -126
  57. data/features/step_definitions/file_steps.rb +0 -14
  58. data/features/step_definitions/rack_steps.rb +0 -27
  59. data/features/step_definitions/rails_application_steps.rb +0 -267
  60. data/features/step_definitions/rake_steps.rb +0 -22
  61. data/features/support/airbrake_shim.rb.template +0 -11
  62. data/features/support/aruba.rb +0 -5
  63. data/features/support/env.rb +0 -39
  64. data/features/support/matchers.rb +0 -35
  65. data/features/support/rails.rb +0 -156
  66. data/features/support/rake/Rakefile +0 -77
  67. data/features/user_informer.feature +0 -57
  68. data/generators/airbrake/airbrake_generator.rb +0 -94
  69. data/generators/airbrake/lib/insert_commands.rb +0 -34
  70. data/generators/airbrake/lib/rake_commands.rb +0 -24
  71. data/generators/airbrake/templates/airbrake_tasks.rake +0 -25
  72. data/generators/airbrake/templates/capistrano_hook.rb +0 -6
  73. data/generators/airbrake/templates/initializer.rb +0 -4
  74. data/install.rb +0 -1
  75. data/lib/airbrake/backtrace.rb +0 -103
  76. data/lib/airbrake/capistrano.rb +0 -103
  77. data/lib/airbrake/capistrano3.rb +0 -3
  78. data/lib/airbrake/cli/client.rb +0 -76
  79. data/lib/airbrake/cli/options.rb +0 -45
  80. data/lib/airbrake/cli/printer.rb +0 -33
  81. data/lib/airbrake/cli/project.rb +0 -17
  82. data/lib/airbrake/cli/project_factory.rb +0 -33
  83. data/lib/airbrake/cli/runner.rb +0 -49
  84. data/lib/airbrake/cli/validator.rb +0 -8
  85. data/lib/airbrake/configuration.rb +0 -366
  86. data/lib/airbrake/jobs/send_job.rb +0 -7
  87. data/lib/airbrake/notice.rb +0 -411
  88. data/lib/airbrake/rack.rb +0 -64
  89. data/lib/airbrake/rails/action_controller_catcher.rb +0 -32
  90. data/lib/airbrake/rails/controller_methods.rb +0 -146
  91. data/lib/airbrake/rails/error_lookup.rb +0 -35
  92. data/lib/airbrake/rails/middleware.rb +0 -63
  93. data/lib/airbrake/rails.rb +0 -45
  94. data/lib/airbrake/rails3_tasks.rb +0 -126
  95. data/lib/airbrake/railtie.rb +0 -46
  96. data/lib/airbrake/rake_handler.rb +0 -75
  97. data/lib/airbrake/response.rb +0 -29
  98. data/lib/airbrake/sender.rb +0 -213
  99. data/lib/airbrake/shared_tasks.rb +0 -59
  100. data/lib/airbrake/sidekiq.rb +0 -8
  101. data/lib/airbrake/sinatra.rb +0 -40
  102. data/lib/airbrake/tasks/airbrake.cap +0 -28
  103. data/lib/airbrake/tasks.rb +0 -81
  104. data/lib/airbrake/user_informer.rb +0 -36
  105. data/lib/airbrake/utils/params_cleaner.rb +0 -141
  106. data/lib/airbrake/utils/rack_filters.rb +0 -45
  107. data/lib/airbrake_tasks.rb +0 -62
  108. data/lib/rails/generators/airbrake/airbrake_generator.rb +0 -155
  109. data/lib/templates/rescue.erb +0 -91
  110. data/rails/init.rb +0 -1
  111. data/resources/README.md +0 -34
  112. data/resources/airbrake_2_4.xsd +0 -89
  113. data/resources/airbrake_3_0.json +0 -52
  114. data/resources/ca-bundle.crt +0 -3376
  115. data/script/integration_test.rb +0 -35
  116. data/test/airbrake_tasks_test.rb +0 -161
  117. data/test/backtrace_test.rb +0 -215
  118. data/test/capistrano_test.rb +0 -44
  119. data/test/configuration_test.rb +0 -303
  120. data/test/controller_methods_test.rb +0 -230
  121. data/test/helper.rb +0 -233
  122. data/test/integration/catcher_test.rb +0 -371
  123. data/test/integration.rb +0 -13
  124. data/test/logger_test.rb +0 -79
  125. data/test/notice_test.rb +0 -494
  126. data/test/notifier_test.rb +0 -288
  127. data/test/params_cleaner_test.rb +0 -204
  128. data/test/rack_test.rb +0 -62
  129. data/test/rails_initializer_test.rb +0 -36
  130. data/test/recursion_test.rb +0 -10
  131. data/test/response_test.rb +0 -18
  132. data/test/sender_test.rb +0 -335
  133. data/test/support/response_shim.xml +0 -4
  134. data/test/user_informer_test.rb +0 -29
@@ -1,94 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
2
- require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
3
-
4
- class AirbrakeGenerator < Rails::Generator::Base
5
- def add_options!(opt)
6
- opt.on('-k', '--api-key=key', String, "Your Airbrake API key") { |v| options[:api_key] = v}
7
- opt.on('-h', '--heroku', "Use the Heroku addon to provide your Airbrake API key") { |v| options[:heroku] = v}
8
- opt.on('-a', '--app=myapp', String, "Your Heroku app name (only required if deploying to >1 Heroku app)") { |v| options[:app] = v}
9
- end
10
-
11
- def manifest
12
- if !api_key_configured? && !options[:api_key] && !options[:heroku]
13
- puts "Must pass --api-key or --heroku or create config/initializers/airbrake.rb"
14
- exit
15
- end
16
- if plugin_is_present?
17
- puts "You must first remove the airbrake plugin. Please run: script/plugin remove airbrake"
18
- exit
19
- end
20
- record do |m|
21
- m.directory 'lib/tasks'
22
- m.file 'airbrake_tasks.rake', 'lib/tasks/airbrake_tasks.rake'
23
- if ['config/deploy.rb', 'Capfile'].all? { |file| File.exists?(file) }
24
- m.append_to 'config/deploy.rb', capistrano_hook
25
- end
26
- if api_key_expression
27
- if use_initializer?
28
- m.template 'initializer.rb', 'config/initializers/airbrake.rb',
29
- :assigns => {:api_key => api_key_expression}
30
- else
31
- m.template 'initializer.rb', 'config/airbrake.rb',
32
- :assigns => {:api_key => api_key_expression}
33
- m.append_to 'config/environment.rb', "require 'config/airbrake'"
34
- end
35
- end
36
- determine_api_key if heroku?
37
- m.rake "airbrake:test", :generate_only => true
38
- end
39
- end
40
-
41
- def api_key_expression
42
- s = if options[:api_key]
43
- "'#{options[:api_key]}'"
44
- elsif options[:heroku]
45
- "ENV['HOPTOAD_API_KEY']"
46
- end
47
- end
48
-
49
- def determine_api_key
50
- puts "Attempting to determine your API Key from Heroku..."
51
- ENV['HOPTOAD_API_KEY'] = heroku_api_key
52
- if ENV['HOPTOAD_API_KEY'] =~ /\S/
53
- puts "... Done."
54
- puts "Heroku's Airbrake API Key is '#{ENV['HOPTOAD_API_KEY']}'"
55
- else
56
- puts "... Failed."
57
- puts "WARNING: We were unable to detect the Airbrake API Key from your Heroku environment."
58
- puts "Your Heroku application environment may not be configured correctly."
59
- exit 1
60
- end
61
- end
62
-
63
- def heroku_var(var,app_name = nil)
64
- app = app_name ? "--app #{app_name}" : ''
65
- `heroku config #{app} | grep -E "#{var.upcase}" | awk '{ print $3; }'`.strip
66
- end
67
-
68
- def heroku_api_key
69
- heroku_var("(hoptoad|airbrake)_api_key",options[:app]).split.find {|x| x =~ /\S/ }
70
- end
71
-
72
- def heroku?
73
- options[:heroku] ||
74
- system("grep HOPTOAD_API_KEY config/initializers/airbrake.rb") ||
75
- system("grep HOPTOAD_API_KEY config/environment.rb")
76
- end
77
-
78
- def use_initializer?
79
- ::Rails::VERSION::MAJOR > 1
80
- end
81
-
82
- def api_key_configured?
83
- File.exists?('config/initializers/airbrake.rb') ||
84
- system("grep Airbrake config/environment.rb")
85
- end
86
-
87
- def capistrano_hook
88
- IO.read(source_path('capistrano_hook.rb'))
89
- end
90
-
91
- def plugin_is_present?
92
- File.exists?('vendor/plugins/airbrake')
93
- end
94
- end
@@ -1,34 +0,0 @@
1
- # Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
2
-
3
- Rails::Generator::Commands::Base.class_eval do
4
- def file_contains?(relative_destination, line)
5
- File.read(destination_path(relative_destination)).include?(line)
6
- end
7
- end
8
-
9
- Rails::Generator::Commands::Create.class_eval do
10
- def append_to(file, line)
11
- logger.insert "#{line} appended to #{file}"
12
- unless options[:pretend] || file_contains?(file, line)
13
- File.open(file, "a") do |file|
14
- file.puts
15
- file.puts line
16
- end
17
- end
18
- end
19
- end
20
-
21
- Rails::Generator::Commands::Destroy.class_eval do
22
- def append_to(file, line)
23
- logger.remove "#{line} removed from #{file}"
24
- unless options[:pretend]
25
- gsub_file file, "\n#{line}", ''
26
- end
27
- end
28
- end
29
-
30
- Rails::Generator::Commands::List.class_eval do
31
- def append_to(file, line)
32
- logger.insert "#{line} appended to #{file}"
33
- end
34
- end
@@ -1,24 +0,0 @@
1
- Rails::Generator::Commands::Create.class_eval do
2
- def rake(cmd, opts = {})
3
- logger.rake "rake #{cmd}"
4
- unless system("rake #{cmd}")
5
- logger.rake "#{cmd} failed. Rolling back"
6
- command(:destroy).invoke!
7
- end
8
- end
9
- end
10
-
11
- Rails::Generator::Commands::Destroy.class_eval do
12
- def rake(cmd, opts = {})
13
- unless opts[:generate_only]
14
- logger.rake "rake #{cmd}"
15
- system "rake #{cmd}"
16
- end
17
- end
18
- end
19
-
20
- Rails::Generator::Commands::List.class_eval do
21
- def rake(cmd, opts = {})
22
- logger.rake "rake #{cmd}"
23
- end
24
- end
@@ -1,25 +0,0 @@
1
- # Don't load anything when running the gems:* tasks.
2
- # Otherwise, airbrake will be considered a framework gem.
3
- # https://thoughtbot.lighthouseapp.com/projects/14221/tickets/629
4
- unless ARGV.any? {|a| a =~ /^gems/}
5
-
6
- Dir[File.join(Rails.root, 'vendor', 'gems', 'airbrake-*')].each do |vendored_notifier|
7
- $: << File.join(vendored_notifier, 'lib')
8
- end
9
-
10
- begin
11
- require 'airbrake/tasks'
12
- rescue LoadError => exception
13
- namespace :airbrake do
14
- %w(deploy test log_stdout).each do |task_name|
15
- desc "Missing dependency for airbrake:#{task_name}"
16
- task task_name do
17
- $stderr.puts "Failed to run airbrake:#{task_name} because of missing dependency."
18
- $stderr.puts "You probably need to run `rake gems:install` to install the airbrake gem"
19
- abort exception.inspect
20
- end
21
- end
22
- end
23
- end
24
-
25
- end
@@ -1,6 +0,0 @@
1
-
2
- Dir[File.join(File.dirname(__FILE__), '..', 'vendor', 'gems', 'airbrake-*')].each do |vendored_notifier|
3
- $: << File.join(vendored_notifier, 'lib')
4
- end
5
-
6
- require 'airbrake/capistrano'
@@ -1,4 +0,0 @@
1
- <% if ::Rails::VERSION::MAJOR < 3 && ::Rails::VERSION::MINOR < 2 -%>
2
- require 'airbrake/rails'
3
- <% end -%>
4
- <%= configuration_output %>
data/install.rb DELETED
@@ -1 +0,0 @@
1
- puts IO.read(File.join(File.dirname(__FILE__), 'INSTALL'))
@@ -1,103 +0,0 @@
1
- module Airbrake
2
- # Front end to parsing the backtrace for each notice
3
- class Backtrace
4
-
5
- # Handles backtrace parsing line by line
6
- class Line
7
-
8
- # regexp (optionnally allowing leading X: for windows support)
9
- INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$}.freeze
10
-
11
- # The file portion of the line (such as app/models/user.rb)
12
- attr_reader :file
13
-
14
- # The line number portion of the line
15
- attr_reader :number
16
-
17
- # The method_name of the line (such as index)
18
- attr_reader :method_name
19
-
20
- # Parses a single line of a given backtrace
21
- # @param [String] unparsed_line The raw line from +caller+ or some backtrace
22
- # @return [Line] The parsed backtrace line
23
- def self.parse(unparsed_line)
24
- _, file, number, method_name = unparsed_line.match(INPUT_FORMAT).to_a
25
- new(file, number, method_name)
26
- end
27
-
28
- def initialize(file, number, method_name)
29
- @file = file
30
- @number = number
31
- @method_name = method_name
32
- end
33
-
34
- # Reconstructs the line in a readable fashion
35
- def to_s
36
- "#{file}:#{number}:in `#{method_name}'"
37
- end
38
-
39
- def ==(other)
40
- to_s == other.to_s
41
- end
42
-
43
- def inspect
44
- "<Line:#{to_s}>"
45
- end
46
- end
47
-
48
- # holder for an Array of Backtrace::Line instances
49
- attr_reader :lines
50
-
51
- def self.parse(ruby_backtrace, opts = {})
52
- ruby_lines = split_multiline_backtrace(ruby_backtrace)
53
-
54
- filters = opts[:filters] || []
55
- filtered_lines = ruby_lines.to_a.map do |line|
56
- filters.inject(line) do |l, proc|
57
- proc.call(l)
58
- end
59
- end.compact
60
-
61
- lines = filtered_lines.collect do |unparsed_line|
62
- Line.parse(unparsed_line)
63
- end
64
-
65
- new(lines)
66
- end
67
-
68
- def initialize(lines)
69
- @lines = lines
70
- end
71
-
72
- def inspect
73
- "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
74
- end
75
-
76
- def to_s
77
- content = []
78
- lines.each do |line|
79
- content << line
80
- end
81
- content.join("\n")
82
- end
83
-
84
- def ==(other)
85
- if other.respond_to?(:lines)
86
- lines == other.lines
87
- else
88
- false
89
- end
90
- end
91
-
92
- private
93
-
94
- def self.split_multiline_backtrace(backtrace)
95
- backtrace = [backtrace] unless backtrace.respond_to?(:to_a)
96
- if backtrace.to_a.size == 1
97
- backtrace.to_a.first.split(/\n\s*/)
98
- else
99
- backtrace
100
- end
101
- end
102
- end
103
- end
@@ -1,103 +0,0 @@
1
- # Defines deploy:notify_airbrake which will send information about the deploy to Airbrake.
2
- require 'capistrano'
3
-
4
- module Airbrake
5
- module Capistrano
6
- # What follows is a copy-paste backport of the shellescape method
7
- # included in Ruby 1.9 and greater. The FSF's guidance on a snippet
8
- # of this size indicates that such a small function is not subject
9
- # to copyright and as such there is no risk of a license conflict:
10
- # See www.gnu.org/prep/maintain/maintain.html#Legally-Significant
11
- #
12
- # Escapes a string so that it can be safely used in a Bourne shell
13
- # command line. +str+ can be a non-string object that responds to
14
- # +to_s+.
15
- #
16
- # Note that a resulted string should be used unquoted and is not
17
- # intended for use in double quotes nor in single quotes.
18
- #
19
- # argv = Shellwords.escape("It's better to give than to receive")
20
- # argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
21
- #
22
- # String#shellescape is a shorthand for this function.
23
- #
24
- # argv = "It's better to give than to receive".shellescape
25
- # argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
26
- #
27
- # # Search files in lib for method definitions
28
- # pattern = "^[ \t]*def "
29
- # open("| grep -Ern #{pattern.shellescape} lib") { |grep|
30
- # grep.each_line { |line|
31
- # file, lineno, matched_line = line.split(':', 3)
32
- # # ...
33
- # }
34
- # }
35
- #
36
- # It is the caller's responsibility to encode the string in the right
37
- # encoding for the shell environment where this string is used.
38
- #
39
- # Multibyte characters are treated as multibyte characters, not bytes.
40
- #
41
- # Returns an empty quoted String if +str+ has a length of zero.
42
- def self.shellescape(str)
43
- str = str.to_s
44
-
45
- # An empty argument will be skipped, so return empty quotes.
46
- return "''" if str.empty?
47
-
48
- str = str.dup
49
-
50
- # Treat multibyte characters as is. It is caller's responsibility
51
- # to encode the string in the right encoding for the shell
52
- # environment.
53
- str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1")
54
-
55
- # A LF cannot be escaped with a backslash because a backslash + LF
56
- # combo is regarded as line continuation and simply ignored.
57
- str.gsub!(/\n/, "'\n'")
58
-
59
- return str
60
- end
61
-
62
- def self.load_into(configuration)
63
- configuration.load do
64
- after "deploy", "airbrake:deploy"
65
- after "deploy:migrations", "airbrake:deploy"
66
- after "deploy:cold", "airbrake:deploy"
67
-
68
- namespace :airbrake do
69
- desc <<-DESC
70
- Notify Airbrake of the deployment by running the notification on the REMOTE machine.
71
- - Run remotely so we use remote API keys, environment, etc.
72
- DESC
73
- task :deploy, :except => { :no_release => true } do
74
- rack_env = fetch(:rack_env, nil)
75
- rails_env = fetch(:rails_env, nil)
76
- airbrake_env = fetch(:airbrake_env, rack_env || rails_env || "production")
77
- local_user = ENV['USER'] || ENV['USERNAME']
78
- executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, 'rake.bat') : fetch(:rake, 'bundle exec rake ')
79
- directory = configuration.release_path
80
- notify_command = "cd #{directory}; #{executable}"
81
- notify_command << " RACK_ENV=#{rack_env}" if rack_env
82
- notify_command << " RAILS_ENV=#{rails_env}" if rails_env
83
- notify_command << " airbrake:deploy TO=#{airbrake_env} REVISION=#{current_revision} REPO=#{repository} USER=#{Airbrake::Capistrano::shellescape(local_user)}"
84
- notify_command << " DRY_RUN=true" if dry_run
85
- logger.info "Notifying Airbrake of Deploy (#{notify_command})"
86
- if configuration.dry_run
87
- logger.info "DRY RUN: Notification not actually run."
88
- else
89
- result = ""
90
- run(notify_command, :once => true) { |ch, stream, data| result << data }
91
- # TODO: Check if SSL is active on account via result content.
92
- end
93
- logger.info "Airbrake Notification Complete."
94
- end
95
- end
96
- end
97
- end
98
- end
99
- end
100
-
101
- if Capistrano::Configuration.instance
102
- Airbrake::Capistrano.load_into(Capistrano::Configuration.instance)
103
- end
@@ -1,3 +0,0 @@
1
- # Defines airbrake:deploy which will send information about the deploy to Airbrake.
2
-
3
- load File.expand_path("../tasks/airbrake.cap", __FILE__)
@@ -1,76 +0,0 @@
1
- require File.expand_path( "../runner", __FILE__)
2
-
3
- module Client
4
- extend self
5
-
6
- def options
7
- Runner.options
8
- end
9
-
10
- def fetch_projects
11
- uri = URI.parse "http://#{options.account}.airbrake.io"\
12
- "/data_api/v1/projects.xml?auth_token=#{options.auth_token}"
13
- http = Net::HTTP.new(uri.host,uri.port)
14
- request = Net::HTTP::Get.new(uri.request_uri)
15
- response = http.request(request)
16
- response.body
17
- end
18
-
19
- def create_project
20
- uri = URI.parse "http://#{options.account}.airbrake.io"\
21
- "/data_api/v1/projects.xml"
22
- http = Net::HTTP.new(uri.host,uri.port)
23
- request = Net::HTTP::Post.new(uri.request_uri)
24
- request.set_form_data('project[name]' => options.name,'auth_token' => options.auth_token)
25
- response = http.request(request)
26
- response.body
27
-
28
- print_project_response(response.body)
29
- end
30
-
31
- def create_deploy
32
- uri = URI.parse "http://airbrake.io/deploys.txt"
33
- http = Net::HTTP.new(uri.host,uri.port)
34
- request = Net::HTTP::Post.new(uri.request_uri)
35
- opts = { 'api_key' => options.api_key }.merge!(deploy_opts)
36
- request.set_form_data(opts)
37
- response = http.request(request)
38
- puts response.message if response.respond_to?(:message)
39
- end
40
-
41
- def deploy_opts
42
- opts = {}
43
- ['rails_env', 'scm_revision', 'scm_repository', 'local_username'].each do |attr|
44
- opts.merge!("deploy[#{attr}]" => options.send(attr))
45
- end
46
- opts
47
- end
48
-
49
- def print_projects
50
- factory = ProjectFactory.new
51
- projects = fetch_projects
52
- factory.create_projects_from_xml(projects)
53
- abort "No projects were fetched. Did you provide the correct auth token?" if projects.match(/error/m)
54
- puts "\nProjects\n" + "".rjust(63,"#")
55
- factory.projects.each do |project|
56
- puts project
57
- end
58
- puts
59
- end
60
-
61
- def print_project_response(response)
62
- case response
63
- when /errors/
64
- puts "Error creating project: #{response.gsub("\n","").scan(/.*<error[^>]*>(.*?)<\/error>.*/).last.first.gsub(/\s{1,}/," ")}"
65
- when /project/
66
- project = Project.new(:id => response[/<id[^>]*>(.*?)<\/id>/,1],
67
- :name => response[/<name[^>]*>(.*?)<\/name>/,1],
68
- :api_key => response[/<api-key[^>]*>(.*?)<\/api-key>/,1])
69
- puts "\nProject details\n" + "".rjust(63,"#")
70
- puts project
71
- else
72
- puts "Unexpected error. Please try again!\n"
73
- puts response
74
- end
75
- end
76
- end
@@ -1,45 +0,0 @@
1
- class Options
2
-
3
- ATTRIBUTES = [:error, :message, :api_key, :host, :port, :auth_token, :name,
4
- :account, :rails_env, :scm_revision, :scm_repository, :local_username]
5
-
6
- ATTRIBUTES.each do |attribute|
7
- attr_reader attribute
8
- end
9
-
10
- private
11
-
12
- # You should not write to this from outside
13
- ATTRIBUTES.each do |attribute|
14
- attr_writer attribute
15
- end
16
-
17
- public
18
-
19
- # Parses all the options passed and stores them in attributes
20
- def initialize(array = [])
21
- opts = Hash[*array]
22
- self.error = opts.delete("-e") || opts.delete("--error") { RuntimeError }
23
- self.message = opts.delete("-m") || opts.delete("--message") { "I've made a huge mistake" }
24
- self.api_key = opts.delete("-k") || opts.delete("--api-key") || config_from_file.api_key || ENV["AIRBRAKE_API_KEY"]
25
- self.host = opts.delete("-h") || opts.delete("--host") || config_from_file.host
26
- self.port = opts.delete("-p") || opts.delete("--port") || config_from_file.port
27
- self.auth_token = opts.delete("-t") || opts.delete("--auth-token") || ENV["AIRBRAKE_AUTH_TOKEN"]
28
- self.name = opts.delete("-n") || opts.delete("--name")
29
- self.account = opts.delete("-a") || opts.delete("--account") || ENV["AIRBRAKE_ACCOUNT"]
30
- self.rails_env = opts.delete("-E") || opts.delete("--rails-env") || ENV["RAILS_ENV"] || "production"
31
- self.scm_revision = opts.delete("-r") || opts.delete("--scm-revision") || ENV["REVISION"]
32
- self.scm_repository = opts.delete("-R") || opts.delete("--scm-repository") || ENV["REPO"]
33
- self.local_username = opts.delete("-u") || opts.delete("--local-username") || ENV["USER"]
34
- opts
35
- end
36
-
37
- # Fallback to read from the initializer
38
- def config_from_file
39
- begin
40
- load "config/initializers/airbrake.rb"
41
- rescue LoadError
42
- end
43
- Airbrake.configuration
44
- end
45
- end
@@ -1,33 +0,0 @@
1
- module Printer
2
- def self.print(collection)
3
- collection.each do |element|
4
- puts element
5
- end
6
- end
7
-
8
- def self.print_usage
9
- puts <<-USAGE
10
- Usage: airbrake [COMMAND] [OPTION]...
11
- Commands:
12
- raise # Raise an exception specified by ERROR and MESSAGE.
13
- list # List all the projects for given AUTH_TOKEN and ACCOUNT.
14
- create # Create a project with the given NAME.
15
- deploy # Send a new deployment notification to a project that matches the API_KEY.
16
-
17
- Options:
18
- -e, [--error=ERROR] # Error class to raise. Default: RuntimeError
19
- -m, [--message=MESSAGE] # Error message. Default: "I've made a huge mistake"
20
- -k, [--api-key=API_KEY] # Api key of your Airbrake application
21
- -h, [--host=HOST] # URL of the Airbrake API server. Default: api.airbrake.io
22
- -p, [--port=PORT] # Port of the Airbrake API server. Default: 80
23
- -t, [--auth-token=AUTH_TOKEN] # The auth token used for API requests
24
- -a, [--account=ACCOUNT] # The account used for API requests
25
- -n, [--name=NAME] # The name of the project you're trying to create
26
- -E, [--rails-env=NAME] # The name of the environment you're deploying to. Default: production
27
- -r, [--scm-revision=REVISION] # SCM revision for deployment info
28
- -R, [--scm-repository=REPO] # SCM repository for deployment info
29
- -u, [--local-username=USER] # The name of the user who is deploying
30
- -h, [--help] # Show this usage
31
- USAGE
32
- end
33
- end
@@ -1,17 +0,0 @@
1
- class Project
2
- attr_writer :name, :id, :api_key
3
-
4
- def initialize(attributes = {})
5
- attributes.keys.each do |key|
6
- instance_variable_set("@#{key}",attributes[key])
7
- end
8
- end
9
-
10
- def to_s
11
- "#{@name}".rjust(20) + "(#{@id}):".rjust(10) + " #{@api_key}"
12
- end
13
-
14
- def valid?
15
- @name && @id && @api_key
16
- end
17
- end
@@ -1,33 +0,0 @@
1
- require File.expand_path( "../project", __FILE__)
2
- # Responsible for creating projects when needed.
3
- # Creates them from XML received.
4
- class ProjectFactory
5
- attr_reader :project, :projects
6
-
7
- def initialize
8
- @project = Project.new
9
- @projects = []
10
- end
11
-
12
- def create_projects_from_xml(xml)
13
- xml.split("\n").each do |line|
14
- /<name[^>]*>(.*)<\/name>/ =~ line
15
- name = $1
16
- project.name = name.capitalize if name
17
- /<id[^>]*>(.*)<\/id>/ =~ line
18
- id = $1
19
- project.id = id if id
20
- /<api-key[^>]*>(.*)<\/api-key>/ =~ line
21
- api_key = $1
22
- project.api_key = api_key if api_key
23
- check_project
24
- end
25
- end
26
-
27
- def check_project
28
- if @project.valid?
29
- projects << @project
30
- @project = Project.new
31
- end
32
- end
33
- end
@@ -1,49 +0,0 @@
1
- require File.expand_path( "../project_factory", __FILE__)
2
- require File.expand_path( "../options", __FILE__)
3
- require File.expand_path( "../validator", __FILE__)
4
- require File.expand_path( "../printer", __FILE__)
5
- require File.expand_path( "../client", __FILE__)
6
-
7
- module Runner
8
- extend Validator
9
-
10
- extend self
11
-
12
- attr_accessor :options
13
-
14
- def run!(command, cli_options = {})
15
-
16
- self.options = Options.new(cli_options)
17
-
18
- case command
19
- when 'raise'
20
- validates :api_key
21
- Airbrake.configure do |c|
22
- c.api_key = options.api_key
23
- c.host = options.host if options.host
24
- c.port = options.port if options.port
25
- c.secure = options.port.to_i == 443
26
- end
27
- exception_id = Airbrake.notify(:error_class => options.error,
28
- :error_message => "#{options.error}: #{options.message}",
29
- :cgi_data => ENV)
30
- abort "Error sending exception to Airbrake server. Try again later." unless exception_id
31
- puts "Exception sent successfully: http://airbrake.io/locate/#{exception_id}"
32
-
33
- when "list"
34
- validates :auth_token, :account
35
- Client.print_projects
36
-
37
- when "create"
38
- validates :auth_token, :account
39
- Client.create_project
40
-
41
- when "deploy"
42
- validates :api_key
43
- Client.create_deploy
44
-
45
- else
46
- Printer.print_usage
47
- end
48
- end
49
- end
@@ -1,8 +0,0 @@
1
- module Validator
2
- def validates(*attributes)
3
- attributes.each do |attribute|
4
- abort "You didn't provide #{attribute.to_s.upcase}"\
5
- " so no API request was made." unless Runner.options.send(attribute)
6
- end
7
- end
8
- end