do_not_use 0.0.0 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +107 -13
- data/lib/do_not_use/configuration.rb +36 -0
- data/lib/do_not_use/deprecator.rb +50 -0
- data/lib/do_not_use/errors/deprecated_method_use_error.rb +23 -0
- data/lib/do_not_use/instruction.rb +71 -0
- data/lib/do_not_use/location.rb +36 -0
- data/lib/do_not_use/patches/module_patch.rb +25 -0
- data/lib/do_not_use/signature_builder.rb +35 -0
- data/lib/do_not_use/signatures/abstract_code.rb +15 -0
- data/lib/do_not_use/signatures/ignored_code.rb +23 -0
- data/lib/do_not_use/signatures/tracked_code.rb +62 -0
- data/lib/do_not_use/version.rb +1 -1
- data/lib/do_not_use.rb +27 -2
- metadata +47 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6896cabb0a8a7e577ab250ce73f0de5c141c3e5132ca2b3f3c8f90b0f5db2ea1
|
|
4
|
+
data.tar.gz: 54faf975c3653b9ff23821f42128b5433935f7ade489f5654f68d2741d628a09
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dac8bb46aa616d09192d07e2c26cb573e8278cd45ce3f22e94cb4de8fef301986db16c44de6ddc4789edea378bdb5f48ef2fbe7dd9e354569a6bf64e0785ab49
|
|
7
|
+
data.tar.gz: c8c79e221519af21ff806786da4ecd432eaedb75dda4920cac68692430ed559df37ed0c4f87a89e4b7f3f43c1f65cfc06c6367b4034d5575d2820123d45c171f
|
data/README.md
CHANGED
|
@@ -1,28 +1,122 @@
|
|
|
1
1
|
# DoNotUse
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/do_not_use`. To experiment with that code, run `bin/console` for an interactive prompt.
|
|
3
|
+
`DoNotUse` gives teams a hard-stop enforcement layer for Ruby APIs that must no longer be used. It provides a DSL to deprecate methods and raise a descriptive error when a deprecated method is used. It also provides configuration options to lets you manage temporary exceptions in one place.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Add the gem to your application:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem "do_not_use"
|
|
11
|
+
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Then install it via:
|
|
12
14
|
|
|
13
|
-
```
|
|
14
|
-
bundle
|
|
15
|
+
```sh
|
|
16
|
+
bundle install
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
You can also install it directly via RubyGems:
|
|
18
20
|
|
|
19
|
-
```
|
|
20
|
-
gem install
|
|
21
|
+
```sh
|
|
22
|
+
gem install do_not_use
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
## Usage
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
Imagine you have a Ruby class called `User` with a method `raw_data` that stores part of the user’s data in JSON format. You’ve decided to deprecate this method across the codebase, but you don’t have time to remove all its usages immediately. At the same time, you need to proceed with schema and data migrations before fully eliminating it.
|
|
28
|
+
|
|
29
|
+
In this case, you can mark the method as deprecated and continue with the migrations. Then, using the `DoNotUse` gem, you can gradually identify and remove its usages across the codebase in an iterative manner while preventing the further logic built on top of it.
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
class User < ApplicationRecord
|
|
33
|
+
do_not_use :raw_data
|
|
34
|
+
|
|
35
|
+
def raw_data
|
|
36
|
+
JSON.parse(super)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class MyService
|
|
41
|
+
def do_something
|
|
42
|
+
user.raw_data # => raises DoNotUse::Errors::DeprecatedMethodUseError
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
With the following configuration, you can temporarily allow `MyService` to access `User#raw_data` method;
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
DoNotUse.configure do |config|
|
|
51
|
+
config.exceptions_yaml_path = Rails.root.join("config", "do_not_use.yaml")
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
# do_not_use.yaml
|
|
57
|
+
User:
|
|
58
|
+
instance:
|
|
59
|
+
raw_data:
|
|
60
|
+
allowed:
|
|
61
|
+
- ["MyService#do_something"]
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If someone introduces a new usage of the deprecated method, a `DeprecatedMethodUseError` will be raised. With `DoNotUse`, you can track not only direct usages of deprecated methods, but also any new execution paths that invoke them.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
For example, imagine someone creates a new service that calls MyService#do_something;
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
class AnotherService
|
|
72
|
+
def self.execute
|
|
73
|
+
my_service_object.do_something
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def my_service_object
|
|
79
|
+
MyService.new
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
AnotherService.execute # => raises DoNotUse::Errors::DeprecatedMethodUseError
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
If you want to allow this new usage, you can register its execution path signature;
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
# do_not_use.yaml
|
|
90
|
+
User:
|
|
91
|
+
instance:
|
|
92
|
+
raw_data:
|
|
93
|
+
allowed:
|
|
94
|
+
- ["MyService#do_something"]
|
|
95
|
+
singleton:
|
|
96
|
+
raw_data:
|
|
97
|
+
allowed:
|
|
98
|
+
- ["AnotherService.execute", "MyService#do_something"]
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
You don’t need to manually generate these signatures, they are included in the exception message, so you can copy and register them as allowed usages.
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
Call `DoNotUse.configure` with a block to configure the gem;
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
DoNotUse.configure do |config|
|
|
110
|
+
config.enabled = !Rails.env.production? # A boolean value is required. It's recommended to disable the gem in production environments.
|
|
111
|
+
config.tracked_paths << Rails.root # The paths where your application logic lives in.
|
|
112
|
+
config.ignored_paths << Rails.root.join("spec") # The paths which you don't want to track.
|
|
113
|
+
config.exceptions_yaml_path = Rails.root.join("exceptions.yaml") # The YAML file path where you specify existing usages of the deprecated APIs.
|
|
114
|
+
config.signature_generators = {
|
|
115
|
+
Rails.root.join("spec", "models") => Proc.new { |instruction| ... }
|
|
116
|
+
} # Helps you configure how the instruction signatures are generated for the ignored paths.
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
26
120
|
|
|
27
121
|
## Development
|
|
28
122
|
|
|
@@ -32,7 +126,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
32
126
|
|
|
33
127
|
## Contributing
|
|
34
128
|
|
|
35
|
-
Bug reports and pull requests are welcome on
|
|
129
|
+
Bug reports and pull requests are welcome on gitlab at https://gitlab.com/minac/do_not_use. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://gitlab.com/minac/do_not_use/blob/master/CODE_OF_CONDUCT.md).
|
|
36
130
|
|
|
37
131
|
## License
|
|
38
132
|
|
|
@@ -40,4 +134,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
40
134
|
|
|
41
135
|
## Code of Conduct
|
|
42
136
|
|
|
43
|
-
Everyone interacting in the DoNotUse project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://
|
|
137
|
+
Everyone interacting in the DoNotUse project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/minac/do_not_use/blob/master/CODE_OF_CONDUCT.md).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module DoNotUse
|
|
6
|
+
class Configuration
|
|
7
|
+
attr_accessor :exceptions_yaml_path, :tracked_paths, :ignored_paths, :enabled, :signature_generators
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@tracked_paths = []
|
|
11
|
+
@ignored_paths = []
|
|
12
|
+
@enabled = true
|
|
13
|
+
@signature_generators = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def exceptions
|
|
17
|
+
@exceptions ||= YAML.load_file(exceptions_yaml_path)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def exceptions_yaml_path
|
|
21
|
+
@exceptions_yaml_path.to_s unless @exceptions_yaml_path.nil?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def exceptions_for(module_name, is_singleton, method_name)
|
|
25
|
+
config_namespace = config_namespace_for(is_singleton)
|
|
26
|
+
|
|
27
|
+
exceptions.dig(module_name, config_namespace, method_name, "allowed").to_a
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def config_namespace_for(is_singleton)
|
|
33
|
+
is_singleton ? "singleton" : "instance"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "binding_of_caller"
|
|
4
|
+
|
|
5
|
+
module DoNotUse
|
|
6
|
+
class Deprecator
|
|
7
|
+
IGNORED_INSTRUCTIONS_COUNT = 3
|
|
8
|
+
|
|
9
|
+
def initialize(module_name, method_name, is_singleton)
|
|
10
|
+
@module_name = module_name
|
|
11
|
+
@method_name = method_name.to_s
|
|
12
|
+
@is_singleton = is_singleton
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def deprecation_warning(...)
|
|
16
|
+
signature_builder = SignatureBuilder.new(callers)
|
|
17
|
+
|
|
18
|
+
return if allowed_usage?(signature_builder.signature)
|
|
19
|
+
|
|
20
|
+
raise Errors::DeprecatedMethodUseError.new(deprecated_method_signature, signature_builder.signature)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
attr_reader :module_name, :method_name, :is_singleton
|
|
26
|
+
|
|
27
|
+
delegate :configuration, to: DoNotUse, private: true
|
|
28
|
+
delegate :exceptions, to: :configuration, private: true
|
|
29
|
+
|
|
30
|
+
def allowed_usage?(signature)
|
|
31
|
+
allowed_usages.include?(signature)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def allowed_usages
|
|
35
|
+
@allowed_usages ||= configuration.exceptions_for(module_name, is_singleton, method_name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def deprecated_method_signature
|
|
39
|
+
@deprecated_method_signature ||= "#{module_name}#{method_type_identifier}#{method_name}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def method_type_identifier
|
|
43
|
+
is_singleton ? '.' : '#'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def callers
|
|
47
|
+
binding.callers[IGNORED_INSTRUCTIONS_COUNT..]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DoNotUse
|
|
4
|
+
module Errors
|
|
5
|
+
class DeprecatedMethodUseError < RuntimeError
|
|
6
|
+
def initialize(method_signature, stacktrace)
|
|
7
|
+
super <<~ERR
|
|
8
|
+
`#{method_signature}` method is deprecated and will be removed soon.
|
|
9
|
+
|
|
10
|
+
Using this method is strongly discouraged, as it introduces additional technical
|
|
11
|
+
debt that will need to be addressed later.
|
|
12
|
+
|
|
13
|
+
If you believe this usage is essential and provides sufficient value to justify
|
|
14
|
+
the added technical debt, please update exceptions YAML file with the following
|
|
15
|
+
stack trace signature. Be aware that this is only a short-term allowance; the
|
|
16
|
+
technical debt introduced here must be addressed and removed promptly.
|
|
17
|
+
|
|
18
|
+
#{stacktrace.inspect}
|
|
19
|
+
ERR
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DoNotUse
|
|
4
|
+
class Instruction
|
|
5
|
+
def initialize(binding)
|
|
6
|
+
@binding = binding
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def receiver
|
|
10
|
+
singleton? ? binding.receiver : binding.receiver.class
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def singleton?
|
|
14
|
+
binding.receiver.is_a?(Module)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def method_name
|
|
18
|
+
binding.eval('__method__')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def method_owner
|
|
22
|
+
return unless frame_type == :method
|
|
23
|
+
|
|
24
|
+
meth = singleton? ? receiver.method(method_name) : receiver.instance_method(method_name)
|
|
25
|
+
|
|
26
|
+
meth.owner
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def track?
|
|
30
|
+
location.track? || (inherited_method? && receiver_location&.track?)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def inherited_method_from_ignored_paths?
|
|
34
|
+
!location.track? && inherited_method?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
delegate :frame_type, to: :binding
|
|
38
|
+
delegate :signature_generator, to: :location
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
attr_reader :binding
|
|
43
|
+
|
|
44
|
+
# The receiver location may differ from the original definition
|
|
45
|
+
# if the method is inherited.
|
|
46
|
+
#
|
|
47
|
+
# It can also be nil when the receiver location cannot be determined,
|
|
48
|
+
# such as for constants defined internally by the VM in C.
|
|
49
|
+
def receiver_location
|
|
50
|
+
return unless receiver_source_path
|
|
51
|
+
|
|
52
|
+
Location.new(receiver_source_path.first)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def location
|
|
56
|
+
@location ||= Location.new(source_path)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def inherited_method?
|
|
60
|
+
receiver != method_owner
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def source_path
|
|
64
|
+
@source_path ||= binding.source_location.first
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def receiver_source_path
|
|
68
|
+
@receiver_source_path ||= Object.const_source_location(receiver.name)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DoNotUse
|
|
4
|
+
class Location
|
|
5
|
+
def initialize(source_path)
|
|
6
|
+
@source_path ||= source_path.to_s
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def track?
|
|
10
|
+
located_in_tracked_path? && !located_in_ignored_path?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Custom signature generators registered via gem configuration.
|
|
14
|
+
# These generators are only used for instructions located in ignored paths.
|
|
15
|
+
#
|
|
16
|
+
# This allows users to define signatures for those instructions as they see fit.
|
|
17
|
+
def signature_generator
|
|
18
|
+
signature_generators.find { |path, _| source_path.starts_with?(path) }&.second
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
attr_reader :source_path
|
|
24
|
+
|
|
25
|
+
delegate :configuration, to: DoNotUse, private: true
|
|
26
|
+
delegate :tracked_paths, :ignored_paths, :signature_generators, to: :configuration, private: true
|
|
27
|
+
|
|
28
|
+
def located_in_tracked_path?
|
|
29
|
+
tracked_paths.any? { |path| source_path.starts_with?(path.to_s) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def located_in_ignored_path?
|
|
33
|
+
ignored_paths.any? { |path| source_path.starts_with?(path.to_s) }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/module/deprecation"
|
|
4
|
+
|
|
5
|
+
module DoNotUse
|
|
6
|
+
module Patches
|
|
7
|
+
module ModulePatch
|
|
8
|
+
def do_not_use(*method_names)
|
|
9
|
+
return unless DoNotUse.enabled?
|
|
10
|
+
|
|
11
|
+
method_names.each do |method_name|
|
|
12
|
+
deprecator = Deprecator.new(do_not_use_name, method_name, singleton_class?)
|
|
13
|
+
|
|
14
|
+
deprecate(method_name, deprecator: deprecator)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def do_not_use_name
|
|
19
|
+
singleton_class? ? attached_object.name : name
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Module.prepend(DoNotUse::Patches::ModulePatch)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DoNotUse
|
|
4
|
+
class SignatureBuilder
|
|
5
|
+
def initialize(bindings)
|
|
6
|
+
@bindings = bindings
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def signature
|
|
10
|
+
@signature ||= signatures.uniq.reverse
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
attr_reader :bindings
|
|
16
|
+
|
|
17
|
+
def signatures
|
|
18
|
+
instructions.each_with_object([]) do |instruction, memo|
|
|
19
|
+
if instruction.track?
|
|
20
|
+
signature = Signatures::TrackedCode.new(instruction).signature
|
|
21
|
+
|
|
22
|
+
memo << signature if signature
|
|
23
|
+
else
|
|
24
|
+
memo << Signatures::IgnoredCode.new(instruction).signature if memo.empty?
|
|
25
|
+
|
|
26
|
+
break memo
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def instructions
|
|
32
|
+
@instructions ||= bindings.map { |binding| Instruction.new(binding) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DoNotUse
|
|
4
|
+
module Signatures
|
|
5
|
+
class IgnoredCode < AbstractCode
|
|
6
|
+
def signature
|
|
7
|
+
custom_signature || parent_module.name
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
delegate :receiver, :signature_generator, to: :instruction, private: true
|
|
13
|
+
|
|
14
|
+
def parent_module
|
|
15
|
+
receiver.module_parents[-2] || receiver
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def custom_signature
|
|
19
|
+
signature_generator&.call(instruction)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DoNotUse
|
|
4
|
+
module Signatures
|
|
5
|
+
class TrackedCode < AbstractCode
|
|
6
|
+
def signature
|
|
7
|
+
return unless klass_name && method_or_block?
|
|
8
|
+
return inherited_code_signature if inherited_method_from_ignored_paths?
|
|
9
|
+
|
|
10
|
+
self_method_signature
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
delegate :frame_type, :singleton?, :inherited_method_from_ignored_paths?, :receiver, :method_owner,
|
|
16
|
+
to: :instruction, private: true
|
|
17
|
+
|
|
18
|
+
# Objects like ActiveRecord models inherit many methods from the library.
|
|
19
|
+
# As a result, the stack trace of a simple method call may include numerous
|
|
20
|
+
# private API calls that can change without notice, potentially triggering
|
|
21
|
+
# new deprecation warnings.
|
|
22
|
+
#
|
|
23
|
+
# Additionally, the specific inherited library methods involved are usually
|
|
24
|
+
# not relevant when registering exceptions.
|
|
25
|
+
#
|
|
26
|
+
# For these reasons, we generate a different signature here.
|
|
27
|
+
def inherited_code_signature
|
|
28
|
+
"#{receiver} < #{method_owner}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self_method_signature
|
|
32
|
+
"#{klass_name}#{separator}#{instruction_name}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def klass_name
|
|
36
|
+
@klass_name ||= instruction.receiver.name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def instruction_name
|
|
40
|
+
block? ? 'block' : instruction.method_name
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def separator
|
|
44
|
+
if block?
|
|
45
|
+
'&'
|
|
46
|
+
elsif singleton?
|
|
47
|
+
'.'
|
|
48
|
+
else
|
|
49
|
+
'#'
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def method_or_block?
|
|
54
|
+
frame_type == :method || frame_type == :block
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def block?
|
|
58
|
+
frame_type == :block
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/do_not_use/version.rb
CHANGED
data/lib/do_not_use.rb
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "active_support/all"
|
|
4
|
+
|
|
3
5
|
require_relative "do_not_use/version"
|
|
6
|
+
require_relative "do_not_use/configuration"
|
|
7
|
+
require_relative "do_not_use/deprecator"
|
|
8
|
+
require_relative "do_not_use/instruction"
|
|
9
|
+
require_relative "do_not_use/location"
|
|
10
|
+
require_relative "do_not_use/signature_builder"
|
|
11
|
+
require_relative "do_not_use/signatures/abstract_code"
|
|
12
|
+
require_relative "do_not_use/signatures/ignored_code"
|
|
13
|
+
require_relative "do_not_use/signatures/tracked_code"
|
|
14
|
+
require_relative "do_not_use/errors/deprecated_method_use_error"
|
|
15
|
+
require_relative "do_not_use/patches/module_patch"
|
|
4
16
|
|
|
5
17
|
module DoNotUse
|
|
6
|
-
|
|
7
|
-
|
|
18
|
+
def self.enabled?
|
|
19
|
+
configuration.enabled
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.configure(&block)
|
|
23
|
+
block.call(configuration)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.configuration
|
|
27
|
+
@configuration ||= Configuration.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.reset_configuration!
|
|
31
|
+
@configuration = Configuration.new
|
|
32
|
+
end
|
|
8
33
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,48 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: do_not_use
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mehmet Emin INAC
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: binding_of_caller
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - "~>"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: 1.0.0
|
|
39
|
+
type: :runtime
|
|
40
|
+
prerelease: false
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - "~>"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 1.0.0
|
|
12
46
|
description: Helps capture deprecated method usages.
|
|
13
47
|
email:
|
|
14
48
|
- mehmetemininac@gmail.com
|
|
@@ -21,6 +55,16 @@ files:
|
|
|
21
55
|
- README.md
|
|
22
56
|
- Rakefile
|
|
23
57
|
- lib/do_not_use.rb
|
|
58
|
+
- lib/do_not_use/configuration.rb
|
|
59
|
+
- lib/do_not_use/deprecator.rb
|
|
60
|
+
- lib/do_not_use/errors/deprecated_method_use_error.rb
|
|
61
|
+
- lib/do_not_use/instruction.rb
|
|
62
|
+
- lib/do_not_use/location.rb
|
|
63
|
+
- lib/do_not_use/patches/module_patch.rb
|
|
64
|
+
- lib/do_not_use/signature_builder.rb
|
|
65
|
+
- lib/do_not_use/signatures/abstract_code.rb
|
|
66
|
+
- lib/do_not_use/signatures/ignored_code.rb
|
|
67
|
+
- lib/do_not_use/signatures/tracked_code.rb
|
|
24
68
|
- lib/do_not_use/version.rb
|
|
25
69
|
homepage: https://gitlab.com/minac/do-not-use
|
|
26
70
|
licenses:
|
|
@@ -42,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
42
86
|
- !ruby/object:Gem::Version
|
|
43
87
|
version: '0'
|
|
44
88
|
requirements: []
|
|
45
|
-
rubygems_version: 4.0.
|
|
89
|
+
rubygems_version: 4.0.9
|
|
46
90
|
specification_version: 4
|
|
47
91
|
summary: Marks methods/attributes as deprecated and captures their usages.
|
|
48
92
|
test_files: []
|