sentry-raven 3.0.0 → 3.0.1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.craft.yml +14 -0
  3. data/.github/workflows/test.yml +77 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +44 -9
  6. data/.scripts/bump-version.sh +9 -0
  7. data/Gemfile +17 -25
  8. data/README.md +3 -2
  9. data/changelog.md +12 -0
  10. data/lib/raven/backtrace.rb +7 -5
  11. data/lib/raven/base.rb +4 -2
  12. data/lib/raven/breadcrumbs.rb +1 -1
  13. data/lib/raven/breadcrumbs/activesupport.rb +10 -10
  14. data/lib/raven/breadcrumbs/logger.rb +3 -3
  15. data/lib/raven/cli.rb +2 -2
  16. data/lib/raven/client.rb +9 -4
  17. data/lib/raven/configuration.rb +15 -5
  18. data/lib/raven/event.rb +4 -2
  19. data/lib/raven/instance.rb +4 -3
  20. data/lib/raven/integrations/delayed_job.rb +13 -14
  21. data/lib/raven/integrations/rack-timeout.rb +2 -3
  22. data/lib/raven/integrations/rack.rb +3 -2
  23. data/lib/raven/integrations/rails.rb +1 -0
  24. data/lib/raven/integrations/rails/active_job.rb +5 -4
  25. data/lib/raven/integrations/rails/overrides/debug_exceptions_catcher.rb +2 -2
  26. data/lib/raven/interface.rb +2 -2
  27. data/lib/raven/interfaces/stack_trace.rb +1 -1
  28. data/lib/raven/linecache.rb +5 -2
  29. data/lib/raven/logger.rb +3 -2
  30. data/lib/raven/processor/cookies.rb +16 -6
  31. data/lib/raven/processor/post_data.rb +2 -0
  32. data/lib/raven/processor/removecircularreferences.rb +1 -0
  33. data/lib/raven/processor/sanitizedata.rb +65 -17
  34. data/lib/raven/processor/utf8conversion.rb +2 -0
  35. data/lib/raven/transports.rb +4 -0
  36. data/lib/raven/transports/http.rb +5 -5
  37. data/lib/raven/utils/exception_cause_chain.rb +1 -0
  38. data/lib/raven/utils/real_ip.rb +1 -1
  39. data/lib/raven/version.rb +2 -2
  40. metadata +5 -3
  41. data/.travis.yml +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c812e5ab292c9f9351064bfc75f13bf3f6fff8ea1163a79a0e7da2e5efa9afb
4
- data.tar.gz: 2fb7356fa0b26ee6f8a09a8ab023a21dcee132aa75fd3d1d87fd5f528a1c3366
3
+ metadata.gz: 765b22e2ec433b8ab12697da42d40ba6c0f2f95956bd6ce93b0923b9160f386f
4
+ data.tar.gz: b4f97a6effa6828a10cb7844001852db042627dfe375aae61e93b92d10eb2ba7
5
5
  SHA512:
6
- metadata.gz: b406e28322db6c9e96db35d108521f617c484cdef0367a6ea246709356d61b5917795289c3caf1cc7324f3228fba349a8b3f9a2b45aeaef0d01872848540db2a
7
- data.tar.gz: f079139a9cf52c7344d28d55eec1fc108c237c76c23df7880122e66851d858bce86da817887d5a83f35c9732c619328178bfdd6f8cb6742c84024f0445710fed
6
+ metadata.gz: 25c1a39ce4a97b7e40fa66fc1dd1eb7ae4ef96a6e0956f7600db04717eb8c9f147d83317513ba072db31a4390b678b9c56f406f6ba02377f11b4810a3fef5128
7
+ data.tar.gz: 17adf7a479a1539a9fdc81003b2204c0334334cb54482812339af18cd7a75eb9830e22389fc0eed7e304787b993f8aaca92bb1d1c2f414e88a61858acadf08aa
@@ -0,0 +1,14 @@
1
+ minVersion: '0.9.0'
2
+ github:
3
+ owner: getsentry
4
+ repo: raven-ruby
5
+ changelogPolicy: simple
6
+ preReleaseCommand: ruby .scripts/bump-version.sh
7
+ statusProvider:
8
+ name: github
9
+ targets:
10
+ - name: github
11
+ - name: registry
12
+ type: sdk
13
+ config:
14
+ canonical: 'gem:sentry-raven'
@@ -0,0 +1,77 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - release/**
8
+ pull_request:
9
+ jobs:
10
+ test:
11
+ name: Test on ruby ${{ matrix.ruby_version }} and rails ${{ matrix.rails_version }}
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ matrix:
15
+ rails_version: [0, 4.2, 5.2, 6.0]
16
+ ruby_version: [2.3, 2.4, 2.5, 2.6, 2.7, jruby, head]
17
+ os: [ubuntu-latest]
18
+ include:
19
+ - ruby_version: head
20
+ rails_version: 0
21
+ - ruby_version: 2.7
22
+ rails_version: 6.0
23
+ env: RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal"
24
+ exclude:
25
+ - ruby_version: 2.3
26
+ rails_version: 6.0
27
+ - ruby_version: 2.4
28
+ rails_version: 6.0
29
+ - ruby_version: 2.7
30
+ rails_version: 4.2
31
+ - ruby_version: head
32
+ rails_version: 4.2
33
+ - ruby_version: head
34
+ rails_version: 5.2
35
+ - ruby_version: head
36
+ rails_version: 6.0
37
+
38
+ steps:
39
+ - uses: actions/checkout@v1
40
+
41
+ - name: Set up Ruby ${{ matrix.ruby_version }}
42
+ uses: ruby/setup-ruby@v1
43
+ with:
44
+ bundler: 1
45
+ ruby-version: ${{ matrix.ruby_version }}
46
+
47
+ - name: Build with Rails ${{ matrix.rails_version }}
48
+ env:
49
+ RAILS_VERSION: ${{ matrix.rails_version }}
50
+ run: |
51
+ bundle install --jobs 4 --retry 3
52
+ bundle exec rake
53
+
54
+ job_zeus:
55
+ name: Zeus
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v2
59
+ - uses: actions/setup-node@v1
60
+ - name: Set up Ruby
61
+ uses: ruby/setup-ruby@v1
62
+ with:
63
+ ruby-version: 2.6 # Not needed with a .ruby-version file
64
+ - run: bundle install
65
+ - name: Install Zeus
66
+ run: |
67
+ yarn global add @zeus-ci/cli
68
+ echo "::add-path::$(yarn global bin)"
69
+ - name: Upload to Zeus
70
+ env:
71
+ ZEUS_API_TOKEN: ${{ secrets.ZEUS_API_TOKEN }}
72
+ ZEUS_HOOK_BASE: ${{ secrets.ZEUS_HOOK_BASE }}
73
+ run: |
74
+ zeus job update -b $GITHUB_RUN_ID -j $GITHUB_RUN_NUMBER -r $GITHUB_SHA
75
+ gem build sentry-raven.gemspec
76
+ zeus upload -b $GITHUB_RUN_ID -j $GITHUB_RUN_NUMBER -t "application/tar+gem" ./*.gem
77
+ zeus job update --status=passed -b $GITHUB_RUN_ID -j $GITHUB_RUN_NUMBER -r $GITHUB_SHA
data/.gitignore CHANGED
@@ -11,3 +11,5 @@ Gemfile.lock
11
11
  .ruby-gemset
12
12
  .idea
13
13
  *.rdb
14
+
15
+ examples/**/node_modules
@@ -13,33 +13,45 @@ Metrics/ClassLength:
13
13
  Metrics/AbcSize:
14
14
  Max: 40
15
15
 
16
+ Metrics/BlockLength:
17
+ Enabled: false
18
+
16
19
  Metrics/CyclomaticComplexity:
17
20
  Max: 12
18
21
 
19
22
  Metrics/PerceivedComplexity:
20
23
  Max: 11
21
24
 
22
- Metrics/LineLength:
23
- Max: 155
24
-
25
25
  Metrics/MethodLength:
26
26
  Max: 30
27
27
 
28
- Style/SignalException:
28
+ Style/SymbolArray:
29
+ Enabled: false
30
+
31
+ Style/PercentLiteralDelimiters:
32
+ Enabled: false
33
+
34
+ Style/FrozenStringLiteralComment:
29
35
  Enabled: false
30
36
 
31
- Performance/Casecmp:
37
+ Style/SignalException:
32
38
  Enabled: false
33
39
 
34
40
  Style/ClassAndModuleChildren:
35
41
  Enabled: false
36
42
 
43
+ Style/RescueStandardError:
44
+ Enabled: false
45
+
37
46
  Style/ParallelAssignment:
38
47
  Enabled: false
39
48
 
40
49
  Style/Documentation:
41
50
  Enabled: false
42
51
 
52
+ Style/CommentedKeyword:
53
+ Enabled: false
54
+
43
55
  Style/RescueModifier:
44
56
  Enabled: false
45
57
 
@@ -52,10 +64,11 @@ Style/CaseEquality:
52
64
  Style/DoubleNegation:
53
65
  Enabled: false
54
66
 
55
- Style/FileName:
56
- Exclude:
57
- - 'lib/sentry-raven-without-integrations.rb'
58
- - 'lib/sentry-raven.rb'
67
+ Style/GuardClause:
68
+ Enabled: false
69
+
70
+ Style/RedundantBegin:
71
+ Enabled: false
59
72
 
60
73
  Style/NumericLiterals:
61
74
  Exclude:
@@ -64,6 +77,9 @@ Style/NumericLiterals:
64
77
  Style/HashSyntax:
65
78
  EnforcedStyle: hash_rockets
66
79
 
80
+ Style/IfUnlessModifier:
81
+ Enabled: false
82
+
67
83
  Lint/RescueException:
68
84
  Exclude:
69
85
  - 'lib/raven/base.rb'
@@ -72,3 +88,22 @@ Lint/RescueException:
72
88
  - 'lib/raven/integrations/rack.rb'
73
89
  - 'lib/raven/integrations/sidekiq.rb'
74
90
  - 'spec/raven/event_spec.rb'
91
+
92
+ Lint/SuppressedException:
93
+ Enabled: false
94
+
95
+ Lint/AssignmentInCondition:
96
+ Enabled: false
97
+
98
+ Layout/LineLength:
99
+ Max: 155
100
+
101
+ Naming/FileName:
102
+ Exclude:
103
+ - 'lib/sentry-raven-without-integrations.rb'
104
+ - 'lib/sentry-raven.rb'
105
+ - 'lib/raven/integrations/rack-timeout.rb'
106
+
107
+ Naming/MethodParameterName:
108
+ Enabled: false
109
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ file_names = ['lib/raven/version.rb']
4
+
5
+ file_names.each do |file_name|
6
+ text = File.read(file_name)
7
+ new_contents = text.gsub(/\d.\d.\d/, ARGV[1])
8
+ File.open(file_name, "w") {|file| file.puts new_contents }
9
+ end
data/Gemfile CHANGED
@@ -2,37 +2,29 @@ source "https://rubygems.org/"
2
2
 
3
3
  gemspec
4
4
 
5
- if ENV["RAILS_VERSION"] && (ENV["RAILS_VERSION"].to_i == 4)
6
- gem "rails", "< 5"
7
- gem "rspec-rails", "> 3"
8
- elsif ENV["RAILS_VERSION"] && (ENV["RAILS_VERSION"].to_i == 0)
9
- # no-op. No Rails.
10
- else
11
- gem "rails", "< 6"
12
- gem "rspec-rails", "> 3"
13
- end
5
+ rails_version = ENV["RAILS_VERSION"].to_f
14
6
 
15
- if RUBY_VERSION < '2.0'
16
- gem "mime-types", "< 3.0.0"
17
- gem "nokogiri", "~> 1.6.8"
18
- gem "rack", "~> 1.6.8"
19
- gem "sidekiq", "< 3.2"
20
- gem "rack-timeout", "0.3.0"
21
- else
22
- gem "rack"
23
- gem "sidekiq"
24
- gem "rack-timeout"
7
+ if rails_version != 0
8
+ gem "rails", "~> #{rails_version}"
9
+ gem "rspec-rails", "~> 4.0"
25
10
  end
11
+
12
+ gem "sidekiq"
13
+
14
+ gem "rack"
15
+ gem "rack-timeout"
16
+
26
17
  gem "pry"
27
- gem "pry-coolline"
28
18
  gem "benchmark-ips"
29
- gem "benchmark-ipsa" if RUBY_VERSION > '2.0'
19
+ gem "benchmark-ipsa"
30
20
  gem "ruby-prof", platform: :mri
31
21
  gem "rake", "> 12"
32
- gem "rubocop", "~> 0.41.1" # Last version that supported 1.9, upgrade to 0.50 after we drop 1.9
33
- gem "rspec", "> 3"
34
- gem "capybara" # rspec system tests
22
+ gem "rubocop", "~> 0.81.0"
23
+ gem "rspec", "~> 3.9.0"
24
+ gem "capybara", "~> 3.15.0" # rspec system tests
35
25
  gem "puma" # rspec system tests
36
26
 
37
27
  gem "timecop"
38
- gem "test-unit", platform: :mri if RUBY_VERSION > '2.2'
28
+ gem "test-unit"
29
+ gem "simplecov"
30
+ gem "codecov"
data/README.md CHANGED
@@ -8,7 +8,8 @@
8
8
  # Raven-Ruby, the Ruby Client for Sentry
9
9
 
10
10
  [![Gem Version](https://img.shields.io/gem/v/sentry-raven.svg)](https://rubygems.org/gems/sentry-raven)
11
- [![Build Status](https://img.shields.io/travis/getsentry/raven-ruby/master.svg)](https://travis-ci.org/getsentry/raven-ruby)
11
+ ![Build Status](https://github.com/getsentry/raven-ruby/workflows/Test/badge.svg)
12
+ [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/raven-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/raven-ruby/branch/master)
12
13
  [![Gem](https://img.shields.io/gem/dt/sentry-raven.svg)](https://rubygems.org/gems/sentry-raven/)
13
14
  [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-raven&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-raven&package-manager=bundler&version-scheme=semver)
14
15
 
@@ -19,7 +20,7 @@ The official Ruby-language client and integration layer for the [Sentry](https:/
19
20
 
20
21
  ## Requirements
21
22
 
22
- We test on Ruby 2.3, 2.4, 2.5, 2.6 and 2.7 at the latest patchlevel/teeny version. We also support JRuby 9.0. Our Rails integration works with Rails 4.2+ (including Rails 5).
23
+ We test on Ruby 2.3, 2.4, 2.5, 2.6 and 2.7 at the latest patchlevel/teeny version. We also support JRuby 9.0. Our Rails integration works with Rails 4.2+, including Rails 5 and Rails 6.
23
24
 
24
25
  ## Getting Started
25
26
 
@@ -1,3 +1,15 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ## 3.0.1
6
+
7
+ * fix: Improve SanitizeData processor (#984)
8
+ * fix: Masking cookies as key/pair instead of a single string (#983)
9
+ * fix: Transports classes' requiring issue (#986)
10
+ * fix: Frozen string issues (#977)
11
+ * feat: Officially support Rails 6 (#982)
12
+
1
13
  3.0.0
2
14
  ----
3
15
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ## Inspired by Rails' and Airbrake's backtrace parsers.
2
4
 
3
5
  module Raven
@@ -5,16 +7,16 @@ module Raven
5
7
  class Backtrace
6
8
  # Handles backtrace parsing line by line
7
9
  class Line
8
- RB_EXTENSION = ".rb".freeze
10
+ RB_EXTENSION = ".rb"
9
11
  # regexp (optional leading X: on windows, or JRuby9000 class-prefix)
10
12
  RUBY_INPUT_FORMAT = /
11
13
  ^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>):
12
14
  (\d+)
13
15
  (?: :in \s `([^']+)')?$
14
- /x
16
+ /x.freeze
15
17
 
16
18
  # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
17
- JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
19
+ JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/.freeze
18
20
 
19
21
  # The file portion of the line (such as app/models/user.rb)
20
22
  attr_reader :file
@@ -74,7 +76,7 @@ module Raven
74
76
 
75
77
  def self.in_app_pattern
76
78
  @in_app_pattern ||= begin
77
- project_root = Raven.configuration.project_root && Raven.configuration.project_root.to_s
79
+ project_root = Raven.configuration.project_root&.to_s
78
80
  Regexp.new("^(#{project_root}/)?#{Raven.configuration.app_dirs_pattern || APP_DIRS_PATTERN}")
79
81
  end
80
82
  end
@@ -84,7 +86,7 @@ module Raven
84
86
  attr_writer :file, :number, :method, :module_name
85
87
  end
86
88
 
87
- APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test)/
89
+ APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test)/.freeze
88
90
 
89
91
  # holder for an Array of Backtrace::Line instances
90
92
  attr_reader :lines
@@ -85,12 +85,13 @@ module Raven
85
85
 
86
86
  def load_integration(integration)
87
87
  require "raven/integrations/#{integration}"
88
- rescue Exception => error
89
- logger.warn "Unable to load raven/integrations/#{integration}: #{error}"
88
+ rescue Exception => e
89
+ logger.warn "Unable to load raven/integrations/#{integration}: #{e}"
90
90
  end
91
91
 
92
92
  def safely_prepend(module_name, opts = {})
93
93
  return if opts[:to].nil? || opts[:from].nil?
94
+
94
95
  if opts[:to].respond_to?(:prepend, true)
95
96
  opts[:to].send(:prepend, opts[:from].const_get(module_name))
96
97
  else
@@ -101,6 +102,7 @@ module Raven
101
102
  def sys_command(command)
102
103
  result = `#{command} 2>&1` rescue nil
103
104
  return if result.nil? || result.empty? || ($CHILD_STATUS && $CHILD_STATUS.exitstatus != 0)
105
+
104
106
  result.strip
105
107
  end
106
108
  end
@@ -64,7 +64,7 @@ module Raven
64
64
  end
65
65
 
66
66
  def empty?
67
- !members.any?
67
+ members.none?
68
68
  end
69
69
 
70
70
  def to_hash
@@ -1,19 +1,19 @@
1
1
  module Raven
2
2
  module ActiveSupportBreadcrumbs
3
3
  class << self
4
- def add(name, started, _finished, _unique_id, data)
5
- Raven.breadcrumbs.record do |crumb|
6
- crumb.data = data
7
- crumb.category = name
8
- crumb.timestamp = started.to_i
9
- end
4
+ def add(name, started, _finished, _unique_id, data)
5
+ Raven.breadcrumbs.record do |crumb|
6
+ crumb.data = data
7
+ crumb.category = name
8
+ crumb.timestamp = started.to_i
10
9
  end
10
+ end
11
11
 
12
- def inject
13
- ActiveSupport::Notifications.subscribe(/.*/) do |name, started, finished, unique_id, data|
14
- add(name, started, finished, unique_id, data)
15
- end
12
+ def inject
13
+ ActiveSupport::Notifications.subscribe(/.*/) do |name, started, finished, unique_id, data|
14
+ add(name, started, finished, unique_id, data)
16
15
  end
16
+ end
17
17
  end
18
18
  end
19
19
  end
@@ -4,13 +4,13 @@ module Raven
4
4
  module BreadcrumbLogger
5
5
  LEVELS = {
6
6
  ::Logger::DEBUG => 'debug',
7
- ::Logger::INFO => 'info',
8
- ::Logger::WARN => 'warn',
7
+ ::Logger::INFO => 'info',
8
+ ::Logger::WARN => 'warn',
9
9
  ::Logger::ERROR => 'error',
10
10
  ::Logger::FATAL => 'fatal'
11
11
  }.freeze
12
12
 
13
- EXC_FORMAT = /^([a-zA-Z0-9]+)\:\s(.*)$/
13
+ EXC_FORMAT = /^([a-zA-Z0-9]+)\:\s(.*)$/.freeze
14
14
 
15
15
  def self.parse_exception(message)
16
16
  lines = message.split(/\n\s*/)
@@ -29,8 +29,8 @@ module Raven
29
29
 
30
30
  begin
31
31
  1 / 0
32
- rescue ZeroDivisionError => exception
33
- evt = instance.capture_exception(exception)
32
+ rescue ZeroDivisionError => e
33
+ evt = instance.capture_exception(e)
34
34
  end
35
35
 
36
36
  if evt && !(evt.is_a? Thread)
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'base64'
3
4
  require 'json'
4
5
  require 'zlib'
5
6
 
7
+ require "raven/transports"
8
+
6
9
  module Raven
7
10
  # Encodes events and sends them to the Sentry server.
8
11
  class Client
9
- PROTOCOL_VERSION = '5'.freeze
10
- USER_AGENT = "raven-ruby/#{Raven::VERSION}".freeze
11
- CONTENT_TYPE = 'application/json'.freeze
12
+ PROTOCOL_VERSION = '5'
13
+ USER_AGENT = "raven-ruby/#{Raven::VERSION}"
14
+ CONTENT_TYPE = 'application/json'
12
15
 
13
16
  attr_accessor :configuration
14
17
 
@@ -120,7 +123,9 @@ module Raven
120
123
  configuration.logger.warn "Not sending event due to previous failure(s)."
121
124
  end
122
125
  configuration.logger.warn("Failed to submit event: #{get_log_message(event)}")
123
- configuration.transport_failure_callback.call(event) if configuration.transport_failure_callback
126
+
127
+ # configuration.transport_failure_callback can be false & nil
128
+ configuration.transport_failure_callback.call(event) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
124
129
  end
125
130
  end
126
131
 
@@ -236,6 +236,7 @@ module Raven
236
236
 
237
237
  def server=(value)
238
238
  return if value.nil?
239
+
239
240
  uri = URI.parse(value)
240
241
  uri_path = uri.path.split('/')
241
242
 
@@ -253,13 +254,14 @@ module Raven
253
254
 
254
255
  # For anyone who wants to read the base server string
255
256
  @server = "#{scheme}://#{host}"
256
- @server << ":#{port}" unless port == { 'http' => 80, 'https' => 443 }[scheme]
257
- @server << path
257
+ @server += ":#{port}" unless port == { 'http' => 80, 'https' => 443 }[scheme]
258
+ @server += path
258
259
  end
259
260
  alias dsn= server=
260
261
 
261
262
  def encoding=(encoding)
262
263
  raise(Error, 'Unsupported encoding') unless %w(gzip json).include? encoding
264
+
263
265
  @encoding = encoding
264
266
  end
265
267
 
@@ -267,6 +269,7 @@ module Raven
267
269
  unless value == false || value.respond_to?(:call)
268
270
  raise(ArgumentError, "async must be callable (or false to disable)")
269
271
  end
272
+
270
273
  @async = value
271
274
  end
272
275
 
@@ -274,6 +277,7 @@ module Raven
274
277
  unless value == false || value.respond_to?(:call)
275
278
  raise(ArgumentError, "transport_failure_callback must be callable (or false to disable)")
276
279
  end
280
+
277
281
  @transport_failure_callback = value
278
282
  end
279
283
 
@@ -281,6 +285,7 @@ module Raven
281
285
  unless value == false || value.respond_to?(:call)
282
286
  raise ArgumentError, "should_capture must be callable (or false to disable)"
283
287
  end
288
+
284
289
  @should_capture = value
285
290
  end
286
291
 
@@ -288,6 +293,7 @@ module Raven
288
293
  unless value == false || value.respond_to?(:call)
289
294
  raise ArgumentError, "before_send must be callable (or false to disable)"
290
295
  end
296
+
291
297
  @before_send = value
292
298
  end
293
299
 
@@ -351,8 +357,8 @@ module Raven
351
357
  detect_release_from_git ||
352
358
  detect_release_from_capistrano ||
353
359
  detect_release_from_heroku
354
- rescue => ex
355
- logger.error "Error detecting release: #{ex.message}"
360
+ rescue => e
361
+ logger.error "Error detecting release: #{e.message}"
356
362
  end
357
363
 
358
364
  def excluded_exception?(incoming_exception)
@@ -418,18 +424,21 @@ module Raven
418
424
 
419
425
  def capture_in_current_environment?
420
426
  return true unless environments.any? && !environments.include?(current_environment)
427
+
421
428
  @errors << "Not configured to send/capture in environment '#{current_environment}'"
422
429
  false
423
430
  end
424
431
 
425
432
  def capture_allowed_by_callback?(message_or_exc)
426
- return true if !should_capture || message_or_exc.nil? || should_capture.call(*[message_or_exc])
433
+ return true if !should_capture || message_or_exc.nil? || should_capture.call(message_or_exc)
434
+
427
435
  @errors << "should_capture returned false"
428
436
  false
429
437
  end
430
438
 
431
439
  def valid?
432
440
  return true if %w(server host path public_key project_id).all? { |k| public_send(k) }
441
+
433
442
  if server
434
443
  %w(server host path public_key project_id).map do |key|
435
444
  @errors << "No #{key} specified" unless public_send(key)
@@ -442,6 +451,7 @@ module Raven
442
451
 
443
452
  def sample_allowed?
444
453
  return true if sample_rate == 1.0
454
+
445
455
  if Random::DEFAULT.rand >= sample_rate
446
456
  @errors << "Excluded by random sample"
447
457
  false
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'socket'
3
4
  require 'securerandom'
4
5
 
@@ -76,7 +77,7 @@ module Raven
76
77
  end
77
78
 
78
79
  def message
79
- @interfaces[:logentry] && @interfaces[:logentry].unformatted_message
80
+ @interfaces[:logentry]&.unformatted_message
80
81
  end
81
82
 
82
83
  def message=(args)
@@ -96,12 +97,13 @@ module Raven
96
97
  end
97
98
 
98
99
  def level=(new_level) # needed to meet the Sentry spec
99
- @level = new_level == "warn" || new_level == :warn ? :warning : new_level
100
+ @level = new_level.to_s == "warn" ? :warning : new_level
100
101
  end
101
102
 
102
103
  def interface(name, value = nil, &block)
103
104
  int = Interface.registered[name]
104
105
  raise(Error, "Unknown interface: #{name}") unless int
106
+
105
107
  @interfaces[int.sentry_alias] = int.new(value, &block) if value || block
106
108
  @interfaces[int.sentry_alias]
107
109
  end
@@ -51,6 +51,7 @@ module Raven
51
51
  # Tell the log that the client is good to go
52
52
  def report_status
53
53
  return if configuration.silence_ready
54
+
54
55
  if configuration.capture_allowed?
55
56
  logger.info "Raven #{VERSION} ready to catch errors"
56
57
  else
@@ -111,15 +112,15 @@ module Raven
111
112
  message_or_exc = obj.is_a?(String) ? "message" : "exception"
112
113
  options[:configuration] = configuration
113
114
  options[:context] = context
114
- if (evt = Event.send("from_" + message_or_exc, obj, options))
115
+ if evt = Event.send("from_" + message_or_exc, obj, options)
115
116
  yield evt if block_given?
116
117
  if configuration.async?
117
118
  begin
118
119
  # We have to convert to a JSON-like hash, because background job
119
120
  # processors (esp ActiveJob) may not like weird types in the event hash
120
121
  configuration.async.call(evt.to_json_compatible)
121
- rescue => ex
122
- logger.error("async event sending failed: #{ex.message}")
122
+ rescue => e
123
+ logger.error("async event sending failed: #{e.message}")
123
124
  send_event(evt, make_hint(obj))
124
125
  end
125
126
  else
@@ -8,19 +8,18 @@ module Delayed
8
8
  begin
9
9
  # Forward the call to the next callback in the callback chain
10
10
  block.call(job, *args)
11
-
12
- rescue Exception => exception
11
+ rescue Exception => e
13
12
  # Log error to Sentry
14
13
  extra = {
15
14
  :delayed_job => {
16
- :id => job.id.to_s,
17
- :priority => job.priority,
18
- :attempts => job.attempts,
19
- :run_at => job.run_at,
20
- :locked_at => job.locked_at,
21
- :locked_by => job.locked_by,
22
- :queue => job.queue,
23
- :created_at => job.created_at
15
+ :id => job.id.to_s,
16
+ :priority => job.priority,
17
+ :attempts => job.attempts,
18
+ :run_at => job.run_at,
19
+ :locked_at => job.locked_at,
20
+ :locked_by => job.locked_by,
21
+ :queue => job.queue,
22
+ :created_at => job.created_at
24
23
  }
25
24
  }
26
25
  # last_error can be nil
@@ -32,16 +31,16 @@ module Delayed
32
31
  if job.respond_to?('payload_object') && job.payload_object.respond_to?('job_data')
33
32
  extra[:active_job] = job.payload_object.job_data
34
33
  end
35
- ::Raven.capture_exception(exception,
36
- :logger => 'delayed_job',
37
- :tags => {
34
+ ::Raven.capture_exception(e,
35
+ :logger => 'delayed_job',
36
+ :tags => {
38
37
  :delayed_job_queue => job.queue,
39
38
  :delayed_job_id => job.id.to_s
40
39
  },
41
40
  :extra => extra)
42
41
 
43
42
  # Make sure we propagate the failure!
44
- raise exception
43
+ raise e
45
44
  ensure
46
45
  ::Raven::Context.clear!
47
46
  ::Raven::BreadcrumbBuffer.clear!
@@ -14,6 +14,5 @@ module RackTimeoutExtensions
14
14
  end
15
15
  end
16
16
 
17
- # Include is private in Ruby 1.9
18
- Rack::Timeout::Error.__send__(:include, RackTimeoutExtensions)
19
- Rack::Timeout::RequestTimeoutException.__send__(:include, RackTimeoutExtensions)
17
+ Rack::Timeout::Error.include(RackTimeoutExtensions)
18
+ Rack::Timeout::RequestTimeoutException.include(RackTimeoutExtensions)
@@ -92,8 +92,8 @@ module Raven
92
92
  request.body.rewind
93
93
  data
94
94
  end
95
- rescue IOError => ex
96
- ex.message
95
+ rescue IOError => e
96
+ e.message
97
97
  end
98
98
 
99
99
  def format_headers_for_sentry(env_hash)
@@ -112,6 +112,7 @@ module Raven
112
112
  next if key == 'HTTP_COOKIE' # Cookies don't go here, they go somewhere else
113
113
 
114
114
  next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key)
115
+
115
116
  # Rack stores headers as HTTP_WHAT_EVER, we need What-Ever
116
117
  key = key.sub(/^HTTP_/, "")
117
118
  key = key.split('_').map(&:capitalize).join('-')
@@ -5,6 +5,7 @@ module Raven
5
5
  require 'raven/integrations/rails/overrides/streaming_reporter'
6
6
  require 'raven/integrations/rails/controller_methods'
7
7
  require 'raven/integrations/rails/controller_transaction'
8
+ require 'raven/integrations/rack'
8
9
 
9
10
  initializer "raven.use_rack_middleware" do |app|
10
11
  app.config.middleware.insert 0, Raven::Rack
@@ -20,10 +20,11 @@ module Raven
20
20
 
21
21
  def capture_and_reraise_with_sentry(job, block)
22
22
  block.call
23
- rescue Exception => exception # rubocop:disable Lint/RescueException
24
- return if rescue_with_handler(exception)
25
- Raven.capture_exception(exception, :extra => raven_context(job))
26
- raise exception
23
+ rescue Exception => e # rubocop:disable Lint/RescueException
24
+ return if rescue_with_handler(e)
25
+
26
+ Raven.capture_exception(e, :extra => raven_context(job))
27
+ raise e
27
28
  ensure
28
29
  Context.clear!
29
30
  BreadcrumbBuffer.clear!
@@ -6,7 +6,7 @@ module Raven
6
6
  begin
7
7
  env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
8
8
  Raven::Rack.capture_exception(exception, env)
9
- rescue # rubocop:disable Lint/HandleExceptions
9
+ rescue
10
10
  end
11
11
  super
12
12
  end
@@ -21,7 +21,7 @@ module Raven
21
21
  begin
22
22
  env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
23
23
  Raven::Rack.capture_exception(exception, env)
24
- rescue # rubocop:disable Lint/HandleExceptions
24
+ rescue
25
25
  end
26
26
  render_exception_without_raven(env_or_request, exception)
27
27
  end
@@ -1,9 +1,9 @@
1
1
  module Raven
2
2
  class Interface
3
3
  def initialize(attributes = nil)
4
- attributes.each do |attr, value|
4
+ attributes&.each do |attr, value|
5
5
  public_send "#{attr}=", value
6
- end if attributes
6
+ end
7
7
 
8
8
  yield self if block_given?
9
9
  end
@@ -58,7 +58,7 @@ module Raven
58
58
  end
59
59
 
60
60
  def project_root
61
- @project_root ||= Raven.configuration.project_root && Raven.configuration.project_root.to_s
61
+ @project_root ||= Raven.configuration.project_root&.to_s
62
62
  end
63
63
 
64
64
  def longest_load_path
@@ -10,6 +10,7 @@ module Raven
10
10
  # line should be the line requested by lineno. See specs for more information.
11
11
  def get_file_context(filename, lineno, context)
12
12
  return nil, nil, nil unless valid_path?(filename)
13
+
13
14
  lines = Array.new(2 * context + 1) do |i|
14
15
  getline(filename, lineno - context + i)
15
16
  end
@@ -26,15 +27,17 @@ module Raven
26
27
  def getlines(path)
27
28
  @cache[path] ||= begin
28
29
  IO.readlines(path)
29
- rescue
30
- nil
30
+ rescue
31
+ nil
31
32
  end
32
33
  end
33
34
 
34
35
  def getline(path, n)
35
36
  return nil if n < 1
37
+
36
38
  lines = getlines(path)
37
39
  return nil if lines.nil?
40
+
38
41
  lines[n - 1]
39
42
  end
40
43
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'logger'
3
4
 
4
5
  module Raven
5
6
  class Logger < ::Logger
6
- LOG_PREFIX = "** [Raven] ".freeze
7
- PROGNAME = "sentry".freeze
7
+ LOG_PREFIX = "** [Raven] "
8
+ PROGNAME = "sentry"
8
9
 
9
10
  def initialize(*)
10
11
  super
@@ -10,17 +10,27 @@ module Raven
10
10
  private
11
11
 
12
12
  def process_if_symbol_keys(data)
13
- data[:request][:cookies] = STRING_MASK if data[:request][:cookies]
13
+ if cookies = data.dig(:request, :cookies)
14
+ data[:request][:cookies] = generate_masked_cookies(cookies)
15
+ end
14
16
 
15
- return unless data[:request][:headers] && data[:request][:headers]["Cookie"]
16
- data[:request][:headers]["Cookie"] = STRING_MASK
17
+ if cookies_header = data[:request][:headers]["Cookie"]
18
+ data[:request][:headers]["Cookie"] = generate_masked_cookies(cookies_header)
19
+ end
17
20
  end
18
21
 
19
22
  def process_if_string_keys(data)
20
- data["request"]["cookies"] = STRING_MASK if data["request"]["cookies"]
23
+ if cookies = data.dig("request", "cookies")
24
+ data["request"]["cookies"] = generate_masked_cookies(cookies)
25
+ end
21
26
 
22
- return unless data["request"]["headers"] && data["request"]["headers"]["Cookie"]
23
- data["request"]["headers"]["Cookie"] = STRING_MASK
27
+ if cookies_header = data.dig("request", "headers", "Cookie")
28
+ data["request"]["headers"]["Cookie"] = generate_masked_cookies(cookies_header)
29
+ end
30
+ end
31
+
32
+ def generate_masked_cookies(cookies)
33
+ cookies.merge(cookies) { STRING_MASK }
24
34
  end
25
35
  end
26
36
  end
@@ -11,11 +11,13 @@ module Raven
11
11
 
12
12
  def process_if_symbol_keys(data)
13
13
  return unless data[:request][:method] == "POST"
14
+
14
15
  data[:request][:data] = STRING_MASK
15
16
  end
16
17
 
17
18
  def process_if_string_keys(data)
18
19
  return unless data["request"]["method"] == "POST"
20
+
19
21
  data["request"]["data"] = STRING_MASK
20
22
  end
21
23
  end
@@ -2,6 +2,7 @@ module Raven
2
2
  class Processor::RemoveCircularReferences < Processor
3
3
  def process(value, visited = [])
4
4
  return "(...)" if visited.include?(value.__id__)
5
+
5
6
  visited << value.__id__ if value.is_a?(Array) || value.is_a?(Hash)
6
7
 
7
8
  case value
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'json'
3
4
 
4
5
  module Raven
5
6
  class Processor::SanitizeData < Processor
6
7
  DEFAULT_FIELDS = %w(authorization password passwd secret ssn social(.*)?sec).freeze
7
- CREDIT_CARD_RE = /\b(?:3[47]\d|(?:4\d|5[1-5]|65)\d{2}|6011)\d{12}\b/
8
+ CREDIT_CARD_RE = /\b(?:3[47]\d|(?:4\d|5[1-5]|65)\d{2}|6011)\d{12}\b/.freeze
8
9
  QUERY_STRING = ['query_string', :query_string].freeze
9
10
  JSON_STARTS_WITH = ["[", "{"].freeze
10
11
 
@@ -20,22 +21,13 @@ module Raven
20
21
  def process(value, key = nil)
21
22
  case value
22
23
  when Hash
23
- !value.frozen? ? value.merge!(value) { |k, v| process v, k } : value.merge(value) { |k, v| process v, k }
24
+ sanitize_hash_value(key, value)
24
25
  when Array
25
- !value.frozen? ? value.map! { |v| process v, key } : value.map { |v| process v, key }
26
+ sanitize_array_value(key, value)
26
27
  when Integer
27
28
  matches_regexes?(key, value.to_s) ? INT_MASK : value
28
29
  when String
29
- if value =~ fields_re && (json = parse_json_or_nil(value))
30
- # if this string is actually a json obj, convert and sanitize
31
- process(json).to_json
32
- elsif matches_regexes?(key, value)
33
- STRING_MASK
34
- elsif QUERY_STRING.include?(key)
35
- sanitize_query_string(value)
36
- else
37
- value
38
- end
30
+ sanitize_string_value(key, value)
39
31
  else
40
32
  value
41
33
  end
@@ -49,6 +41,39 @@ module Raven
49
41
  @utf8_processor ||= Processor::UTF8Conversion.new
50
42
  end
51
43
 
44
+ def sanitize_hash_value(key, value)
45
+ if key =~ sensitive_fields
46
+ STRING_MASK
47
+ elsif value.frozen?
48
+ value.merge(value) { |k, v| process v, k }
49
+ else
50
+ value.merge!(value) { |k, v| process v, k }
51
+ end
52
+ end
53
+
54
+ def sanitize_array_value(key, value)
55
+ if value.frozen?
56
+ value.map { |v| process v, key }
57
+ else
58
+ value.map! { |v| process v, key }
59
+ end
60
+ end
61
+
62
+ def sanitize_string_value(key, value)
63
+ if value =~ sensitive_fields && (json = parse_json_or_nil(value))
64
+ # if this string is actually a json obj, convert and sanitize
65
+ process(json).to_json
66
+ elsif matches_regexes?(key, value)
67
+ STRING_MASK
68
+ elsif QUERY_STRING.include?(key)
69
+ sanitize_query_string(value)
70
+ elsif value =~ sensitive_fields
71
+ sanitize_sensitive_string_content(value)
72
+ else
73
+ value
74
+ end
75
+ end
76
+
52
77
  def sanitize_query_string(query_string)
53
78
  query_hash = CGI.parse(query_string)
54
79
  sanitized = utf8_processor.process(query_hash)
@@ -56,16 +81,38 @@ module Raven
56
81
  URI.encode_www_form(processed_query_hash)
57
82
  end
58
83
 
84
+ # this scrubs some sensitive info from the string content. for example:
85
+ #
86
+ # ```
87
+ # unexpected token at '{
88
+ # "role": "admin","password": "Abc@123","foo": "bar"
89
+ # }'
90
+ # ```
91
+ #
92
+ # will become
93
+ #
94
+ # ```
95
+ # unexpected token at '{
96
+ # "role": "admin","password": *******,"foo": "bar"
97
+ # }'
98
+ # ```
99
+ #
100
+ # it's particularly useful in hash or param-parsing related errors
101
+ def sanitize_sensitive_string_content(value)
102
+ value.gsub(/(#{sensitive_fields}['":]\s?(:|=>)?\s?)(".*?"|'.*?')/, '\1' + STRING_MASK)
103
+ end
104
+
59
105
  def matches_regexes?(k, v)
60
106
  (sanitize_credit_cards && v =~ CREDIT_CARD_RE) ||
61
- k =~ fields_re
107
+ k =~ sensitive_fields
62
108
  end
63
109
 
64
- def fields_re
65
- return @fields_re if instance_variable_defined?(:@fields_re)
110
+ def sensitive_fields
111
+ return @sensitive_fields if instance_variable_defined?(:@sensitive_fields)
112
+
66
113
  fields = DEFAULT_FIELDS | sanitize_fields
67
114
  fields -= sanitize_fields_excluded
68
- @fields_re = /#{fields.map do |f|
115
+ @sensitive_fields = /#{fields.map do |f|
69
116
  use_boundary?(f) ? "\\b#{f}\\b" : f
70
117
  end.join("|")}/i
71
118
  end
@@ -80,6 +127,7 @@ module Raven
80
127
 
81
128
  def parse_json_or_nil(string)
82
129
  return unless string.start_with?(*JSON_STARTS_WITH)
130
+
83
131
  JSON.parse(string)
84
132
  rescue JSON::ParserError, NoMethodError
85
133
  nil
@@ -14,6 +14,7 @@ module Raven
14
14
  !value.frozen? ? value.map! { |v| process v } : value.map { |v| process v }
15
15
  when Exception
16
16
  return value if value.message.valid_encoding?
17
+
17
18
  clean_exc = value.class.new(remove_invalid_bytes(value.message))
18
19
  clean_exc.set_backtrace(value.backtrace)
19
20
  clean_exc
@@ -27,6 +28,7 @@ module Raven
27
28
  value.force_encoding(Encoding::UTF_8)
28
29
  end
29
30
  return value if value.valid_encoding?
31
+
30
32
  remove_invalid_bytes(value)
31
33
  else
32
34
  value
@@ -13,3 +13,7 @@ module Raven
13
13
  end
14
14
  end
15
15
  end
16
+
17
+ require "raven/transports/dummy"
18
+ require "raven/transports/http"
19
+ require "raven/transports/stdout"
@@ -26,10 +26,10 @@ module Raven
26
26
  req.headers['X-Sentry-Auth'] = auth_header
27
27
  req.body = data
28
28
  end
29
- rescue Faraday::Error => ex
30
- error_info = ex.message
31
- if ex.response && ex.response[:headers]['x-sentry-error']
32
- error_info += " Error in headers is: #{ex.response[:headers]['x-sentry-error']}"
29
+ rescue Faraday::Error => e
30
+ error_info = e.message
31
+ if e.response && e.response[:headers]['x-sentry-error']
32
+ error_info += " Error in headers is: #{e.response[:headers]['x-sentry-error']}"
33
33
  end
34
34
  raise Raven::Error, error_info
35
35
  end
@@ -42,7 +42,7 @@ module Raven
42
42
  proxy = configuration.public_send(:proxy)
43
43
 
44
44
  Faraday.new(configuration.server, :ssl => ssl_configuration, :proxy => proxy) do |builder|
45
- configuration.faraday_builder.call(builder) if configuration.faraday_builder
45
+ configuration.faraday_builder&.call(builder)
46
46
  builder.response :raise_error
47
47
  builder.options.merge! faraday_opts
48
48
  builder.headers[:user_agent] = "sentry-ruby/#{Raven::VERSION}"
@@ -7,6 +7,7 @@ module Raven
7
7
  while exception.cause
8
8
  exception = exception.cause
9
9
  break if exceptions.any? { |e| e.object_id == exception.object_id }
10
+
10
11
  exceptions << exception
11
12
  end
12
13
  exceptions
@@ -13,7 +13,7 @@ module Raven
13
13
  "fc00::/7", # private IPv6 range fc00::/7
14
14
  "10.0.0.0/8", # private IPv4 range 10.x.x.x
15
15
  "172.16.0.0/12", # private IPv4 range 172.16.0.0 .. 172.31.255.255
16
- "192.168.0.0/16", # private IPv4 range 192.168.x.x
16
+ "192.168.0.0/16" # private IPv4 range 192.168.x.x
17
17
  ].map { |proxy| IPAddr.new(proxy) }
18
18
 
19
19
  attr_accessor :ip, :ip_addresses
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Raven
3
- # Freezing this constant breaks in 1.9.x
4
- VERSION = "3.0.0" # rubocop:disable Style/MutableConstant
4
+ VERSION = "3.0.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-raven
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-02 00:00:00.000000000 Z
11
+ date: 2020-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -33,11 +33,13 @@ extra_rdoc_files:
33
33
  - README.md
34
34
  - LICENSE
35
35
  files:
36
+ - ".craft.yml"
37
+ - ".github/workflows/test.yml"
36
38
  - ".gitignore"
37
39
  - ".gitmodules"
38
40
  - ".rspec"
39
41
  - ".rubocop.yml"
40
- - ".travis.yml"
42
+ - ".scripts/bump-version.sh"
41
43
  - Gemfile
42
44
  - LICENSE
43
45
  - README.md
@@ -1,43 +0,0 @@
1
- language: ruby
2
- dist: trusty
3
- group: beta
4
- cache: bundler
5
-
6
- services:
7
- - redis-server
8
-
9
- branches:
10
- only: [master]
11
-
12
- rvm:
13
- - 2.3.8
14
- - 2.4.9
15
- - 2.5.7
16
- - 2.6.5
17
- - 2.7.0
18
-
19
- env:
20
- - RAILS_VERSION=4
21
- - RAILS_VERSION=5
22
- - RAILS_VERSION=0
23
-
24
- addons:
25
- apt:
26
- packages:
27
- - haveged
28
-
29
- before_install:
30
- - service haveged start
31
- # Pin bundler version due to https://github.com/rubygems/rubygems/issues/2055
32
- - gem install bundler -v 1.16.0
33
-
34
- matrix:
35
- include:
36
- - rvm: jruby-9.2.9.0
37
- env: JRUBY_OPTS="--dev -J-Djruby.launch.inproc=true -J-Xmx1024M" RAILS_VERSION=4
38
- - rvm: jruby-9.2.9.0
39
- env: JRUBY_OPTS="--dev -J-Djruby.launch.inproc=true -J-Xmx1024M" RAILS_VERSION=5
40
- - rvm: ruby-head
41
- env: RAILS_VERSION=0
42
- allow_failures:
43
- - rvm: ruby-head