airbrake 4.3.8 → 5.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake.rb +16 -185
  3. data/lib/airbrake/capistrano/tasks.rb +64 -0
  4. data/lib/airbrake/delayed_job/plugin.rb +48 -0
  5. data/lib/airbrake/rack/middleware.rb +45 -0
  6. data/lib/airbrake/rack/notice_builder.rb +80 -0
  7. data/lib/airbrake/rack/user.rb +51 -0
  8. data/lib/airbrake/rails/action_controller.rb +35 -0
  9. data/lib/airbrake/rails/active_job.rb +23 -0
  10. data/lib/airbrake/rails/active_record.rb +40 -0
  11. data/lib/airbrake/rails/railtie.rb +61 -0
  12. data/lib/airbrake/rake/task_ext.rb +61 -0
  13. data/lib/airbrake/rake/tasks.rb +93 -0
  14. data/lib/airbrake/resque/failure.rb +19 -0
  15. data/lib/airbrake/sidekiq/error_handler.rb +35 -0
  16. data/lib/airbrake/version.rb +4 -1
  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 +110 -325
  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.rb +0 -45
  90. data/lib/airbrake/rails/action_controller_catcher.rb +0 -32
  91. data/lib/airbrake/rails/controller_methods.rb +0 -146
  92. data/lib/airbrake/rails/error_lookup.rb +0 -35
  93. data/lib/airbrake/rails/middleware.rb +0 -63
  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.rb +0 -81
  103. data/lib/airbrake/tasks/airbrake.cap +0 -28
  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.rb +0 -13
  123. data/test/integration/catcher_test.rb +0 -371
  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
@@ -0,0 +1,51 @@
1
+ module Airbrake
2
+ module Rack
3
+ ##
4
+ # Represents an authenticated Warden user, which can be converted to
5
+ # Airbrake's payload format.
6
+ class User
7
+ # Finds the Warden user in the Rack environment and creates a new user
8
+ # wrapper.
9
+ #
10
+ # @param [Hash{String=>Object}] rack_env The Rack environment
11
+ # @return [Airbrake::Rack::User, nil]
12
+ def self.extract(rack_env)
13
+ return unless (warden = rack_env['warden'])
14
+ new(warden.user(run_callbacks: false))
15
+ end
16
+
17
+ ##
18
+ # @param [Warden::Proxy] warden_user
19
+ def initialize(warden_user)
20
+ @warden_user = warden_user
21
+ end
22
+
23
+ ##
24
+ # Converts the user to Airbrake payload user.
25
+ # @return [Hash{Symbol=>String}] the hash with retrieved user details
26
+ def to_hash
27
+ user = {}
28
+
29
+ user[:id] = try_to_get(:id)
30
+ user[:name] = full_name
31
+ user[:username] = try_to_get(:username)
32
+ user[:email] = try_to_get(:email)
33
+
34
+ user = user.delete_if { |_key, val| val.nil? }
35
+ user.empty? ? user : { user: user }
36
+ end
37
+
38
+ private
39
+
40
+ def try_to_get(key)
41
+ String(@warden_user.__send__(key)) if @warden_user.respond_to?(key)
42
+ end
43
+
44
+ def full_name
45
+ # Try to get first and last names. If that fails, try to get just 'name'.
46
+ name = [try_to_get(:first_name), try_to_get(:last_name)].compact.join(' ')
47
+ name.empty? ? try_to_get(:name) : name
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # Contains helper methods that can be used inside Rails controllers to send
5
+ # notices to Airbrake. The main benefit of using them instead of the direct
6
+ # API is that they automatically add information from the Rack environment
7
+ # to notices.
8
+ module ActionController
9
+ private
10
+
11
+ ##
12
+ # A helper method for sending notices to Airbrake *asynchronously*.
13
+ # Attaches information from the Rack env.
14
+ # @see Airbrake#notify, #notify_airbrake_sync
15
+ def notify_airbrake(exception, parameters = {}, notifier = :default)
16
+ Airbrake.notify(build_notice(exception), parameters, notifier)
17
+ end
18
+
19
+ ##
20
+ # A helper method for sending notices to Airbrake *synchronously*.
21
+ # Attaches information from the Rack env.
22
+ # @see Airbrake#notify_sync, #notify_airbrake
23
+ def notify_airbrake_sync(exception, parameters = {}, notifier = :default)
24
+ Airbrake.notify_sync(build_notice(exception), parameters, notifier)
25
+ end
26
+
27
+ ##
28
+ # @param [Exception] exception
29
+ # @return [Airbrake::Notice] the notice with information from the Rack env
30
+ def build_notice(exception)
31
+ Airbrake::Rack::NoticeBuilder.new(request.env).build_notice(exception)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # Enables support for exceptions occurring in ActiveJob jobs.
5
+ module ActiveJob
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ rescue_from(Exception) do |exception|
10
+ notice = Airbrake.build_notice(exception)
11
+
12
+ notice[:context][:component] = self.class.name
13
+ notice[:context][:action] = job_id
14
+
15
+ notice[:params] = as_json
16
+
17
+ Airbrake.notify(notice)
18
+ raise exception
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # Rails <4.2 has a bug with regard to swallowing exceptions in the
5
+ # +after_commit+ and the +after_rollback+ hooks: it doesn't bubble up
6
+ # exceptions from there.
7
+ #
8
+ # This module makes it possible to report exceptions occurring there.
9
+ #
10
+ # @see https://github.com/rails/rails/pull/14488 Detailed description of the
11
+ # bug and the fix
12
+ # @see https://goo.gl/348lor Rails 4.2+ implementation (fixed)
13
+ # @see https://goo.gl/ddFNg7 Rails <4.2 implementation (bugged)
14
+ module ActiveRecord
15
+ ##
16
+ # @return [Array<Symbol>] the hooks that needs fixing
17
+ KINDS = [:commit, :rollback].freeze
18
+
19
+ ##
20
+ # Patches default +run_callbacks+ with our version, which is capable of
21
+ # notifying about exceptions.
22
+ #
23
+ # rubocop:disable Lint/RescueException
24
+ def run_callbacks(kind, *args, &block)
25
+ # Let the post process handle the exception if it's not a bugged hook.
26
+ return super unless KINDS.include?(kind)
27
+
28
+ # Handle the exception ourselves. The 'ex' exception won't be
29
+ # propagated, therefore we must notify it here.
30
+ begin
31
+ super
32
+ rescue Exception => ex
33
+ Airbrake.notify(ex)
34
+ raise ex
35
+ end
36
+ end
37
+ # rubocop:enable Lint/RescueException
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # This railtie works for any Rails application that supports railties (Rails
5
+ # 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
6
+ # occurring in the application automatically.
7
+ class Railtie < ::Rails::Railtie
8
+ initializer('airbrake.middleware') do |app|
9
+ # Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
10
+ # responsible for logging exceptions and showing a debugging page in
11
+ # case the request is local. We want to insert our middleware after
12
+ # DebugExceptions, so we don't notify Airbrake about local requests.
13
+
14
+ if ::Rails.version =~ /\A5\./
15
+ # Avoid the warning about deprecated strings.
16
+ app.config.middleware.insert_after(
17
+ ActionDispatch::DebugExceptions, Airbrake::Rack::Middleware
18
+ )
19
+ else
20
+ app.config.middleware.insert_after(
21
+ ActionDispatch::DebugExceptions, 'Airbrake::Rack::Middleware'
22
+ )
23
+ end
24
+ end
25
+
26
+ rake_tasks do
27
+ # Report exceptions occurring in Rake tasks.
28
+ require 'airbrake/rake/task_ext'
29
+
30
+ # Defines tasks such as `airbrake:test` & `airbrake:deploy`.
31
+ require 'airbrake/rake/tasks'
32
+ end
33
+
34
+ initializer('airbrake.action_controller') do
35
+ ActiveSupport.on_load(:action_controller) do
36
+ # Patches ActionController with methods that allow us to retrieve
37
+ # interesting request data. Appends that information to notices.
38
+ require 'airbrake/rails/action_controller'
39
+ include Airbrake::Rails::ActionController
40
+ end
41
+ end
42
+
43
+ initializer('airbrake.active_record') do
44
+ ActiveSupport.on_load(:active_record) do
45
+ # Reports exceptions occurring in some bugged ActiveRecord callbacks.
46
+ # Applicable only to the versions of Rails lower than 4.2.
47
+ require 'airbrake/rails/active_record'
48
+ include Airbrake::Rails::ActiveRecord
49
+ end
50
+ end
51
+
52
+ initializer('airbrake.active_job') do
53
+ ActiveSupport.on_load(:active_job) do
54
+ # Reports exceptions occurring in ActiveJob jobs.
55
+ require 'airbrake/rails/active_job'
56
+ include Airbrake::Rails::ActiveJob
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ # This is not bulletproof, but if this file is executed before a task
2
+ # definition, we can grab tasks descriptions and locations.
3
+ # See: https://goo.gl/ksn6PE
4
+ Rake::TaskManager.record_task_metadata = true
5
+
6
+ module Rake
7
+ ##
8
+ # Redefine +Rake::Task#execute+, so it can report errors to Airbrake.
9
+ class Task
10
+ # Store the original method to use it later.
11
+ alias_method :execute_without_airbrake, :execute
12
+
13
+ ##
14
+ # A wrapper around the original +#execute+, that catches all errors and
15
+ # notifies Airbrake.
16
+ #
17
+ # rubocop:disable Lint/RescueException
18
+ def execute(args = nil)
19
+ execute_without_airbrake(args)
20
+ rescue Exception => ex
21
+ notice = Airbrake.build_notice(ex)
22
+ notice[:context][:component] = 'rake'
23
+ notice[:context][:action] = name
24
+ notice[:params] = {
25
+ rake_task: task_info,
26
+ execute_args: args,
27
+ argv: ARGV.join(' ')
28
+ }
29
+
30
+ Airbrake.notify(notice)
31
+ raise ex
32
+ end
33
+ # rubocop:enable Lint/RescueException
34
+
35
+ private
36
+
37
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
38
+ def task_info
39
+ info = {}
40
+
41
+ info[:name] = name
42
+ info[:timestamp] = timestamp.to_s
43
+ info[:investigation] = investigation
44
+
45
+ info[:full_comment] = full_comment if full_comment
46
+ info[:arg_names] = arg_names if arg_names.any?
47
+ info[:arg_description] = arg_description if arg_description
48
+ info[:locations] = locations if locations.any?
49
+ info[:sources] = sources if sources.any?
50
+
51
+ if prerequisite_tasks.any?
52
+ info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
53
+ p.__send__(:task_info)
54
+ end
55
+ end
56
+
57
+ info
58
+ end
59
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
60
+ end
61
+ end
@@ -0,0 +1,93 @@
1
+ namespace :airbrake do
2
+ desc 'Verify your gem installation by sending a test exception'
3
+ task test: :environment do
4
+ require 'pp'
5
+
6
+ begin
7
+ raise StandardError, 'Exception from the test Rake task'
8
+ rescue => ex
9
+ response = Airbrake.notify_sync(ex)
10
+ end
11
+
12
+ notifiers = Airbrake.instance_variable_get(:@notifiers).map do |name, notif|
13
+ cfg = notif.instance_variable_get(:@config)
14
+ filters = notif.instance_variable_get(:@filter_chain)
15
+ "#{name}:\n " + [cfg, filters].pretty_inspect
16
+ end.join("\n")
17
+
18
+ puts <<OUTPUT
19
+ [ruby]
20
+ description: #{RUBY_DESCRIPTION}
21
+
22
+ #{if defined?(Rails)
23
+ "[rails]\nversion: #{Rails::VERSION::STRING}"
24
+ elsif defined?(Sinatra)
25
+ "[sinatra]\nversion: #{Sinatra::VERSION}"
26
+ end}
27
+
28
+ [airbrake]
29
+ version: #{Airbrake::AIRBRAKE_VERSION}
30
+
31
+ [airbrake-ruby]
32
+ version: #{Airbrake::Notice::NOTIFIER[:version]}
33
+
34
+ [notifiers]
35
+ #{notifiers}
36
+
37
+ The output above contains useful information about your environment. Our support
38
+ team may request this information if you have problems using the Airbrake gem;
39
+ we would be really grateful if you could attach the output to your message.
40
+
41
+ The test exception was sent. Find it here: #{response['url']}
42
+ OUTPUT
43
+ end
44
+
45
+ desc 'Notify Airbrake of a new deploy'
46
+ task :deploy do
47
+ if defined?(Rails)
48
+ initializer = Rails.root.join('config', 'initializers', 'airbrake.rb')
49
+
50
+ # Avoid loading the environment to speed up the deploy task and try guess
51
+ # the initializer file location.
52
+ if initializer.exist?
53
+ load initializer
54
+ else
55
+ Rake::Task[:environment].invoke
56
+ end
57
+ end
58
+
59
+ Airbrake.create_deploy(
60
+ environment: ENV['ENVIRONMENT'],
61
+ username: ENV['USERNAME'],
62
+ revision: ENV['REVISION'],
63
+ repository: ENV['REPOSITORY'],
64
+ version: ENV['VERSION']
65
+ )
66
+ end
67
+
68
+ desc 'Install a Heroku deploy hook to notify Airbrake of deploys'
69
+ task :install_heroku_deploy_hook do
70
+ app = ENV['HEROKU_APP']
71
+
72
+ config = Bundler.with_clean_env do
73
+ `heroku config --shell#{ " --app #{app}" if app }`
74
+ end
75
+
76
+ heroku_env = config.each_line.with_object({}) do |line, h|
77
+ h.merge!(Hash[*line.rstrip.split('=')])
78
+ end
79
+
80
+ id = heroku_env['AIRBRAKE_PROJECT_ID']
81
+ key = heroku_env['AIRBRAKE_API_KEY']
82
+
83
+ exit!(1) if [id, key].any?(&:nil?)
84
+
85
+ url = "https://airbrake.io/api/v3/projects/#{id}/heroku-deploys?key=#{key}"
86
+
87
+ command = %(heroku addons:create deployhooks:http --url="#{url}")
88
+ command << " --app #{app}" if app
89
+
90
+ puts "$ #{command}"
91
+ Bundler.with_clean_env { puts `#{command}` }
92
+ end
93
+ end
@@ -0,0 +1,19 @@
1
+ module Resque
2
+ module Failure
3
+ ##
4
+ # Provides Resque integration with Airbrake.
5
+ #
6
+ # @since v5.0.0
7
+ # @see https://github.com/resque/resque/wiki/Failure-Backends
8
+ class Airbrake < Base
9
+ def save
10
+ params = payload.merge(
11
+ component: 'resque',
12
+ action: payload['class'].to_s
13
+ )
14
+
15
+ ::Airbrake.notify_sync(exception, params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ module Airbrake
2
+ module Sidekiq
3
+ ##
4
+ # Provides integration with Sidekiq 2 and Sidekiq 3.
5
+ class ErrorHandler
6
+ # rubocop:disable Lint/RescueException
7
+ def call(_worker, context, _queue)
8
+ yield
9
+ rescue Exception => exception
10
+ notify_airbrake(exception, context)
11
+ raise exception
12
+ end
13
+ # rubocop:enable Lint/RescueException
14
+
15
+ private
16
+
17
+ def notify_airbrake(exception, context)
18
+ params = context.merge(component: 'sidekiq', action: context['class'])
19
+ Airbrake.notify(exception, params)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ if Sidekiq::VERSION < '3'
26
+ Sidekiq.configure_server do |config|
27
+ config.server_middleware do |chain|
28
+ chain.add(Airbrake::Sidekiq::ErrorHandler)
29
+ end
30
+ end
31
+ else
32
+ Sidekiq.configure_server do |config|
33
+ config.error_handlers << Airbrake::Sidekiq::ErrorHandler.new.method(:notify_airbrake)
34
+ end
35
+ end
@@ -1,3 +1,6 @@
1
+ ##
2
+ # We use Semantic Versioning v2.0.0
3
+ # More information: http://semver.org/
1
4
  module Airbrake
2
- VERSION = "4.3.8".freeze
5
+ AIRBRAKE_VERSION = '5.0.0.rc.1'.freeze
3
6
  end
@@ -0,0 +1,25 @@
1
+ ##
2
+ # Creates the Airbrake initializer file for Rails apps.
3
+ #
4
+ # @example Invokation from terminal
5
+ # rails generate airbrake PROJECT_KEY PROJECT_ID [NAME]
6
+ #
7
+ class AirbrakeGenerator < Rails::Generators::Base
8
+ # Adds current directory to source paths, so we can find the template file.
9
+ source_root File.expand_path('..', __FILE__)
10
+
11
+ argument :project_id, required: false
12
+ argument :project_key, required: false
13
+
14
+ ##
15
+ # Makes the NAME option optional, which allows to subclass from Base, so we
16
+ # can pass arguments to the ERB template.
17
+ #
18
+ # @see http://asciicasts.com/episodes/218-making-generators-in-rails-3
19
+ argument :name, type: :string, default: 'application'
20
+
21
+ desc 'Configures the Airbrake notifier with your project id and project key'
22
+ def generate_layout
23
+ template 'airbrake_initializer.rb.erb', 'config/initializers/airbrake.rb'
24
+ end
25
+ end