simplycop 2.34.3 → 2.34.4

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: a012007bd10f42a48abae25b01c49dd81f6b1def4451b5560afac90570517601
4
- data.tar.gz: e40d81ba5bccdfa760b2eb323acf55ff0d89c324a523b49a13e4654da0195a2f
3
+ metadata.gz: c5cccbb176267321b2cbc3fc80ea3c7fec278cf63e456c5b7b2f788238d723c8
4
+ data.tar.gz: ad20e21b2f3b62a458bf4a967f10f314dc87b7294f7920d5cc1a77bea8805b99
5
5
  SHA512:
6
- metadata.gz: 5b9062f38dea4ad7012c63397b6cae444bf07a56358140925a8c2f2e85de70b6f661d18c6f87b4f52f0bc197a555ebd10a5eab5ec7d7bf9fbab4caa77135ad1f
7
- data.tar.gz: 492fef1f67bb6795ec1af3d0c296583a1c0ebb777a686ee612d494b81cbdf3213e88edea50e9906726ebc85ff474ae9bcc0c99e5da79de0370b2294b25059d04
6
+ metadata.gz: 895fa251a17f034c87bfc8dba66c8acf3d9ab55c144b575fba46d62b61a72af002a9476b9246ce40f4377871f68a0678d6cc716c220d81891fc00b60c409045b
7
+ data.tar.gz: 00f7019f9d6146e6839b969e1d5fe53c3ca57268444fc04720b788489c8fd69b021c4f1198960a168f0011f67f42ca6a3d9edbfd2efb4828099743883f6a30f2
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CustomCops
4
+ # Detects incorrect semantic version comparisons.
5
+ # Triggers on variables/methods containing 'version'.
6
+ #
7
+ # @example Bad - version.to_f >= 2.0, version >= "2"
8
+ # @example Good - Gem::Version.new(version) >= Gem::Version.new('2.0')
9
+ #
10
+ # If this cop flags a false positive, disable it with an inline rubocop comment.
11
+ class VersionComparison < RuboCop::Cop::Base
12
+ extend RuboCop::Cop::AutoCorrector
13
+
14
+ DISABLE_HINT = 'Disable if not a semantic version string.'
15
+ MSG_TO_F = "Avoid `.to_f` on version strings; use `Gem::Version.new()`. #{DISABLE_HINT}"
16
+ MSG_TO_I = "Avoid `.to_i` on version strings; use `Gem::Version.new()`. #{DISABLE_HINT}"
17
+ MSG_STRING = "Avoid ordering operators on version strings; use `Gem::Version.new()`. #{DISABLE_HINT}"
18
+ ORDERING_OPERATORS = [:>=, :>, :<=, :<].freeze
19
+ REVERSED_OPERATORS = { :>= => :<=, :> => :<, :<= => :>=, :< => :> }.freeze
20
+
21
+ def_node_matcher :to_f_call?, '(send $_ :to_f)'
22
+ def_node_matcher :to_i_call?, '(send $_ :to_i)'
23
+ def_node_matcher :ordering_comparison?, <<~PATTERN
24
+ (send $_ {#{ORDERING_OPERATORS.map(&:inspect).join(' ')}} (str $_))
25
+ PATTERN
26
+ def_node_matcher :reversed_ordering_comparison?, <<~PATTERN
27
+ (send (str $_) {#{ORDERING_OPERATORS.map(&:inspect).join(' ')}} $_)
28
+ PATTERN
29
+
30
+ def on_send(node)
31
+ check_numeric_conversion(node, :to_f_call?, MSG_TO_F)
32
+ check_numeric_conversion(node, :to_i_call?, MSG_TO_I)
33
+ check_ordering_comparison(node)
34
+ check_reversed_ordering_comparison(node)
35
+ end
36
+
37
+ private
38
+
39
+ def check_numeric_conversion(node, matcher, message)
40
+ send(matcher, node) do |receiver|
41
+ return unless version_related?(receiver)
42
+
43
+ add_offense(node, message: message) { |c| autocorrect_numeric(c, node, receiver) }
44
+ end
45
+ end
46
+
47
+ def check_ordering_comparison(node)
48
+ ordering_comparison?(node) do |receiver, str_val|
49
+ return unless version_related?(receiver)
50
+
51
+ add_offense(node, message: MSG_STRING) do |c|
52
+ c.replace(node, build_comparison(receiver.source, node.method_name, "'#{str_val}'"))
53
+ end
54
+ end
55
+ end
56
+
57
+ def check_reversed_ordering_comparison(node)
58
+ reversed_ordering_comparison?(node) do |str_val, receiver|
59
+ return unless version_related?(receiver)
60
+
61
+ add_offense(node, message: MSG_STRING) do |c|
62
+ c.replace(node, build_comparison(receiver.source, REVERSED_OPERATORS[node.method_name], "'#{str_val}'"))
63
+ end
64
+ end
65
+ end
66
+
67
+ def autocorrect_numeric(corrector, node, receiver)
68
+ parent = node.parent
69
+ if parent&.send_type? && ORDERING_OPERATORS.include?(parent.method_name)
70
+ corrector.replace(parent, build_comparison(receiver.source, parent.method_name, parent.arguments.first.source))
71
+ else
72
+ corrector.replace(node, "Gem::Version.new(#{receiver.source})")
73
+ end
74
+ end
75
+
76
+ def build_comparison(lhs, operator, rhs)
77
+ "Gem::Version.new(#{lhs}) #{operator} Gem::Version.new(#{rhs})"
78
+ end
79
+
80
+ def version_related?(node)
81
+ return false unless node
82
+
83
+ case node.type
84
+ when :lvar, :ivar, :cvar, :gvar then node.children.first.to_s.downcase.include?('version')
85
+ when :send then method_or_key_contains_version?(node)
86
+ else false
87
+ end
88
+ end
89
+
90
+ def method_or_key_contains_version?(node)
91
+ return true if node.method_name.to_s.downcase.include?('version')
92
+
93
+ key = node.arguments.first
94
+ return true if node.method_name == :[] && key && [:str, :sym].include?(key.type) &&
95
+ key.value.to_s.downcase.include?('version')
96
+
97
+ version_related?(node.receiver)
98
+ end
99
+ end
100
+ end
@@ -7,5 +7,5 @@
7
7
  #
8
8
 
9
9
  module Simplycop
10
- VERSION = '2.34.3'
10
+ VERSION = '2.34.4'
11
11
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplycop
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.34.3
4
+ version: 2.34.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simply Business
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-12-30 00:00:00.000000000 Z
10
+ date: 2026-01-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: benchmark
@@ -249,6 +249,7 @@ files:
249
249
  - lib/simplycop/custom_cops/no_foreground_indices.rb
250
250
  - lib/simplycop/custom_cops/timecop_without_block.rb
251
251
  - lib/simplycop/custom_cops/variable_name_shadowing_method.rb
252
+ - lib/simplycop/custom_cops/version_comparison.rb
252
253
  - lib/simplycop/security/csrf_token_validation.rb
253
254
  - lib/simplycop/security/reject_all_requests_local.rb
254
255
  - lib/simplycop/version.rb