honeybadger 1.6.2 → 1.7.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.
data/honeybadger.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'honeybadger'
7
- s.version = '1.6.2'
8
- s.date = '2013-04-10'
7
+ s.version = '1.7.0'
8
+ s.date = '2013-06-07'
9
9
 
10
10
  s.summary = 'Error reports you can be happy about.'
11
11
  s.description = 'Make managing application errors a more pleasant experience.'
data/lib/honeybadger.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'net/http'
2
2
  require 'net/https'
3
3
  require 'json'
4
+ require 'digest'
4
5
  require 'logger'
5
6
 
6
7
  require 'honeybadger/configuration'
@@ -12,7 +13,7 @@ require 'honeybadger/sender'
12
13
  require 'honeybadger/railtie' if defined?(Rails::Railtie)
13
14
 
14
15
  module Honeybadger
15
- VERSION = '1.6.2'
16
+ VERSION = '1.7.0'
16
17
  LOG_PREFIX = "** [Honeybadger] "
17
18
 
18
19
  HEADERS = {
@@ -138,6 +138,10 @@ module Honeybadger
138
138
  as_json.to_json(*a)
139
139
  end
140
140
 
141
+ def to_s
142
+ lines.map(&:to_s).join("\n")
143
+ end
144
+
141
145
  def inspect
142
146
  "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
143
147
  end
@@ -19,16 +19,20 @@ module Honeybadger
19
19
  rake_task = fetch(:honeybadger_deploy_task, 'honeybadger:deploy')
20
20
  local_user = ENV['USER'] || ENV['USERNAME']
21
21
  executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, 'rake.bat') : fetch(:rake, 'rake')
22
+ async_notify = fetch(:honeybadger_async_notify, false)
22
23
  directory = configuration.current_release
23
- notify_command = "cd #{directory}; #{executable} RAILS_ENV=#{rails_env} #{rake_task} TO=#{honeybadger_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
24
+ notify_command = "cd #{directory};"
25
+ notify_command << " nohup" if async_notify
26
+ notify_command << " #{executable} RAILS_ENV=#{rails_env} #{rake_task} TO=#{honeybadger_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
24
27
  notify_command << " DRY_RUN=true" if dry_run
25
28
  notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
29
+ notify_command << " >> /dev/null 2>&1 &" if async_notify
26
30
  logger.info "Notifying Honeybadger of Deploy (#{notify_command})"
27
31
  if configuration.dry_run
28
32
  logger.info "DRY RUN: Notification not actually run."
29
33
  else
30
34
  result = ""
31
- run(notify_command, :once => true) { |ch, stream, data| result << data }
35
+ run(notify_command, :once => true, :pty => false) { |ch, stream, data| result << data }
32
36
  # TODO: Check if SSL is active on account via result content.
33
37
  end
34
38
  logger.info "Honeybadger Notification Complete."
@@ -6,7 +6,7 @@ module Honeybadger
6
6
  :params_filters, :project_root, :port, :protocol, :proxy_host, :proxy_pass,
7
7
  :proxy_port, :proxy_user, :secure, :use_system_ssl_cert_chain, :framework,
8
8
  :user_information, :rescue_rake_exceptions, :source_extract_radius,
9
- :send_request_session, :debug].freeze
9
+ :send_request_session, :debug, :fingerprint].freeze
10
10
 
11
11
  # The API key for your project, found on the project edit form.
12
12
  attr_accessor :api_key
@@ -101,6 +101,9 @@ module Honeybadger
101
101
  # A Proc object used to send notices asynchronously
102
102
  attr_writer :async
103
103
 
104
+ # A Proc object used to generate optional fingerprint
105
+ attr_writer :fingerprint
106
+
104
107
  DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
105
108
 
106
109
  DEFAULT_BACKTRACE_FILTERS = [
@@ -262,6 +265,24 @@ module Honeybadger
262
265
  end
263
266
  alias :async? :async
264
267
 
268
+ # Public: Generate custom fingerprint (optional)
269
+ #
270
+ # block - An optional block returning object responding to #to_s
271
+ #
272
+ # Examples
273
+ #
274
+ # config.fingerprint = Proc.new { |notice| ... }
275
+ #
276
+ # config.fingerprint do |notice|
277
+ # [notice[:error_class], notice[:component], notice[:backtrace].to_s].join(':')
278
+ # end
279
+ #
280
+ # Returns configured fingerprint generator (should respond to #call(notice))
281
+ def fingerprint
282
+ @fingerprint = Proc.new if block_given?
283
+ @fingerprint
284
+ end
285
+
265
286
  def port
266
287
  @port || default_port
267
288
  end
@@ -8,6 +8,9 @@ module Honeybadger
8
8
  # The backtrace from the given exception or hash.
9
9
  attr_reader :backtrace
10
10
 
11
+ # Custom fingerprint for error, used to group similar errors together (optional)
12
+ attr_reader :fingerprint
13
+
11
14
  # The name of the class of error (such as RuntimeError)
12
15
  attr_reader :error_class
13
16
 
@@ -100,6 +103,7 @@ module Honeybadger
100
103
  self.environment_name = args[:environment_name]
101
104
  self.cgi_data = args[:cgi_data] || args[:rack_env]
102
105
  self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller), :filters => self.backtrace_filters)
106
+ self.fingerprint = hashed_fingerprint
103
107
  self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
104
108
  self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
105
109
  "#{exception.class.name}: #{exception.message}"
@@ -121,8 +125,10 @@ module Honeybadger
121
125
 
122
126
  # Public: Send the notice to Honeybadger using the configured sender
123
127
  #
124
- # Returns a reference to the error in Honeybadger
128
+ # Returns a reference to the error in Honeybadger, false if sender isn't
129
+ # configured
125
130
  def deliver
131
+ return false unless Honeybadger.sender
126
132
  Honeybadger.sender.send_to_honeybadger(self)
127
133
  end
128
134
 
@@ -141,7 +147,8 @@ module Honeybadger
141
147
  :class => error_class,
142
148
  :message => error_message,
143
149
  :backtrace => backtrace,
144
- :source => source_extract
150
+ :source => source_extract,
151
+ :fingerprint => fingerprint
145
152
  },
146
153
  :request => {
147
154
  :url => url,
@@ -212,12 +219,12 @@ module Honeybadger
212
219
 
213
220
  private
214
221
 
215
- attr_writer :exception, :backtrace, :error_class, :error_message,
216
- :backtrace_filters, :parameters, :params_filters, :environment_filters,
217
- :session_data, :project_root, :url, :ignore, :ignore_by_filters,
218
- :notifier_name, :notifier_url, :notifier_version, :component, :action,
219
- :cgi_data, :environment_name, :hostname, :context, :source_extract,
220
- :source_extract_radius, :send_request_session
222
+ attr_writer :exception, :backtrace, :fingerprint, :error_class,
223
+ :error_message, :backtrace_filters, :parameters, :params_filters,
224
+ :environment_filters, :session_data, :project_root, :url, :ignore,
225
+ :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
226
+ :component, :action, :cgi_data, :environment_name, :hostname, :context,
227
+ :source_extract, :source_extract_radius, :send_request_session
221
228
 
222
229
  # Private: Arguments given in the initializer
223
230
  attr_accessor :args
@@ -295,6 +302,21 @@ module Honeybadger
295
302
  end
296
303
  end
297
304
 
305
+ def fingerprint_from_args
306
+ if args[:fingerprint].respond_to?(:call)
307
+ args[:fingerprint].call(self)
308
+ else
309
+ args[:fingerprint]
310
+ end
311
+ end
312
+
313
+ def hashed_fingerprint
314
+ fingerprint = fingerprint_from_args
315
+ if fingerprint && fingerprint.respond_to?(:to_s)
316
+ Digest::SHA1.hexdigest(fingerprint.to_s)
317
+ end
318
+ end
319
+
298
320
  def extract_source_from_backtrace
299
321
  if backtrace.lines.empty?
300
322
  nil
@@ -34,12 +34,17 @@ module Honeybadger
34
34
  #
35
35
  # Returns error id from successful response
36
36
  def send_to_honeybadger(notice)
37
+ if api_key.nil?
38
+ log(:error, "API key not found.")
39
+ return nil
40
+ end
41
+
37
42
  data = notice.is_a?(String) ? notice : notice.to_json
38
43
 
39
44
  http = setup_http_connection
40
45
  headers = HEADERS
41
46
 
42
- headers.merge!({ 'X-API-Key' => api_key}) unless api_key.nil?
47
+ headers.merge!({ 'X-API-Key' => api_key})
43
48
 
44
49
  response = begin
45
50
  http.post(url.path, data, headers)
@@ -31,13 +31,14 @@ namespace :honeybadger do
31
31
  namespace :heroku do
32
32
  desc "Install Heroku deploy notifications addon"
33
33
  task :add_deploy_notification => [:environment] do
34
- def heroku_var(var, app_name = nil)
34
+ def heroku_var(var, app_name, default = nil)
35
35
  app = app_name ? "--app #{app_name}" : ''
36
- `heroku config:get #{var} #{app} 2> /dev/null`.strip
36
+ result = `heroku config:get #{var} #{app} 2> /dev/null`.strip
37
+ result.split.find(lambda { default }) {|x| x =~ /\S/ }
37
38
  end
38
39
 
39
- heroku_rails_env = heroku_var('RAILS_ENV', ENV['APP'])
40
- heroku_api_key = heroku_var('HONEYBADGER_API_KEY', ENV['APP']).split.find(Honeybadger.configuration.api_key) {|x| x =~ /\S/ }
40
+ heroku_rails_env = heroku_var('RAILS_ENV', ENV['APP'], Honeybadger.configuration.environment_name)
41
+ heroku_api_key = heroku_var('HONEYBADGER_API_KEY', ENV['APP'], Honeybadger.configuration.api_key)
41
42
 
42
43
  unless heroku_api_key =~ /\S/ && heroku_rails_env =~ /\S/
43
44
  puts "WARNING: We were unable to detect the configuration from your Heroku environment."
@@ -29,6 +29,7 @@ class ConfigurationTest < Test::Unit::TestCase
29
29
  assert_config_default :async, nil
30
30
  assert_config_default :send_request_session, true
31
31
  assert_config_default :debug, false
32
+ assert_config_default :fingerprint, nil
32
33
  end
33
34
 
34
35
  should "configure async as Proc" do
@@ -48,6 +49,19 @@ class ConfigurationTest < Test::Unit::TestCase
48
49
  assert_equal config.async.call('foo'), 'foo'
49
50
  end
50
51
 
52
+ should "configure fingerprint as Proc" do
53
+ config = Honeybadger::Configuration.new
54
+ fingerprint_generator = Proc.new { |n| n[:error_class] }
55
+ config.fingerprint = fingerprint_generator
56
+ assert_equal config.fingerprint.call({ :error_class => 'foo' }), 'foo'
57
+ end
58
+
59
+ should "configure fingerprint with block" do
60
+ config = Honeybadger::Configuration.new
61
+ config.fingerprint { |n| n[:error_class] }
62
+ assert_equal config.fingerprint.call({ :error_class => 'foo' }), 'foo'
63
+ end
64
+
51
65
  should "stub current_user_method" do
52
66
  config = Honeybadger::Configuration.new
53
67
  assert_nothing_raised { config.current_user_method = :foo }
@@ -93,6 +107,7 @@ class ConfigurationTest < Test::Unit::TestCase
93
107
  assert_config_overridable :logger
94
108
  assert_config_overridable :source_extract_radius
95
109
  assert_config_overridable :async
110
+ assert_config_overridable :fingerprint
96
111
  assert_config_overridable :send_request_session
97
112
  assert_config_overridable :debug
98
113
  end
@@ -109,8 +124,8 @@ class ConfigurationTest < Test::Unit::TestCase
109
124
  :ignore_by_filters, :ignore_user_agent, :notifier_name, :notifier_url,
110
125
  :notifier_version, :params_filters, :project_root, :port, :protocol,
111
126
  :proxy_host, :proxy_pass, :proxy_port, :proxy_user, :secure,
112
- :source_extract_radius, :async, :send_request_session, :debug].each do |option|
113
- assert_equal config[option], hash[option], "Wrong value for #{option}"
127
+ :source_extract_radius, :async, :send_request_session, :debug, :fingerprint].each do |option|
128
+ assert_equal config[option], hash[option], "Wrong value for #{option}"
114
129
  end
115
130
  end
116
131
 
@@ -22,14 +22,26 @@ class NoticeTest < Test::Unit::TestCase
22
22
  :env => { 'three' => 'four' } }.update(attrs))
23
23
  end
24
24
 
25
- should "deliver to sender" do
26
- sender = stub_sender!
27
- notice = build_notice
28
- notice.stubs(:to_json => { :foo => 'bar' })
25
+ context '#deliver' do
26
+ context 'sender is configured' do
27
+ should "deliver to sender" do
28
+ sender = stub_sender!
29
+ notice = build_notice
30
+ notice.stubs(:to_json => { :foo => 'bar' })
31
+
32
+ notice.deliver
29
33
 
30
- notice.deliver
34
+ assert_received(sender, :send_to_honeybadger) { |expect| expect.with(notice) }
35
+ end
36
+ end
31
37
 
32
- assert_received(sender, :send_to_honeybadger) { |expect| expect.with(notice) }
38
+ context 'sender is not configured' do
39
+ should "return false" do
40
+ notice = build_notice
41
+ Honeybadger.sender = nil
42
+ assert_equal false, notice.deliver
43
+ end
44
+ end
33
45
  end
34
46
 
35
47
  should "generate json from as_json template" do
@@ -80,6 +92,28 @@ class NoticeTest < Test::Unit::TestCase
80
92
  assert_equal hostname, notice.hostname
81
93
  end
82
94
 
95
+ context "custom fingerprint" do
96
+ should "include nil fingerprint when no fingerprint is specified" do
97
+ notice = build_notice
98
+ assert_equal nil, notice.fingerprint
99
+ end
100
+
101
+ should "accept fingerprint as string" do
102
+ notice = build_notice({ :fingerprint => 'foo' })
103
+ assert_equal '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', notice.fingerprint
104
+ end
105
+
106
+ should "accept fingerprint responding to #call" do
107
+ notice = build_notice({ :fingerprint => mock(:call => 'foo') })
108
+ assert_equal '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', notice.fingerprint
109
+ end
110
+
111
+ should "accept fingerprint using #to_s" do
112
+ notice = build_notice({ :fingerprint => mock(:to_s => 'foo') })
113
+ assert_equal '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', notice.fingerprint
114
+ end
115
+ end
116
+
83
117
  context "with a backtrace" do
84
118
  setup do
85
119
  @source = <<-RUBY
@@ -71,6 +71,12 @@ class SenderTest < Test::Unit::TestCase
71
71
  assert_equal nil, send_exception(:secure => false)
72
72
  end
73
73
 
74
+ should "log missing API key and return nil" do
75
+ sender = build_sender({ :api_key => nil })
76
+ sender.expects(:log).with(:error, includes('API key'))
77
+ assert_equal nil, send_exception(:sender => sender, :secure => false)
78
+ end
79
+
74
80
  should "should log success" do
75
81
  http = stub_http
76
82
  sender = build_sender
metadata CHANGED
@@ -1,32 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.7.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Joshua Wood
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-04-10 00:00:00.000000000 Z
12
+ date: 2013-06-07 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: json
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - '>='
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - '>='
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: cucumber
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
@@ -34,6 +38,7 @@ dependencies:
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ~>
39
44
  - !ruby/object:Gem::Version
@@ -41,6 +46,7 @@ dependencies:
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: rspec
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - ~>
46
52
  - !ruby/object:Gem::Version
@@ -48,6 +54,7 @@ dependencies:
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - ~>
53
60
  - !ruby/object:Gem::Version
@@ -55,6 +62,7 @@ dependencies:
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: fakeweb
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
67
  - - ~>
60
68
  - !ruby/object:Gem::Version
@@ -62,6 +70,7 @@ dependencies:
62
70
  type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
75
  - - ~>
67
76
  - !ruby/object:Gem::Version
@@ -69,6 +78,7 @@ dependencies:
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: sham_rack
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
83
  - - ~>
74
84
  - !ruby/object:Gem::Version
@@ -76,6 +86,7 @@ dependencies:
76
86
  type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
91
  - - ~>
81
92
  - !ruby/object:Gem::Version
@@ -83,20 +94,23 @@ dependencies:
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: bourne
85
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
86
98
  requirements:
87
- - - '>='
99
+ - - ! '>='
88
100
  - !ruby/object:Gem::Version
89
101
  version: '1.0'
90
102
  type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
- - - '>='
107
+ - - ! '>='
95
108
  - !ruby/object:Gem::Version
96
109
  version: '1.0'
97
110
  - !ruby/object:Gem::Dependency
98
111
  name: shoulda
99
112
  requirement: !ruby/object:Gem::Requirement
113
+ none: false
100
114
  requirements:
101
115
  - - ~>
102
116
  - !ruby/object:Gem::Version
@@ -104,6 +118,7 @@ dependencies:
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
107
122
  requirements:
108
123
  - - ~>
109
124
  - !ruby/object:Gem::Version
@@ -111,71 +126,81 @@ dependencies:
111
126
  - !ruby/object:Gem::Dependency
112
127
  name: capistrano
113
128
  requirement: !ruby/object:Gem::Requirement
129
+ none: false
114
130
  requirements:
115
- - - '>='
131
+ - - ! '>='
116
132
  - !ruby/object:Gem::Version
117
133
  version: '0'
118
134
  type: :development
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
121
138
  requirements:
122
- - - '>='
139
+ - - ! '>='
123
140
  - !ruby/object:Gem::Version
124
141
  version: '0'
125
142
  - !ruby/object:Gem::Dependency
126
143
  name: rake
127
144
  requirement: !ruby/object:Gem::Requirement
145
+ none: false
128
146
  requirements:
129
- - - '>='
147
+ - - ! '>='
130
148
  - !ruby/object:Gem::Version
131
149
  version: '0'
132
150
  type: :development
133
151
  prerelease: false
134
152
  version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
135
154
  requirements:
136
- - - '>='
155
+ - - ! '>='
137
156
  - !ruby/object:Gem::Version
138
157
  version: '0'
139
158
  - !ruby/object:Gem::Dependency
140
159
  name: sinatra
141
160
  requirement: !ruby/object:Gem::Requirement
161
+ none: false
142
162
  requirements:
143
- - - '>='
163
+ - - ! '>='
144
164
  - !ruby/object:Gem::Version
145
165
  version: '0'
146
166
  type: :development
147
167
  prerelease: false
148
168
  version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
149
170
  requirements:
150
- - - '>='
171
+ - - ! '>='
151
172
  - !ruby/object:Gem::Version
152
173
  version: '0'
153
174
  - !ruby/object:Gem::Dependency
154
175
  name: aruba
155
176
  requirement: !ruby/object:Gem::Requirement
177
+ none: false
156
178
  requirements:
157
- - - '>='
179
+ - - ! '>='
158
180
  - !ruby/object:Gem::Version
159
181
  version: '0'
160
182
  type: :development
161
183
  prerelease: false
162
184
  version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
163
186
  requirements:
164
- - - '>='
187
+ - - ! '>='
165
188
  - !ruby/object:Gem::Version
166
189
  version: '0'
167
190
  - !ruby/object:Gem::Dependency
168
191
  name: appraisal
169
192
  requirement: !ruby/object:Gem::Requirement
193
+ none: false
170
194
  requirements:
171
- - - '>='
195
+ - - ! '>='
172
196
  - !ruby/object:Gem::Version
173
197
  version: '0'
174
198
  type: :development
175
199
  prerelease: false
176
200
  version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
177
202
  requirements:
178
- - - '>='
203
+ - - ! '>='
179
204
  - !ruby/object:Gem::Version
180
205
  version: '0'
181
206
  description: Make managing application errors a more pleasant experience.
@@ -267,7 +292,6 @@ files:
267
292
  - test/unit/sender_test.rb
268
293
  homepage: http://www.honeybadger.io
269
294
  licenses: []
270
- metadata: {}
271
295
  post_install_message:
272
296
  rdoc_options:
273
297
  - --charset=UTF-8
@@ -275,18 +299,23 @@ rdoc_options:
275
299
  require_paths:
276
300
  - lib
277
301
  required_ruby_version: !ruby/object:Gem::Requirement
302
+ none: false
278
303
  requirements:
279
- - - '>='
304
+ - - ! '>='
280
305
  - !ruby/object:Gem::Version
281
306
  version: '0'
307
+ segments:
308
+ - 0
309
+ hash: -2239778721023369939
282
310
  required_rubygems_version: !ruby/object:Gem::Requirement
311
+ none: false
283
312
  requirements:
284
- - - '>='
313
+ - - ! '>='
285
314
  - !ruby/object:Gem::Version
286
315
  version: '0'
287
316
  requirements: []
288
317
  rubyforge_project:
289
- rubygems_version: 2.0.3
318
+ rubygems_version: 1.8.23
290
319
  signing_key:
291
320
  specification_version: 2
292
321
  summary: Error reports you can be happy about.