deprecool 0.1.2 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 959b5cdb23ec0d5eef80f87185fb7a31a5646cf991cced0030d4d839fb835906
4
- data.tar.gz: 87eac39b80c35af2e3bc868ab99b03d534f46f06e0f6ef6945381e5d00e8798b
3
+ metadata.gz: eca3a279e6790babeed0e659c1093f1b1a9086d9695a637460dda7cfa69d7182
4
+ data.tar.gz: a9a735cbd4232f568e002c643370c42491bad699a4ee1cfdd8eaae8e8493c723
5
5
  SHA512:
6
- metadata.gz: d6da4e681409697beeaad714e669ad6854000a66a9086a8bf593ded61016e3741beb5147d616a42d99c3e19b3d51ad886f432d056ba58db2e56a559b0188ae87
7
- data.tar.gz: cd41a34a6787fb74f7985e9180893d46a765a19d369b90c09d23738a378ee645bce9d02109fda4e7806195f82bc94f9b0d2ac300ec6c69bf6d0ccb65c9e41e9a
6
+ metadata.gz: e8ce7b248608aecf4281f836bedc94c5cc6b493a9581145b22d01a9fee87266a304ce389193841dba4c5e1e5e0029af6fb63397b61e7ca877b4bf19e81b974db
7
+ data.tar.gz: 37d39d356843be3105baff39d2f4021b48f9edbf31816b241e715a43f19d489d0b72f3f5abe04de8e4c23749409158c5b5d05470608f3788b618c907faf6c572
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Deprecool
2
2
 
3
+ ## [0.1.3] - 2026-08-24
4
+ - Added Finder for: "Passing `binds` as a positional argument to `insert` deprecated", see [original commit](https://github.com/rails/rails/commit/2dca5457ab2097626481fdbec233ea56d3fb9ee3)
5
+ - Added `effort` to the CLI output
6
+
3
7
  ## [0.1.2] - 2026-08-14
4
8
 
5
9
  - Add Finder for Rails's deprecation of `write_attribute(:id, value)`
data/lib/deprecool/cli.rb CHANGED
@@ -24,7 +24,7 @@ module Deprecool
24
24
  option :gems, type: :array, desc: 'Specify gem name(s) to list which versions have deprecation tracking available'
25
25
 
26
26
  def call(gems:)
27
- CLI.list_finders(Finder.registry)
27
+ CLI.list_finders(Finder.subclasses)
28
28
 
29
29
  # TODO: REPL to filter through the available finders?
30
30
  end
@@ -116,7 +116,7 @@ module Deprecool
116
116
  def text_report(offenses, finders)
117
117
  if offenses.empty?
118
118
  puts colorize('No deprecations found.', :green)
119
- puts "(#{finders.size} finder#{'s' unless finders.size == 1} active)"
119
+ puts "(#{finders.size} finder(s) active)"
120
120
  return
121
121
  end
122
122
 
@@ -125,10 +125,13 @@ module Deprecool
125
125
  offenses.each_value do |offense_array|
126
126
  offense = offense_array.first
127
127
 
128
- puts "\n#{colorize(offense.title, :bold)}\n"
128
+ puts "\n#{colorize(offense.title, :bold)}"
129
+ puts
129
130
  puts " * #{offense.summary}"
130
- puts " #{colorize('fix:', :green)} #{offense.suggestion}" if offense.suggestion
131
- puts " #{colorize('source:', :green)} #{offense.reference}" if offense.reference
131
+ puts
132
+ puts " #{colorize('effort:', :green).ljust(16)} #{colorize_effort(offense.effort)}"
133
+ puts " #{colorize('fix:', :green).ljust(16)} #{offense.suggestion}" if offense.suggestion
134
+ puts " #{colorize('source(s):', :green).ljust(16)} #{offense.reference}" if offense.reference
132
135
  puts ' Found At:'
133
136
  offense_array.each do |o|
134
137
  offense_count += 1
@@ -158,6 +161,17 @@ module Deprecool
158
161
 
159
162
  "\e[#{colors.fetch(color, nil)}m#{text}\e[0m"
160
163
  end
164
+
165
+ def colorize_effort(effort)
166
+ # the effort method raises if you set anything but these
167
+ # values so it's safe to assume, it would also be a hassle
168
+ # to remove duplication here so oh well
169
+ effort_colors = { low: :green,
170
+ medium: :yellow,
171
+ high: :red }
172
+
173
+ colorize(effort, effort_colors[effort])
174
+ end
161
175
  end
162
176
  end
163
177
  end
@@ -31,17 +31,7 @@ module Deprecool
31
31
  class Finder
32
32
  include PrismHelpers
33
33
 
34
- @registry = []
35
-
36
34
  class << self
37
- # All finder subclasses, in definition order.
38
- attr_reader :registry
39
-
40
- def inherited(subclass)
41
- Finder.registry << subclass
42
- super
43
- end
44
-
45
35
  # defines class methods that set instance variables
46
36
  %i[gem title summary suggestion reference].each do |attribute|
47
37
  define_method(attribute) do |value = (getter = true)|
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Deprecool
4
+ module Finders
5
+ module Rails
6
+ module V8_2_0
7
+ class InsertUpdateDeleteBinds < Deprecool::Finder
8
+ gem :rails
9
+ deprecated_in '8.2.0'
10
+ removed_in '9.0.0'
11
+ title 'Binds being bassed to Insert Update Delete is deprecated'
12
+ summary ' Now that `Arel.sql(sql_with_placeholders, *binds)` wraps SQL and its binds' \
13
+ 'together as an `Arel::Nodes::BoundSqlLiteral`, just like ' \
14
+ '`Model.where("... = ?", value)`, the separate positional is no longer needed'
15
+ suggestion 'Old: `connection.insert("INSERT INTO topics (title) VALUES (?)", nil, nil, ["hello"])` ' \
16
+ 'New: `connection.insert(Arel.sql("INSERT INTO topics (title) VALUES (?)", "hello"))`'
17
+ reference 'Original Commit: https://github.com/rails/rails/commit/2dca5457ab2097626481fdbec233ea56d3fb9ee3'
18
+ effort :low
19
+
20
+ def on_call_node(node)
21
+ return unless %i[insert update delete].include?(node.name)
22
+ return unless arguments = unwrap_arguments(node.arguments)
23
+ return unless arguments.length > 1
24
+
25
+ confidence = confidence_from_arguments(arguments)
26
+ return if confidence == :none
27
+
28
+ add_offense(node, confidence: confidence)
29
+ end
30
+
31
+ private
32
+
33
+ def confidence_from_arguments(arguments)
34
+ first = arguments[0]
35
+
36
+ # if first argument is string node that starts with "INSERT" "UPDATE" "DELETE" then :high
37
+ # if first argument is a variable then :low confidence
38
+ # it it's a Prism::CallNode, and not a variable call, then I don't know what it is here,
39
+ # maybe it's like 'connection.update(generate_sql(some_arg), ["name"])' and if you are doing that
40
+ # then good luck?
41
+ if first.is_a?(Prism::CallNode)
42
+ return :low if first.variable_call? # can't tell what's stored in the variable, https://docs.ruby-lang.org/en/master/Prism/CallNode.html#method-i-variable_call-3F
43
+ :none
44
+ elsif %w[INSERT UPDATE DELETE].include?(first.unescaped[..5].upcase)
45
+ :high
46
+ else
47
+ :none
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -27,9 +27,9 @@ module Deprecool
27
27
  # I don't think we need much more than this
28
28
  # I'm open to be wrong though, maybe lots of people are subclassing
29
29
  # ObjectSpace or defining '_id2ref' on custom classes
30
- confidence = node.receiver.name == :ObjectSpace ? :high : nil
30
+ confidence = node.receiver.name == :ObjectSpace ? :high : :none
31
31
 
32
- return unless confidence
32
+ return if confidence == :none
33
33
 
34
34
  add_offense node, confidence: confidence
35
35
  end
@@ -11,8 +11,8 @@ module Deprecool
11
11
  title 'Passing arguments to #to_set is deprecated'
12
12
  summary 'Since Ruby 4.0, passing arguments to Set#to_set / Enumerable#to_set ' \
13
13
  'is deprecated and will be removed.'
14
- suggestion 'Call #to_set with no arguments. If you were building a ' \
15
- 'Set subclass, construct it explicitly instead.'
14
+ suggestion 'Call #to_set with no arguments. If you want an instance of a subclass of Set' \
15
+ 'from an enumerable construct it explicitly instead: MySetSubclass.new(enumerable)'
16
16
  reference 'https://bugs.ruby-lang.org/issues/21390 https://github.com/ruby/ruby/pull/13489'
17
17
  effort :low
18
18
 
@@ -21,7 +21,7 @@ module Deprecool
21
21
  return unless node.arguments
22
22
 
23
23
  confidence = confidence_from_receiver_node(node.receiver)
24
- return unless confidence
24
+ return if confidence == :none
25
25
 
26
26
  add_offense(node, confidence:)
27
27
  end
@@ -35,12 +35,12 @@ module Deprecool
35
35
  # a plain `to_set(x)` call to the current scope's own
36
36
  # method. This is probably not Enumerable#to_set unless someone has
37
37
  # monkeypatched Enumerable and is using to_set with an argument, I guess
38
- when nil then nil
38
+ when nil then :none
39
39
  when Prism::ConstantReadNode, Prism::ConstantPathNode
40
40
  # These nodes can constants like:
41
41
  # MY_DATA.to_set(arg) => likely an array, but can't be sure so :low
42
42
  # MyClass.to_set(arg) => has lowercase letters so it's a class method
43
- receiver&.name&.match?(/[a-z]/) ? nil : :low
43
+ receiver&.name&.match?(/[a-z]/) ? :none : :low
44
44
  else
45
45
  # this branch is when the receiver is some
46
46
  # local var, instance variable, method chain, safe navigation, etc.
@@ -7,7 +7,7 @@ module Deprecool
7
7
 
8
8
  # All the subclasses of Finder
9
9
  def all_finders
10
- Finder.registry
10
+ @all ||= Finder.subclasses
11
11
  end
12
12
 
13
13
  # Gets finders that apply to the given versions.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deprecool
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.3'
5
5
  end
6
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deprecool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zac Radford
@@ -56,6 +56,7 @@ files:
56
56
  - lib/deprecool/cli.rb
57
57
  - lib/deprecool/finder.rb
58
58
  - lib/deprecool/finders/rails/v7.1.0/serializer_positional_class_argument.rb
59
+ - lib/deprecool/finders/rails/v8.2.0/no_binds_to_insert_update_delete.rb
59
60
  - lib/deprecool/finders/rails/v8.2.0/redis_cache_store_default_redis_options.rb
60
61
  - lib/deprecool/finders/rails/v8.2.0/to_sql_binds.rb
61
62
  - lib/deprecool/finders/rails/v8.2.0/write_attribute_id.rb