Class: Rolemodel::SentryGenerator

Inherits:
GeneratorBase
  • Object
show all
Defined in:
lib/generators/rolemodel/sentry/sentry_generator.rb

Constant Summary collapse

JS_DEPS =
%w[
  @sentry/browser
  @sentry/webpack-plugin
]

Instance Method Summary collapse

Instance Method Details

#add_js_dependenciesObject



55
56
57
58
59
60
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 55

def add_js_dependencies
  say 'Adding Sentry JS dependencies to package.json', :green

  ensure_yarn
  run "yarn add --dev #{JS_DEPS.join(' ')}"
end

#add_js_initializerObject



62
63
64
65
66
67
68
69
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 62

def add_js_initializer
  say 'Setting up Sentry for JS error reporting', :green

  copy_file 'app/javascript/initializers/sentry.js'
  append_to_file 'app/javascript/application.js', <<~JS
    import './initializers/sentry'
  JS
end

#add_ruby_initializerObject



28
29
30
31
32
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 28

def add_ruby_initializer
  say 'Setting up Sentry for Ruby error reporting', :green

  copy_file 'config/initializers/sentry.rb'
end

#add_user_contextObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 34

def add_user_context
  say 'Adding Sentry user context to ApplicationController', :green

  inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController',
                    "  before_action :set_sentry_user\n"

  inject_into_file 'app/controllers/application_controller.rb', before: /^end\b/ do
    <<-RUBY

  private

  # Guarded so it works whether or not an authentication generator has been run.
  def set_sentry_user
return unless respond_to?(:current_user) && current_user

Sentry.set_user(id: current_user.id)
  end
    RUBY
  end
end

#configure_webpackObject

Wire the Sentry webpack plugin into webpack.config.js. Idempotent and a no-op if there's no webpack.config.js or it's already wired, so the webpack generator can safely invoke this generator via its --sentry option.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 74

def configure_webpack
  config = File.expand_path('webpack.config.js', destination_root)
  return unless File.exist?(config)
  return if File.read(config).include?('@sentry/webpack-plugin')

  say 'Wiring Sentry into webpack.config.js', :green

  inject_into_file 'webpack.config.js',
                   "import { sentryWebpackPlugin } from '@sentry/webpack-plugin'\n",
                   after: "import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'\n"

  inject_into_file 'webpack.config.js', after: "'process.env.RAILS_ENV': JSON.stringify(process.env.RAILS_ENV),\n" do
    <<-JS
  'process.env.SENTRY_DSN': JSON.stringify(process.env.SENTRY_DSN),
  'process.env.SENTRY_ENVIRONMENT': JSON.stringify(process.env.SENTRY_ENVIRONMENT),
  'process.env.SENTRY_AUTH_TOKEN': JSON.stringify(process.env.SENTRY_AUTH_TOKEN),
    JS
  end

  gsub_file 'webpack.config.js', "    })\n  ].filter(Boolean)", <<-JS.chomp
}),

// Upload source maps to Sentry in production for easier debugging
mode === 'production' &&
  !process.env.CI &&
  sentryWebpackPlugin({
    authToken: process.env.SENTRY_AUTH_TOKEN,
    org: 'rolemodel-software',
    project: '#{sentry_app_name}',
    telemetry: false,
    applicationKey: 'app-frontend'
  })
  ].filter(Boolean)
  JS
end

#finishing_notesObject



110
111
112
113
114
115
116
117
118
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 110

def finishing_notes
  say <<~NOTES

    *** Update the sentryWebpackPlugin `project` and `applicationKey` in webpack.config.js,
        and the matching `filterKeys` in app/javascript/initializers/sentry.js, to your Sentry project.

    *** Set the SENTRY_DSN, SENTRY_ENVIRONMENT, and SENTRY_AUTH_TOKEN environment variables.
  NOTES
end

#install_gemObject



12
13
14
15
16
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 12

def install_gem
  say 'Adding sentry-rails gem', :green

  bundle_command 'add sentry-rails'
end

#install_profiler_gemObject



18
19
20
21
22
23
24
25
26
# File 'lib/generators/rolemodel/sentry/sentry_generator.rb', line 18

def install_profiler_gem
  say 'Adding stackprof gem for Sentry profiling', :green

  # config/initializers/sentry.rb sets profiles_sample_rate; without stackprof
  # the SDK logs a warning on every boot and profiling is silently disabled.
  # stackprof is a native MRI extension, so restrict it to compatible platforms.
  gem 'stackprof', platforms: :ruby
  run_bundle
end