stoplight 2.2.1 → 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 (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