stoplight 2.2.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -33
  3. data/lib/stoplight/color.rb +4 -4
  4. data/lib/stoplight/data_store/base.rb +10 -1
  5. data/lib/stoplight/data_store/memory.rb +27 -1
  6. data/lib/stoplight/data_store/redis.rb +61 -26
  7. data/lib/stoplight/data_store.rb +1 -1
  8. data/lib/stoplight/default.rb +3 -3
  9. data/lib/stoplight/error.rb +1 -1
  10. data/lib/stoplight/failure.rb +2 -2
  11. data/lib/stoplight/light/runnable.rb +16 -8
  12. data/lib/stoplight/light.rb +1 -1
  13. data/lib/stoplight/notifier/base.rb +1 -1
  14. data/lib/stoplight/notifier/bugsnag.rb +2 -2
  15. data/lib/stoplight/notifier/generic.rb +1 -1
  16. data/lib/stoplight/notifier/honeybadger.rb +2 -2
  17. data/lib/stoplight/notifier/io.rb +1 -1
  18. data/lib/stoplight/notifier/logger.rb +1 -1
  19. data/lib/stoplight/notifier/pagerduty.rb +1 -1
  20. data/lib/stoplight/notifier/raven.rb +2 -2
  21. data/lib/stoplight/notifier/rollbar.rb +1 -1
  22. data/lib/stoplight/notifier/slack.rb +1 -1
  23. data/lib/stoplight/notifier.rb +1 -1
  24. data/lib/stoplight/state.rb +4 -4
  25. data/lib/stoplight/version.rb +2 -2
  26. data/lib/stoplight.rb +2 -3
  27. data/spec/spec_helper.rb +2 -3
  28. data/spec/stoplight/color_spec.rb +1 -1
  29. data/spec/stoplight/data_store/base_spec.rb +8 -1
  30. data/spec/stoplight/data_store/memory_spec.rb +27 -1
  31. data/spec/stoplight/data_store/redis_spec.rb +37 -6
  32. data/spec/stoplight/data_store_spec.rb +1 -1
  33. data/spec/stoplight/default_spec.rb +1 -1
  34. data/spec/stoplight/error_spec.rb +1 -1
  35. data/spec/stoplight/failure_spec.rb +1 -1
  36. data/spec/stoplight/light/runnable_spec.rb +39 -9
  37. data/spec/stoplight/light_spec.rb +5 -5
  38. data/spec/stoplight/notifier/base_spec.rb +1 -1
  39. data/spec/stoplight/notifier/bugsnag_spec.rb +1 -1
  40. data/spec/stoplight/notifier/generic_spec.rb +1 -1
  41. data/spec/stoplight/notifier/honeybadger_spec.rb +1 -1
  42. data/spec/stoplight/notifier/io_spec.rb +1 -1
  43. data/spec/stoplight/notifier/logger_spec.rb +1 -1
  44. data/spec/stoplight/notifier/pagerduty_spec.rb +1 -1
  45. data/spec/stoplight/notifier/raven_spec.rb +1 -1
  46. data/spec/stoplight/notifier/rollbar_spec.rb +1 -1
  47. data/spec/stoplight/notifier/slack_spec.rb +2 -3
  48. data/spec/stoplight/notifier_spec.rb +1 -1
  49. data/spec/stoplight/state_spec.rb +1 -1
  50. data/spec/stoplight/version_spec.rb +1 -1
  51. data/spec/stoplight_spec.rb +1 -1
  52. metadata +79 -54
  53. data/lib/stoplight/notifier/hip_chat.rb +0 -43
  54. data/spec/stoplight/notifier/hip_chat_spec.rb +0 -92
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e26d25f913bb759dccd62f2b12576cbe51550753c3c6428fb16cdb6052559928
4
- data.tar.gz: 6cbfd0ccd62da40cb335e671c8ba2d84348652e206520355fa651eb2276e16ea
3
+ metadata.gz: 4ec8f5b8b13778f792ad1fbbbc3138229ef51ac4e62149f93eb3a8b4bccc9d3a
4
+ data.tar.gz: d93e27dbf0563bb30a7025bf646befe712269c4bd5f259432ffeeb8c680934da
5
5
  SHA512:
6
- metadata.gz: a186fc199cd54411996a65c369c687dc1165ecb2115699c72e6aa005f1b3d5b0da3b5f90402d2c49b12d73ca708628b09f5b9ba02e57c127ce89a33f8dc16cd2
7
- data.tar.gz: 7ee5b81cad78ed7aaa7200aedf74cba3af8aff5b1e95940c572ca93bbefa28676ceb507ef04ce63bef28d9b6e7dcb2590653dd06704cf14b561653662c9fa30b
6
+ metadata.gz: c3c10ff2886343b2625c777c5143656624df7591ab75e3bb8c8c43032fc10a92dacd9f2a801eebd7c636c5adc5a744525be76cb22f4acb4f839f6a87a6f8608b
7
+ data.tar.gz: 28af6a4a57af91a6d21df0b79909a4584acca9e5028079aff313911a965d3cb1da36b3a0b9c934b8621b6bd372e84da34d1fa47b47c043c10e27bb99a885c6f9
data/README.md CHANGED
@@ -4,7 +4,6 @@
4
4
  [![Build badge][]][build]
5
5
  [![Coverage badge][]][coverage]
6
6
  [![Climate badge][]][climate]
7
- [![Dependencies badge][]][dependencies]
8
7
 
9
8
  Stoplight is traffic control for code. It's an implementation of the circuit
10
9
  breaker pattern in Ruby.
@@ -29,7 +28,6 @@ Check out [stoplight-admin][] for controlling your stoplights.
29
28
  - [Redis](#redis)
30
29
  - [Notifiers](#notifiers)
31
30
  - [Bugsnag](#bugsnag)
32
- - [HipChat](#hipchat)
33
31
  - [Honeybadger](#honeybadger)
34
32
  - [Logger](#logger)
35
33
  - [Pagerduty](#pagerduty)
@@ -312,22 +310,6 @@ Stoplight::Light.default_notifiers += [notifier]
312
310
  # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Bugsnag:...>]
313
311
  ```
314
312
 
315
- #### HipChat
316
-
317
- Make sure you have [the HipChat gem][] (`~> 1.5`) installed before configuring
318
- Stoplight.
319
-
320
- ``` rb
321
- require 'hipchat'
322
- # => true
323
- hip_chat = HipChat::Client.new('token')
324
- # => #<HipChat::Client:...>
325
- notifier = Stoplight::Notifier::HipChat.new(hip_chat, 'room')
326
- # => #<Stoplight::Notifier::HipChat:...>
327
- Stoplight::Light.default_notifiers += [notifier]
328
- # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::HipChat:...>]
329
- ```
330
-
331
313
  #### Honeybadger
332
314
 
333
315
  Make sure you have [the Honeybadger gem][] (`~> 2.5`) installed before
@@ -495,31 +477,28 @@ stoplight = Stoplight("test-#{rand}") { ... }
495
477
 
496
478
  ## Credits
497
479
 
498
- Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][].
499
- A [complete list of contributors][] is available on GitHub. We were inspired by
500
- Martin Fowler's [CircuitBreaker][] article.
480
+ Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][]. [@bolshakov][] is the current
481
+ maintainer of the gem. A [complete list of contributors][] is available on GitHub. We were inspired by
482
+ Martin Fowler's [CircuitBreaker][] article.
501
483
 
502
484
  Stoplight is licensed under [the MIT License][].
503
485
 
504
- [Stoplight]: https://github.com/orgsync/stoplight
486
+ [Stoplight]: https://github.com/bolshakov/stoplight
505
487
  [Version badge]: https://img.shields.io/gem/v/stoplight.svg?label=version
506
488
  [version]: https://rubygems.org/gems/stoplight
507
- [Build badge]: https://img.shields.io/travis/orgsync/stoplight/master.svg?label=build
508
- [build]: https://travis-ci.org/orgsync/stoplight
509
- [Coverage badge]: https://img.shields.io/coveralls/orgsync/stoplight/master.svg?label=coverage
510
- [coverage]: https://coveralls.io/r/orgsync/stoplight
511
- [Climate badge]: https://img.shields.io/codeclimate/github/orgsync/stoplight.svg?label=climate
512
- [climate]: https://codeclimate.com/github/orgsync/stoplight
513
- [Dependencies badge]: https://img.shields.io/gemnasium/orgsync/stoplight.svg?label=dependencies
514
- [dependencies]: https://gemnasium.com/orgsync/stoplight
515
- [stoplight-admin]: https://github.com/orgsync/stoplight-admin
489
+ [Build badge]: https://github.com/bolshakov/stoplight/workflows/Specs/badge.svg
490
+ [build]: https://github.com/bolshakov/stoplight/actions?query=branch%3Amaster
491
+ [Coverage badge]: https://img.shields.io/coveralls/bolshakov/stoplight/master.svg?label=coverage
492
+ [coverage]: https://coveralls.io/r/bolshakov/stoplight
493
+ [Climate badge]: https://api.codeclimate.com/v1/badges/3451c2d281ffa345441a/maintainability
494
+ [climate]: https://codeclimate.com/github/bolshakov/stoplight
495
+ [stoplight-admin]: https://github.com/bolshakov/stoplight-admin
516
496
  [Semantic Versioning]: http://semver.org/spec/v2.0.0.html
517
497
  [the change log]: CHANGELOG.md
518
498
  [the notifiers section]: #notifiers
519
499
  [the cool off time section]: #custom-cool-off-time
520
500
  [the Redis gem]: https://rubygems.org/gems/redis
521
501
  [the Bugsnag gem]: https://rubygems.org/gems/bugsnag
522
- [the HipChat gem]: https://rubygems.org/gems/hipchat
523
502
  [the Honeybadger gem]: https://rubygems.org/gems/honeybadger
524
503
  [the Logger class]: http://ruby-doc.org/stdlib-2.2.3/libdoc/logger/rdoc/Logger.html
525
504
  [the Rollbar gem]: https://rubygems.org/gems/rollbar
@@ -529,6 +508,7 @@ Stoplight is licensed under [the MIT License][].
529
508
  [@camdez]: https://github.com/camdez
530
509
  [@tfausak]: https://github.com/tfausak
531
510
  [@orgsync]: https://github.com/OrgSync
532
- [complete list of contributors]: https://github.com/orgsync/stoplight/graphs/contributors
511
+ [@bolshakov]: https://github.com/bolshakov
512
+ [complete list of contributors]: https://github.com/bolshakov/stoplight/graphs/contributors
533
513
  [CircuitBreaker]: http://martinfowler.com/bliki/CircuitBreaker.html
534
514
  [the MIT license]: LICENSE.md
@@ -1,9 +1,9 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Color
5
- GREEN = 'green'.freeze
6
- YELLOW = 'yellow'.freeze
7
- RED = 'red'.freeze
5
+ GREEN = 'green'
6
+ YELLOW = 'yellow'
7
+ RED = 'red'
8
8
  end
9
9
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module DataStore
@@ -52,6 +52,15 @@ module Stoplight
52
52
  def clear_state(_light)
53
53
  raise NotImplementedError
54
54
  end
55
+
56
+ # @param _light [Light]
57
+ # @param _from_color [String]
58
+ # @param _to_color [String]
59
+ # @yield _block
60
+ # @return [Void]
61
+ def with_notification_lock(_light, _from_color, _to_color, &_block)
62
+ raise NotImplementedError
63
+ end
55
64
  end
56
65
  end
57
66
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'monitor'
4
4
 
@@ -7,10 +7,12 @@ module Stoplight
7
7
  # @see Base
8
8
  class Memory < Base
9
9
  include MonitorMixin
10
+ KEY_SEPARATOR = ':'
10
11
 
11
12
  def initialize
12
13
  @failures = Hash.new { |h, k| h[k] = [] }
13
14
  @states = Hash.new { |h, k| h[k] = State::UNLOCKED }
15
+ @last_notifications = {}
14
16
  super() # MonitorMixin
15
17
  end
16
18
 
@@ -49,6 +51,30 @@ module Stoplight
49
51
  def clear_state(light)
50
52
  synchronize { @states.delete(light.name) }
51
53
  end
54
+
55
+ def with_notification_lock(light, from_color, to_color)
56
+ synchronize do
57
+ if last_notification(light) != [from_color, to_color]
58
+ set_last_notification(light, from_color, to_color)
59
+
60
+ yield
61
+ end
62
+ end
63
+ end
64
+
65
+ # @param light [Stoplight::Light]
66
+ # @return [Array, nil]
67
+ def last_notification(light)
68
+ @last_notifications[light.name]
69
+ end
70
+
71
+ # @param light [Stoplight::Light]
72
+ # @param from_color [String]
73
+ # @param to_color [String]
74
+ # @return [void]
75
+ def set_last_notification(light, from_color, to_color)
76
+ @last_notifications[light.name] = [from_color, to_color]
77
+ end
52
78
  end
53
79
  end
54
80
  end
@@ -1,15 +1,18 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require 'redlock'
2
4
 
3
5
  module Stoplight
4
6
  module DataStore
5
7
  # @see Base
6
8
  class Redis < Base
7
- KEY_PREFIX = 'stoplight'.freeze
8
- KEY_SEPARATOR = ':'.freeze
9
+ KEY_PREFIX = 'stoplight'
10
+ KEY_SEPARATOR = ':'
9
11
 
10
12
  # @param redis [::Redis]
11
- def initialize(redis)
13
+ def initialize(redis, redlock: Redlock::Client.new([redis]))
12
14
  @redis = redis
15
+ @redlock = redlock
13
16
  end
14
17
 
15
18
  def names
@@ -25,9 +28,9 @@ module Stoplight
25
28
  end
26
29
 
27
30
  def get_all(light)
28
- failures, state = @redis.multi do
29
- query_failures(light)
30
- @redis.hget(states_key, light.name)
31
+ failures, state = @redis.multi do |transaction|
32
+ query_failures(light, transaction: transaction)
33
+ transaction.hget(states_key, light.name)
31
34
  end
32
35
 
33
36
  [
@@ -41,18 +44,18 @@ module Stoplight
41
44
  end
42
45
 
43
46
  def record_failure(light, failure)
44
- size, = @redis.multi do
45
- @redis.lpush(failures_key(light), failure.to_json)
46
- @redis.ltrim(failures_key(light), 0, light.threshold - 1)
47
+ size, = @redis.multi do |transaction|
48
+ transaction.lpush(failures_key(light), failure.to_json)
49
+ transaction.ltrim(failures_key(light), 0, light.threshold - 1)
47
50
  end
48
51
 
49
52
  size
50
53
  end
51
54
 
52
55
  def clear_failures(light)
53
- failures, = @redis.multi do
54
- query_failures(light)
55
- @redis.del(failures_key(light))
56
+ failures, = @redis.multi do |transaction|
57
+ query_failures(light, transaction: transaction)
58
+ transaction.del(failures_key(light))
56
59
  end
57
60
 
58
61
  normalize_failures(failures, light.error_notifier)
@@ -68,33 +71,57 @@ module Stoplight
68
71
  end
69
72
 
70
73
  def clear_state(light)
71
- state, = @redis.multi do
72
- query_state(light)
73
- @redis.hdel(states_key, light.name)
74
+ state, = @redis.multi do |transaction|
75
+ query_state(light, transaction: transaction)
76
+ transaction.hdel(states_key, light.name)
74
77
  end
75
78
 
76
79
  normalize_state(state)
77
80
  end
78
81
 
82
+ LOCK_TTL = 2_000 # milliseconds
83
+
84
+ def with_notification_lock(light, from_color, to_color)
85
+ @redlock.lock(notification_lock_key(light), LOCK_TTL) do
86
+ if last_notification(light) != [from_color, to_color]
87
+ set_last_notification(light, from_color, to_color)
88
+
89
+ yield
90
+ end
91
+ end
92
+ end
93
+
79
94
  private
80
95
 
81
- def query_failures(light)
82
- @redis.lrange(failures_key(light), 0, -1)
96
+ # @param light [Stoplight::Light]
97
+ # @return [Array, nil]
98
+ def last_notification(light)
99
+ @redis.get(last_notification_key(light))&.split('->')
100
+ end
101
+
102
+ # @param light [Stoplight::Light]
103
+ # @param from_color [String]
104
+ # @param to_color [String]
105
+ # @return [void]
106
+ def set_last_notification(light, from_color, to_color)
107
+ @redis.set(last_notification_key(light), [from_color, to_color].join('->'))
108
+ end
109
+
110
+ def query_failures(light, transaction: @redis)
111
+ transaction.lrange(failures_key(light), 0, -1)
83
112
  end
84
113
 
85
114
  def normalize_failures(failures, error_notifier)
86
115
  failures.map do |json|
87
- begin
88
- Failure.from_json(json)
89
- rescue => error
90
- error_notifier.call(error)
91
- Failure.from_error(error)
92
- end
116
+ Failure.from_json(json)
117
+ rescue StandardError => e
118
+ error_notifier.call(e)
119
+ Failure.from_error(e)
93
120
  end
94
121
  end
95
122
 
96
- def query_state(light)
97
- @redis.hget(states_key, light.name)
123
+ def query_state(light, transaction: @redis)
124
+ transaction.hget(states_key, light.name)
98
125
  end
99
126
 
100
127
  def normalize_state(state)
@@ -105,6 +132,14 @@ module Stoplight
105
132
  key('failures', light.name)
106
133
  end
107
134
 
135
+ def notification_lock_key(light)
136
+ key('notification_lock', light.name)
137
+ end
138
+
139
+ def last_notification_key(light)
140
+ key('last_notification', light.name)
141
+ end
142
+
108
143
  def states_key
109
144
  key('states')
110
145
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module DataStore # rubocop:disable Style/Documentation
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Default
@@ -6,9 +6,9 @@ module Stoplight
6
6
 
7
7
  DATA_STORE = DataStore::Memory.new
8
8
 
9
- ERROR_HANDLER = -> (error, handler) { handler.call(error) }
9
+ ERROR_HANDLER = ->(error, handler) { handler.call(error) }
10
10
 
11
- ERROR_NOTIFIER = -> (error) { warn error }
11
+ ERROR_NOTIFIER = ->(error) { warn error }
12
12
 
13
13
  FALLBACK = nil
14
14
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Error
@@ -1,11 +1,11 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
4
  require 'time'
5
5
 
6
6
  module Stoplight
7
7
  class Failure # rubocop:disable Style/Documentation
8
- TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'.freeze
8
+ TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'
9
9
 
10
10
  # @return [String]
11
11
  attr_reader :error_class
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  class Light
@@ -30,11 +30,15 @@ module Stoplight
30
30
 
31
31
  def run_green
32
32
  on_failure = lambda do |size, error|
33
- notify(Color::GREEN, Color::RED, error) if size == threshold
33
+ notify(Color::GREEN, Color::RED, error) if failures_threshold_breached?(size, threshold)
34
34
  end
35
35
  run_code(nil, on_failure)
36
36
  end
37
37
 
38
+ def failures_threshold_breached?(current_failures_count, max_errors_threshold)
39
+ current_failures_count == max_errors_threshold
40
+ end
41
+
38
42
  def run_yellow
39
43
  on_success = lambda do |failures|
40
44
  notify(Color::RED, Color::GREEN) unless failures.empty?
@@ -44,23 +48,25 @@ module Stoplight
44
48
 
45
49
  def run_red
46
50
  raise Error::RedLight, name unless fallback
51
+
47
52
  fallback.call(nil)
48
53
  end
49
54
 
50
55
  def run_code(on_success, on_failure)
51
56
  result = code.call
52
57
  failures = clear_failures
53
- on_success.call(failures) if on_success
58
+ on_success&.call(failures)
54
59
  result
55
- rescue Exception => error # rubocop:disable Lint/RescueException
56
- handle_error(error, on_failure)
60
+ rescue Exception => e # rubocop:disable Lint/RescueException
61
+ handle_error(e, on_failure)
57
62
  end
58
63
 
59
64
  def handle_error(error, on_failure)
60
65
  error_handler.call(error, Error::HANDLER)
61
66
  size = record_failure(error)
62
- on_failure.call(size, error) if on_failure
67
+ on_failure&.call(size, error)
63
68
  raise error unless fallback
69
+
64
70
  fallback.call(error)
65
71
  end
66
72
 
@@ -73,8 +79,10 @@ module Stoplight
73
79
  end
74
80
 
75
81
  def notify(from_color, to_color, error = nil)
76
- notifiers.each do |notifier|
77
- safely { notifier.notify(self, from_color, to_color, error) }
82
+ data_store.with_notification_lock(self, from_color, to_color) do
83
+ notifiers.each do |notifier|
84
+ safely { notifier.notify(self, from_color, to_color, error) }
85
+ end
78
86
  end
79
87
  end
80
88
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  class Light # rubocop:disable Style/Documentation
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -29,7 +29,7 @@ module Stoplight
29
29
 
30
30
  def notify(light, from_color, to_color, error)
31
31
  message = formatter.call(light, from_color, to_color, error)
32
- bugsnag.notify(StoplightStatusChange.new(message), options)
32
+ bugsnag.notify(StoplightStatusChange.new(message), **options)
33
33
  message
34
34
  end
35
35
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -34,7 +34,7 @@ module Stoplight
34
34
  h = options.merge(
35
35
  api_key: api_key,
36
36
  error_message: message,
37
- backtrace: (error.backtrace if error)
37
+ backtrace: error&.backtrace
38
38
  )
39
39
  ::Honeybadger.notify(h)
40
40
  message
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -30,7 +30,7 @@ module Stoplight
30
30
 
31
31
  h = options.merge(
32
32
  configuration: configuration,
33
- backtrace: (error.backtrace if error)
33
+ backtrace: error&.backtrace
34
34
  )
35
35
  ::Raven.capture_message(message, h)
36
36
  message
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier # rubocop:disable Style/Documentation
@@ -1,9 +1,9 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module State
5
- UNLOCKED = 'unlocked'.freeze
6
- LOCKED_GREEN = 'locked_green'.freeze
7
- LOCKED_RED = 'locked_red'.freeze
5
+ UNLOCKED = 'unlocked'
6
+ LOCKED_GREEN = 'locked_green'
7
+ LOCKED_RED = 'locked_red'
8
8
  end
9
9
  end
@@ -1,5 +1,5 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
- VERSION = Gem::Version.new('2.2.1')
4
+ VERSION = Gem::Version.new('3.0.1')
5
5
  end
data/lib/stoplight.rb CHANGED
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight # rubocop:disable Style/Documentation
4
4
  end
@@ -20,7 +20,6 @@ require 'stoplight/notifier/base'
20
20
  require 'stoplight/notifier/generic'
21
21
 
22
22
  require 'stoplight/notifier/bugsnag'
23
- require 'stoplight/notifier/hip_chat'
24
23
  require 'stoplight/notifier/honeybadger'
25
24
  require 'stoplight/notifier/io'
26
25
  require 'stoplight/notifier/logger'
@@ -35,6 +34,6 @@ require 'stoplight/light/runnable'
35
34
  require 'stoplight/light'
36
35
 
37
36
  # @see Stoplight::Light#initialize
38
- def Stoplight(name, &code) # rubocop:disable Style/MethodName
37
+ def Stoplight(name, &code) # rubocop:disable Naming/MethodName
39
38
  Stoplight::Light.new(name, &code)
40
39
  end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,6 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'coveralls'
4
- Coveralls.wear!
3
+ require 'simplecov'
5
4
 
6
5
  require 'stoplight'
7
6
  require 'timecop'
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -61,4 +61,11 @@ RSpec.describe Stoplight::DataStore::Base do
61
61
  .to raise_error(NotImplementedError)
62
62
  end
63
63
  end
64
+
65
+ describe '#with_notification_lock' do
66
+ it 'is not implemented' do
67
+ expect { data_store.with_notification_lock(nil, nil, nil) }
68
+ .to raise_error(NotImplementedError)
69
+ end
70
+ end
64
71
  end