deprecation_toolkit 1.5.1 → 2.2.3
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.
- checksums.yaml +4 -4
- data/README.md +67 -13
- data/lib/deprecation_toolkit/behaviors/ci_record_helper.rb +5 -4
- data/lib/deprecation_toolkit/behaviors/disabled.rb +4 -2
- data/lib/deprecation_toolkit/behaviors/raise.rb +10 -4
- data/lib/deprecation_toolkit/behaviors/record.rb +3 -2
- data/lib/deprecation_toolkit/collector.rb +14 -6
- data/lib/deprecation_toolkit/configuration.rb +9 -0
- data/lib/deprecation_toolkit/deprecation_subscriber.rb +57 -6
- data/lib/deprecation_toolkit/read_write_helper.rb +3 -7
- data/lib/deprecation_toolkit/rspec_plugin.rb +12 -6
- data/lib/deprecation_toolkit/test_triggerer.rb +3 -1
- data/lib/deprecation_toolkit/version.rb +1 -1
- data/lib/deprecation_toolkit/warning.rb +21 -35
- data/lib/deprecation_toolkit.rb +30 -15
- data/lib/minitest/deprecation_toolkit_plugin.rb +7 -2
- data/lib/tasks/ci_recorder.rake +10 -9
- metadata +8 -90
- data/.gitignore +0 -10
- data/.rspec +0 -4
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1017
- data/.rubocop.yml +0 -12
- data/.travis.yml +0 -18
- data/CHANGELOG.md +0 -42
- data/Gemfile +0 -10
- data/Gemfile.lock +0 -69
- data/Rakefile +0 -13
- data/deprecation_toolkit.gemspec +0 -36
- data/gemfiles/activesupport_5.2.gemfile +0 -11
- data/gemfiles/activesupport_6.0.gemfile +0 -11
- data/gemfiles/spec/deprecations/deprecation_toolkit/behaviors/raise.yml +0 -12
- data/gemfiles/test/deprecations +0 -1
- data/shipit.rubygems.yml +0 -1
- data/spec/deprecation_toolkit/behaviors/disabled_spec.rb +0 -23
- data/spec/deprecation_toolkit/behaviors/raise_spec.rb +0 -96
- data/spec/deprecation_toolkit/behaviors/record_spec.rb +0 -71
- data/spec/deprecations/deprecation_toolkit/behaviors/raise.yml +0 -12
- data/spec/rspec/plugin_env_options_spec.rb +0 -13
- data/spec/rspec/plugin_spec.rb +0 -18
- data/spec/spec_helper.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7b57fe6f900e79cc13938de52e802aaff9ab51dfe546d5f9e1cdc0a9ec6c4648
|
|
4
|
+
data.tar.gz: 61ca80ab4fd5d2337b83cba6af0d53dd1af734957487fcf78d1677ca6b2205d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cff2de2f59cb48d1d96b4f39c5c4cdc601d2fdf512d990794e09cf791ef49c7ca8ada4effaa1c19ce0cecc53d535cace10a32eb443abc2a04ac5ca831118dc4c
|
|
7
|
+
data.tar.gz: 9fc7fda9a92dd4f73af1297200b81c20825b5f37529ce8f808c2a3b6e1f777586d0fba83b5982d978222c8f90b9a24e473107456d39d8758df91d775ac821d7b
|
data/README.md
CHANGED
|
@@ -6,10 +6,9 @@ Deprecation Toolkit is a gem that helps you get rid of deprecations in your code
|
|
|
6
6
|
Having deprecations in your application usually means that something will break whenever you upgrade third-party dependencies. The sooner the better to fix them!
|
|
7
7
|
Fixing all deprecations at once might be tough depending on the size of your app and the number of deprecations. You might have to progressively resolve them while making sure your team doesn't add new ones. This is where this gem comes handy!
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
## How it works
|
|
11
10
|
|
|
12
|
-
The Deprecation Toolkit gem works by using a [shitlist approach](https://
|
|
11
|
+
The Deprecation Toolkit gem works by using a [shitlist approach](https://www.youtube.com/watch?v=20pj_ajDBOg).
|
|
13
12
|
First, the gem records all existing deprecations into `.yml` files. When running a test that have non-recorded deprecations after the initial recording, Deprecation Toolkit triggers a behavior of your choice (by default it raises an error).
|
|
14
13
|
|
|
15
14
|
## Recording Deprecations
|
|
@@ -44,15 +43,13 @@ end
|
|
|
44
43
|
|
|
45
44
|
Behaviors define what happens when non-recorded deprecations are encountered.
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
This gem provides 3 behaviors, the default one being `DeprecationToolkit::Behaviors::Raise`.
|
|
46
|
+
This gem provides 4 behaviors, the default one being `DeprecationToolkit::Behaviors::Raise`.
|
|
50
47
|
|
|
51
48
|
* `DeprecationToolkit::Behaviors::Raise` will raise either:
|
|
52
|
-
- `DeprecationToolkit::DeprecationIntroduced` error if a new deprecation is introduced.
|
|
53
|
-
- `DeprecationToolkit::DeprecationRemoved` error if a deprecation was removed (compare to the one recorded in the shitlist).
|
|
49
|
+
- `DeprecationToolkit::Behaviors::DeprecationIntroduced` error if a new deprecation is introduced.
|
|
50
|
+
- `DeprecationToolkit::Behaviors::DeprecationRemoved` error if a deprecation was removed (compare to the one recorded in the shitlist).
|
|
54
51
|
* `DeprecationToolkit::Behaviors::Record` will record deprecations.
|
|
55
|
-
* `DeprecationToolkit::Behaviors::CIRecordHelper` See
|
|
52
|
+
* `DeprecationToolkit::Behaviors::CIRecordHelper` See separate explanation below.
|
|
56
53
|
* `DeprecationToolkit::Behaviors::Disabled` will do nothing.
|
|
57
54
|
- This is useful if you want to disable this gem for a moment without removing the gem from your Gemfile.
|
|
58
55
|
|
|
@@ -60,25 +57,25 @@ This gem provides 3 behaviors, the default one being `DeprecationToolkit::Behavi
|
|
|
60
57
|
DeprecationToolkit::Configuration.behavior = DeprecationToolkit::Behaviors::Record
|
|
61
58
|
```
|
|
62
59
|
|
|
63
|
-
You can also create your own behavior
|
|
60
|
+
You can also create your own behavior object and perform the logic you want. Your behavior needs to respond to `trigger`.
|
|
64
61
|
|
|
65
62
|
```ruby
|
|
66
63
|
class StatsdBehavior
|
|
67
|
-
def
|
|
64
|
+
def trigger(test, deprecations, recorded_deprecations)
|
|
68
65
|
# Could send some statsd event for example
|
|
69
66
|
end
|
|
70
67
|
end
|
|
71
68
|
|
|
72
|
-
DeprecationToolkit::Configuration.behavior = StatsdBehavior
|
|
69
|
+
DeprecationToolkit::Configuration.behavior = StatsdBehavior.new
|
|
73
70
|
```
|
|
74
71
|
|
|
75
|
-
|
|
72
|
+
#### DeprecationToolkit::Behaviors::CIRecordHelper
|
|
76
73
|
|
|
77
74
|
This is a special type of behaviour meant to help you record deprecations if you have a lof of them.
|
|
78
75
|
Imagine if you have thousands of tests and need to record deprecations for each on your machine, this is going to take ages.
|
|
79
76
|
Recording deprecations on CI with the regular `Record` behavior isn't possible because of the way CI parallelize test in multiple container (Multiple tests from the same file runs in parallel in diferrent machines, the deprecation files that get created are then splitted. Regrouping them is a nightmare.)
|
|
80
77
|
|
|
81
|
-
This
|
|
78
|
+
This behavior will output a JSON representation of your deprecations. Your CI should have a way to download the log generated from the test run. Download it on your locale machine. Finally run the rake task `FILEPATH=<path_to_downloaded_log> deprecation_toolkit:record_from_ci_output`.
|
|
82
79
|
This task will parse your CI log and grab the output generated by the DeprecationToolkit and will finally convert everything back to YML files.
|
|
83
80
|
|
|
84
81
|
### 🔨 `#DeprecationToolkit::Configuration#allowed_deprecations`
|
|
@@ -114,6 +111,44 @@ a message in the console.
|
|
|
114
111
|
Deprecation Toolkit allows you to configure which warnings should be treated as deprecations in order for you
|
|
115
112
|
to keep track of them as if they were regular deprecations.
|
|
116
113
|
|
|
114
|
+
This setting accepts an array of regular expressions. To match on all warnings, you can provide a empty regex:
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
DeprecationToolkit::Configuration.warnings_treated_as_deprecation = [//]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
In addition to regexps, anything that responds to `===` can be a matcher, for instance a proc:
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
DeprecationToolkit::Configuration.warnings_treated_as_deprecation = [
|
|
124
|
+
->(warning) { !warning.match?(/not a deprecation/)}
|
|
125
|
+
]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 🔨 `#DeprecationToolkit::Configuration#deprecation_file_path_format`
|
|
129
|
+
|
|
130
|
+
DeprecationToolkit allows you to choose the file path format for deprecation files.
|
|
131
|
+
|
|
132
|
+
For Minitest, it defaults to using class name so the following code would correspond to `#{deprecation_path}/deprecation_toolkit/behaviors/raise_test.yml`
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
module DeprecationToolkit
|
|
136
|
+
module Behaviors
|
|
137
|
+
class RaiseTest < ActiveSupport::TestCase
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
For rspec if defaults to the file location with spec removed. `/spec/models/user_spec.rb` would correspond to `/models/user.yml`.
|
|
144
|
+
|
|
145
|
+
If you have a specific use case you can configure this with a custom format using a proc. The proc is called with an instance of the test.
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
Configuration.deprecation_file_path_format = -> (test) do
|
|
149
|
+
Kernel.const_source_location(test.class.name)[0].sub(%r{^./test/}, "").sub(/_test.rb$/, "")
|
|
150
|
+
end
|
|
151
|
+
```
|
|
117
152
|
|
|
118
153
|
## RSpec
|
|
119
154
|
|
|
@@ -135,6 +170,25 @@ It's possible to record deprecations while running your specs by adding an ENV['
|
|
|
135
170
|
DEPRECATION_BEHAVIOR="record" bundle exec rspec path/to/file_spec.rb
|
|
136
171
|
```
|
|
137
172
|
|
|
173
|
+
## Usage without Rails
|
|
174
|
+
|
|
175
|
+
Without Rails, you'll need to make sure your `ActiveSupport::Deprecation` instances use the [`:notify` behavior](https://api.rubyonrails.org/classes/ActiveSupport/Deprecation/Behavior.html#method-i-behavior-3D) and the `attach_to` is the underscored version of the deprecator's `gem_name` (this is how the `:notify` behavior works):
|
|
176
|
+
|
|
177
|
+
```ruby
|
|
178
|
+
# defined in the gem:
|
|
179
|
+
MyGem.deprecator = ActiveSupport::Deprecation.new("2.0", "MyGem::Something")
|
|
180
|
+
|
|
181
|
+
# in the test helper:
|
|
182
|
+
MyGem.deprecator.behavior = :notify
|
|
183
|
+
|
|
184
|
+
DeprecationToolkit::Configuration.configure do |config|
|
|
185
|
+
config.attach_to = MyGem.deprecator.gem_name.underscore.tr("/", "_")
|
|
186
|
+
# or more simply
|
|
187
|
+
# config.attach_to = "my_gem_something"
|
|
188
|
+
config.behavior = :notify
|
|
189
|
+
end
|
|
190
|
+
```
|
|
191
|
+
|
|
138
192
|
## License
|
|
139
193
|
|
|
140
194
|
Deprecation Toolkit is licensed under the [MIT license](LICENSE.txt).
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "json"
|
|
4
4
|
|
|
5
5
|
module DeprecationToolkit
|
|
6
6
|
module Behaviors
|
|
7
|
-
|
|
7
|
+
module CIRecordHelper
|
|
8
|
+
extend self
|
|
8
9
|
extend ReadWriteHelper
|
|
9
10
|
|
|
10
|
-
HEADER =
|
|
11
|
+
HEADER = "[DeprecationToolkit]"
|
|
11
12
|
|
|
12
|
-
def
|
|
13
|
+
def trigger(test, current_deprecations, _recorded_deprecations)
|
|
13
14
|
filename = recorded_deprecations_path(test)
|
|
14
15
|
|
|
15
16
|
to_output = {
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module DeprecationToolkit
|
|
4
4
|
module Behaviors
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
module Raise
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
def trigger(_test, current_deprecations, recorded_deprecations)
|
|
7
9
|
error_class = if current_deprecations.size > recorded_deprecations.size
|
|
8
10
|
DeprecationIntroduced
|
|
9
11
|
elsif current_deprecations.size < recorded_deprecations.size
|
|
@@ -32,7 +34,9 @@ module DeprecationToolkit
|
|
|
32
34
|
You have introduced new deprecations in the codebase. Fix or record them in order to discard this error.
|
|
33
35
|
#{record_message}
|
|
34
36
|
|
|
37
|
+
******* The following deprecations were added: *******
|
|
35
38
|
#{introduced_deprecations.join("\n")}
|
|
39
|
+
******************************************************
|
|
36
40
|
EOM
|
|
37
41
|
|
|
38
42
|
super(message)
|
|
@@ -55,7 +59,9 @@ module DeprecationToolkit
|
|
|
55
59
|
The recorded deprecations needs to be updated to reflect your changes.
|
|
56
60
|
#{record_message}
|
|
57
61
|
|
|
62
|
+
****** The following deprecations were removed: ******
|
|
58
63
|
#{removed_deprecations.join("\n")}
|
|
64
|
+
******************************************************
|
|
59
65
|
EOM
|
|
60
66
|
|
|
61
67
|
super(message)
|
|
@@ -77,9 +83,9 @@ module DeprecationToolkit
|
|
|
77
83
|
#{record_message}
|
|
78
84
|
|
|
79
85
|
===== Expected
|
|
80
|
-
#{recorded_deprecations.
|
|
86
|
+
#{recorded_deprecations.deprecations_without_stacktrace.join("\n")}
|
|
81
87
|
===== Actual
|
|
82
|
-
#{current_deprecations.
|
|
88
|
+
#{current_deprecations.deprecations_without_stacktrace.join("\n")}
|
|
83
89
|
EOM
|
|
84
90
|
|
|
85
91
|
super(message)
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module DeprecationToolkit
|
|
4
4
|
module Behaviors
|
|
5
|
-
|
|
5
|
+
module Record
|
|
6
|
+
extend self
|
|
6
7
|
extend ReadWriteHelper
|
|
7
8
|
|
|
8
|
-
def
|
|
9
|
+
def trigger(test, collector, _)
|
|
9
10
|
deprecation_file = recorded_deprecations_path(test)
|
|
10
11
|
|
|
11
12
|
write(deprecation_file, test_name(test) => collector.deprecations_without_stacktrace)
|
|
@@ -35,11 +35,9 @@ module DeprecationToolkit
|
|
|
35
35
|
|
|
36
36
|
def deprecations_without_stacktrace
|
|
37
37
|
deprecations.map do |deprecation|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
deprecation.sub(/ \(called from .*\)$/, "")
|
|
42
|
-
end
|
|
38
|
+
deprecation
|
|
39
|
+
.sub(*active_support_deprecation_sub_params)
|
|
40
|
+
.sub(*gem_deprecate_sub_params)
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
|
|
@@ -61,7 +59,17 @@ module DeprecationToolkit
|
|
|
61
59
|
end
|
|
62
60
|
|
|
63
61
|
def flaky?
|
|
64
|
-
size == 1 && deprecations.first[
|
|
62
|
+
size == 1 && deprecations.first["flaky"] == true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def active_support_deprecation_sub_params
|
|
68
|
+
[/ \(called from .*\)$/, ""]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def gem_deprecate_sub_params
|
|
72
|
+
[/NOTE: (.*is deprecated.*)\n.* called from.*:\d+\.\n/, "\\1"]
|
|
65
73
|
end
|
|
66
74
|
end
|
|
67
75
|
end
|
|
@@ -12,5 +12,14 @@ module DeprecationToolkit
|
|
|
12
12
|
config_accessor(:deprecation_path) { "test/deprecations" }
|
|
13
13
|
config_accessor(:test_runner) { :minitest }
|
|
14
14
|
config_accessor(:warnings_treated_as_deprecation) { [] }
|
|
15
|
+
config_accessor(:deprecation_file_path_format) do
|
|
16
|
+
proc do |test|
|
|
17
|
+
if DeprecationToolkit::Configuration.test_runner == :rspec
|
|
18
|
+
test.example_group.file_path.sub(%r{^./spec/}, "").sub(/_spec.rb$/, "")
|
|
19
|
+
else
|
|
20
|
+
test.class.name.underscore
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
15
24
|
end
|
|
16
25
|
end
|
|
@@ -4,8 +4,56 @@ require "active_support/subscriber"
|
|
|
4
4
|
|
|
5
5
|
module DeprecationToolkit
|
|
6
6
|
class DeprecationSubscriber < ActiveSupport::Subscriber
|
|
7
|
-
|
|
8
|
-
notifier
|
|
7
|
+
class << self
|
|
8
|
+
def attach_to(gem_name, subscriber = new, notifier = ActiveSupport::Notifications, inherit_all: false)
|
|
9
|
+
return if already_attached_to?(gem_name)
|
|
10
|
+
|
|
11
|
+
super(gem_name, subscriber, notifier, inherit_all: inherit_all)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def detach_from(gem_name, notifier = ActiveSupport::Notifications)
|
|
15
|
+
@namespace = gem_name
|
|
16
|
+
@subscriber = find_attached_subscriber(gem_name)
|
|
17
|
+
@notifier = notifier
|
|
18
|
+
|
|
19
|
+
return unless subscriber
|
|
20
|
+
|
|
21
|
+
subscribers.delete(subscriber)
|
|
22
|
+
|
|
23
|
+
# Remove event subscribers of all existing methods on the class.
|
|
24
|
+
fetch_public_methods(subscriber, true).each do |event|
|
|
25
|
+
remove_event_subscriber(event)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@notifier = nil unless any_subscribers_attached?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def already_attached_to?(gem_name)
|
|
34
|
+
subscribers.any? do |subscriber|
|
|
35
|
+
attached_subscriber?(subscriber, gem_name)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def any_subscribers_attached?
|
|
40
|
+
subscribers.any? do |subscriber|
|
|
41
|
+
subscriber.is_a?(self)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def find_attached_subscriber(gem_name)
|
|
46
|
+
subscribers.find do |attached_subscriber|
|
|
47
|
+
attached_subscriber?(attached_subscriber, gem_name)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def attached_subscriber?(subscriber, gem_name)
|
|
52
|
+
subscriber.is_a?(self) &&
|
|
53
|
+
subscriber.patterns.keys.any? do |pattern|
|
|
54
|
+
pattern.end_with?(".#{gem_name}")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
9
57
|
end
|
|
10
58
|
|
|
11
59
|
def deprecation(event)
|
|
@@ -17,10 +65,13 @@ module DeprecationToolkit
|
|
|
17
65
|
private
|
|
18
66
|
|
|
19
67
|
def deprecation_allowed?(payload)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
68
|
+
Configuration.allowed_deprecations.any? do |rule|
|
|
69
|
+
if rule.is_a?(Regexp)
|
|
70
|
+
rule.match?(payload[:message])
|
|
71
|
+
else
|
|
72
|
+
rule.call(payload[:message], payload[:callstack])
|
|
73
|
+
end
|
|
74
|
+
end
|
|
24
75
|
end
|
|
25
76
|
end
|
|
26
77
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/string/inflections"
|
|
4
|
+
require "active_support/core_ext/string/filters"
|
|
4
5
|
require "bundler"
|
|
5
6
|
require "yaml"
|
|
6
7
|
|
|
@@ -47,18 +48,13 @@ module DeprecationToolkit
|
|
|
47
48
|
Configuration.deprecation_path
|
|
48
49
|
end
|
|
49
50
|
|
|
50
|
-
path =
|
|
51
|
-
if DeprecationToolkit::Configuration.test_runner == :rspec
|
|
52
|
-
test.example_group.file_path.sub(%r{^./spec/}, "").sub(/_spec.rb$/, "")
|
|
53
|
-
else
|
|
54
|
-
test.class.name.underscore
|
|
55
|
-
end
|
|
51
|
+
path = Configuration.deprecation_file_path_format.call(test)
|
|
56
52
|
|
|
57
53
|
Pathname(deprecation_folder).join("#{path}.yml")
|
|
58
54
|
end
|
|
59
55
|
|
|
60
56
|
def test_location(test)
|
|
61
|
-
|
|
57
|
+
Kernel.const_source_location(test.class.name)[0]
|
|
62
58
|
rescue NameError
|
|
63
59
|
"unknown"
|
|
64
60
|
end
|
|
@@ -2,16 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
module DeprecationToolkit
|
|
4
4
|
module RSpecPlugin
|
|
5
|
+
extend self
|
|
6
|
+
|
|
5
7
|
RSpec.configure do |config|
|
|
6
8
|
config.before(:suite) do
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
end
|
|
9
|
+
RSpecPlugin.before_suite
|
|
10
|
+
end
|
|
11
|
+
end
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
def before_suite
|
|
14
|
+
case ENV["DEPRECATION_BEHAVIOR"]
|
|
15
|
+
when "r", "record", "record-deprecations"
|
|
16
|
+
DeprecationToolkit::Configuration.behavior = DeprecationToolkit::Behaviors::Record
|
|
14
17
|
end
|
|
18
|
+
|
|
19
|
+
DeprecationToolkit.add_notify_behavior
|
|
20
|
+
DeprecationToolkit.attach_subscriber
|
|
15
21
|
end
|
|
16
22
|
end
|
|
17
23
|
end
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module DeprecationToolkit
|
|
4
4
|
module TestTriggerer
|
|
5
|
-
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def trigger_deprecation_toolkit_behavior(test)
|
|
6
8
|
current_deprecations = DeprecationToolkit::Collector.new(DeprecationToolkit::Collector.deprecations)
|
|
7
9
|
recorded_deprecations = DeprecationToolkit::Collector.load(test)
|
|
8
10
|
if !recorded_deprecations.flaky? && current_deprecations != recorded_deprecations
|
|
@@ -38,48 +38,34 @@ module DeprecationToolkit
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def deprecation_triggered?(str)
|
|
41
|
-
DeprecationToolkit::Configuration.warnings_treated_as_deprecation.any? { |warning| warning
|
|
41
|
+
DeprecationToolkit::Configuration.warnings_treated_as_deprecation.any? { |warning| warning === str }
|
|
42
42
|
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Warning is a new feature in ruby 2.5, so support older versions
|
|
47
|
-
# Note that the `Warning` module exists in Ruby 2.4 but has a bug https://bugs.ruby-lang.org/issues/12944
|
|
48
|
-
if RUBY_VERSION < '2.5.0' && RUBY_ENGINE == 'ruby'
|
|
49
|
-
module Kernel
|
|
50
|
-
class << self
|
|
51
|
-
alias_method :__original_warn, :warn
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if DeprecationToolkit::Warning.deprecation_triggered?(message)
|
|
58
|
-
ActiveSupport::Deprecation.warn(message)
|
|
59
|
-
else
|
|
60
|
-
__original_warn(messages)
|
|
61
|
-
end
|
|
44
|
+
def deprecator
|
|
45
|
+
@deprecator ||= ActiveSupport::Deprecation.new("next", "DeprecationToolkit::Warning").tap do |deprecator|
|
|
46
|
+
deprecator.behavior = :notify
|
|
47
|
+
DeprecationSubscriber.attach_to(:deprecation_toolkit_warning)
|
|
62
48
|
end
|
|
63
49
|
end
|
|
64
|
-
|
|
65
|
-
def warn(*messages)
|
|
66
|
-
Kernel.warn(messages)
|
|
67
|
-
end
|
|
68
50
|
end
|
|
69
|
-
else
|
|
70
|
-
module DeprecationToolkit
|
|
71
|
-
module WarningPatch
|
|
72
|
-
def warn(str)
|
|
73
|
-
str = DeprecationToolkit::Warning.handle_multipart(str)
|
|
74
|
-
return unless str
|
|
75
51
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
52
|
+
module WarningPatch
|
|
53
|
+
def warn(str, *)
|
|
54
|
+
if Configuration.warnings_treated_as_deprecation.empty?
|
|
55
|
+
return super
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
str = DeprecationToolkit::Warning.handle_multipart(str)
|
|
59
|
+
return unless str
|
|
60
|
+
|
|
61
|
+
if DeprecationToolkit::Warning.deprecation_triggered?(str)
|
|
62
|
+
DeprecationToolkit::Warning.deprecator.warn(str)
|
|
63
|
+
else
|
|
64
|
+
super
|
|
81
65
|
end
|
|
82
66
|
end
|
|
67
|
+
ruby2_keywords :warn
|
|
83
68
|
end
|
|
84
|
-
|
|
69
|
+
|
|
70
|
+
::Warning.singleton_class.prepend(WarningPatch)
|
|
85
71
|
end
|
data/lib/deprecation_toolkit.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "active_support"
|
|
4
|
+
|
|
5
|
+
load("tasks/ci_recorder.rake")
|
|
4
6
|
|
|
5
7
|
module DeprecationToolkit
|
|
6
8
|
autoload :DeprecationSubscriber, "deprecation_toolkit/deprecation_subscriber"
|
|
@@ -14,28 +16,41 @@ module DeprecationToolkit
|
|
|
14
16
|
autoload :Raise, "deprecation_toolkit/behaviors/raise"
|
|
15
17
|
autoload :Record, "deprecation_toolkit/behaviors/record"
|
|
16
18
|
autoload :CIRecordHelper, "deprecation_toolkit/behaviors/ci_record_helper"
|
|
19
|
+
autoload :DeprecationIntroduced, "deprecation_toolkit/behaviors/raise"
|
|
20
|
+
autoload :DeprecationRemoved, "deprecation_toolkit/behaviors/raise"
|
|
21
|
+
autoload :DeprecationMismatch, "deprecation_toolkit/behaviors/raise"
|
|
17
22
|
end
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
class << self
|
|
25
|
+
def add_notify_behavior
|
|
26
|
+
notify = ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:notify]
|
|
27
|
+
|
|
28
|
+
each_deprecator do |deprecator|
|
|
29
|
+
behaviors = deprecator.behavior
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
unless behaviors.find { |behavior| behavior == notify }
|
|
32
|
+
deprecator.behavior = (behaviors << notify)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
25
35
|
end
|
|
26
|
-
end
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
def attach_subscriber
|
|
38
|
+
Configuration.attach_to.each do |gem_name|
|
|
39
|
+
DeprecationSubscriber.attach_to(gem_name)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def each_deprecator(&block)
|
|
46
|
+
if defined?(Rails.application) && Rails.application.respond_to?(:deprecators)
|
|
47
|
+
Rails.application.deprecators.each(&block)
|
|
48
|
+
elsif ActiveSupport::Deprecation.respond_to?(:behavior)
|
|
49
|
+
block.call(ActiveSupport::Deprecation)
|
|
50
|
+
end
|
|
33
51
|
end
|
|
34
52
|
end
|
|
35
53
|
end
|
|
36
54
|
|
|
37
|
-
unless defined?
|
|
38
|
-
require "deprecation_toolkit/minitest_hook"
|
|
39
|
-
end
|
|
40
|
-
|
|
55
|
+
require "deprecation_toolkit/minitest_hook" unless defined? RSpec
|
|
41
56
|
require "deprecation_toolkit/warning"
|
|
@@ -12,7 +12,12 @@ module Minitest
|
|
|
12
12
|
def plugin_deprecation_toolkit_init(options)
|
|
13
13
|
return unless using_bundler?
|
|
14
14
|
|
|
15
|
-
require
|
|
15
|
+
require "deprecation_toolkit"
|
|
16
|
+
|
|
17
|
+
setup_deprecation_toolkit(options)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def setup_deprecation_toolkit(options)
|
|
16
21
|
if options[:record_deprecations]
|
|
17
22
|
DeprecationToolkit::Configuration.behavior = DeprecationToolkit::Behaviors::Record
|
|
18
23
|
end
|
|
@@ -24,6 +29,6 @@ module Minitest
|
|
|
24
29
|
private
|
|
25
30
|
|
|
26
31
|
def using_bundler?
|
|
27
|
-
ENV[
|
|
32
|
+
ENV["BUNDLE_GEMFILE"]
|
|
28
33
|
end
|
|
29
34
|
end
|
data/lib/tasks/ci_recorder.rake
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require_relative
|
|
3
|
+
require "tempfile"
|
|
4
|
+
require "json"
|
|
5
|
+
require "active_support/core_ext/hash"
|
|
6
|
+
require "rake"
|
|
7
|
+
require_relative "../deprecation_toolkit/read_write_helper"
|
|
8
8
|
|
|
9
9
|
class CIRecorder
|
|
10
10
|
include Rake::DSL
|
|
11
11
|
include DeprecationToolkit::ReadWriteHelper
|
|
12
12
|
|
|
13
13
|
def initialize
|
|
14
|
-
namespace
|
|
15
|
-
desc
|
|
16
|
-
task
|
|
17
|
-
raw_file = ENV.fetch(
|
|
14
|
+
namespace(:deprecation_toolkit) do
|
|
15
|
+
desc("Parse a file generated with the CIOutputHelper and generate deprecations out of it")
|
|
16
|
+
task(:record_from_ci_output) do
|
|
17
|
+
raw_file = ENV.fetch("FILEPATH")
|
|
18
18
|
|
|
19
19
|
deprecations = extract_deprecations_output(raw_file) do |file|
|
|
20
20
|
parse_file(file)
|
|
@@ -32,6 +32,7 @@ class CIRecorder
|
|
|
32
32
|
shell_command = "cat #{file} | sed -n -e 's/^.* \\[DeprecationToolkit\\] \\(.*\\)/\\1/p' > #{tmp_file.path}"
|
|
33
33
|
|
|
34
34
|
raise "Couldn't extract deprecations from output" unless system(shell_command)
|
|
35
|
+
|
|
35
36
|
yield(tmp_file)
|
|
36
37
|
ensure
|
|
37
38
|
tmp_file.delete
|