rubocop-i18n 2.0.1 → 2.0.2
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/.rubocop_todo.yml +4 -4
- data/.ruby-version +1 -0
- data/.travis.yml +2 -5
- data/CHANGELOG.md +13 -2
- data/CODEOWNERS +5 -0
- data/Gemfile +2 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/lib/rubocop-i18n.rb +2 -0
- data/lib/rubocop/cop/i18n.rb +3 -0
- data/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb +6 -2
- data/lib/rubocop/cop/i18n/gettext/decorate_string.rb +12 -1
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb +13 -18
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb +4 -1
- data/lib/rubocop/cop/i18n/rails_i18n.rb +12 -0
- data/lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb +75 -10
- data/lib/rubocop/cop/i18n/rails_i18n/decorate_string_formatting_using_interpolation.rb +61 -0
- data/rubocop-i18n.gemspec +6 -4
- metadata +17 -14
- data/lib/rubocop/rspec/cop_helper.rb +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 298270613b63bb269fc258034c5a16aab14f764e5631540d672a44662e2d8b66
|
4
|
+
data.tar.gz: 2422d8f873a23edbbd9873df60af5db71370ceca545b4134a8ea9d7e0f1ffc37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d4ae45e34a92d3b3eb013929e4fef7ae3fb7967575a55273575edf6032bfcac243e6e320e15a010f8c914032fc7e1e05acc0e14ab155f25d91512ea9e610e0e
|
7
|
+
data.tar.gz: 92507187ded035d39a07ae4b967cd97017a1879876c0cb74877fc20d0f04d3606aa6d0ef12b377a8e1e178a46e3da6f1a5d77a7fa995bfa1378ffce8c09d57dd
|
data/.rubocop_todo.yml
CHANGED
@@ -9,7 +9,6 @@
|
|
9
9
|
# Offense count: 6
|
10
10
|
Lint/InterpolationCheck:
|
11
11
|
Exclude:
|
12
|
-
- 'spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb'
|
13
12
|
- 'spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb'
|
14
13
|
|
15
14
|
# Offense count: 4
|
@@ -19,11 +18,13 @@ Metrics/AbcSize:
|
|
19
18
|
# Offense count: 6
|
20
19
|
# Configuration parameters: CountComments, ExcludedMethods.
|
21
20
|
Metrics/BlockLength:
|
21
|
+
Enabled: false
|
22
22
|
Max: 61
|
23
23
|
|
24
24
|
# Offense count: 1
|
25
25
|
# Configuration parameters: CountComments.
|
26
26
|
Metrics/ClassLength:
|
27
|
+
Enabled: false
|
27
28
|
Max: 106
|
28
29
|
|
29
30
|
# Offense count: 3
|
@@ -47,13 +48,14 @@ Style/Documentation:
|
|
47
48
|
- 'lib/rubocop/cop/i18n/gettext.rb'
|
48
49
|
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
49
50
|
|
50
|
-
# Offense count:
|
51
|
+
# Offense count: 12
|
51
52
|
# Configuration parameters: EnforcedStyle.
|
52
53
|
# SupportedStyles: annotated, template, unannotated
|
53
54
|
Style/FormatStringToken:
|
54
55
|
Exclude:
|
55
56
|
- 'spec/rubocop/cop/i18n/gettext/decorate_function_message_spec.rb'
|
56
57
|
- 'spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb'
|
58
|
+
- 'spec/rubocop/cop/i18n/rails_i18n/decorate_string_formatting_using_interpolation_spec.rb'
|
57
59
|
- 'spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent_spec.rb'
|
58
60
|
- 'spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb'
|
59
61
|
|
@@ -62,7 +64,6 @@ Style/FormatStringToken:
|
|
62
64
|
Style/GuardClause:
|
63
65
|
Exclude:
|
64
66
|
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
65
|
-
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb'
|
66
67
|
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb'
|
67
68
|
|
68
69
|
# Offense count: 10
|
@@ -70,7 +71,6 @@ Style/GuardClause:
|
|
70
71
|
Style/IfUnlessModifier:
|
71
72
|
Exclude:
|
72
73
|
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
73
|
-
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb'
|
74
74
|
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb'
|
75
75
|
- 'lib/rubocop/rspec/cop_helper.rb'
|
76
76
|
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.6
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
### master (Unreleased)
|
3
|
+
### [master (Unreleased)](https://github.com/puppetlabs/rubocop-i18n/compare/v2.0.2...master)
|
4
4
|
|
5
|
-
|
5
|
+
### [2.0.2](https://github.com/puppetlabs/rubocop-i18n/compare/v2.0.1...v2.0.2)
|
6
|
+
|
7
|
+
* Add auto-correct for `DecorateString` (#40) Thanks @mvz!
|
8
|
+
* Update rake and bundler requirements to be more permissive of newer versions (#43)
|
9
|
+
|
10
|
+
### 2.0.1
|
11
|
+
|
12
|
+
* `chmod` all the files to be world readable and ensured that `gem
|
13
|
+
build` doesn't emit any warnings.
|
14
|
+
* fixes license name
|
15
|
+
* specifies version for pry and rb-readline
|
16
|
+
* bump Z version
|
6
17
|
|
7
18
|
### 2.0.0
|
8
19
|
|
data/CODEOWNERS
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Rubocop::I18n
|
2
2
|
|
3
|
+
[](https://travis-ci.org/puppetlabs/rubocop-i18n)
|
4
|
+
|
3
5
|
A set of cops for detecting strings that need i18n decoration in your project.
|
4
6
|
|
5
7
|
Supports the following framework styles:
|
@@ -44,6 +46,8 @@ GetText:
|
|
44
46
|
# If you want custom control of all the cops
|
45
47
|
GetText/DecorateString:
|
46
48
|
Enabled: false
|
49
|
+
# Disable the autocorrect
|
50
|
+
AutoCorrect: false
|
47
51
|
GetText/DecorateFunctionMessage:
|
48
52
|
Enabled: false
|
49
53
|
GetText/DecorateStringFormattingUsingInterpolation:
|
@@ -276,6 +280,33 @@ raise(translate("Warning is %{value}") % { value: 'good' })
|
|
276
280
|
raise(I18n.t("Warning is %{value}") % { value: 'good' })
|
277
281
|
```
|
278
282
|
|
283
|
+
### RailsI18n/DecorateStringFormattingUsingInterpolation
|
284
|
+
|
285
|
+
This cop looks for decorated rails-i18n methods like `t()` and `translate()` and checks that all strings contained
|
286
|
+
within do not use string interpolation '#{}'
|
287
|
+
|
288
|
+
#### Simple decoration of a message
|
289
|
+
|
290
|
+
Simple message strings should be decorated with the t() function
|
291
|
+
|
292
|
+
##### Error message thrown
|
293
|
+
|
294
|
+
```
|
295
|
+
't' function, message key string should not contain #{} formatting
|
296
|
+
```
|
297
|
+
|
298
|
+
##### Bad
|
299
|
+
|
300
|
+
``` ruby
|
301
|
+
puts t("path.to.key.with.#{'interpolation'}")
|
302
|
+
```
|
303
|
+
|
304
|
+
##### Good
|
305
|
+
|
306
|
+
``` ruby
|
307
|
+
puts t("path.to.key.with.interpolation")
|
308
|
+
```
|
309
|
+
|
279
310
|
## How to ignore rules in code
|
280
311
|
|
281
312
|
It may be necessary to ignore a cop for a particular piece of code. We follow standard rubocop idioms.
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/lib/rubocop-i18n.rb
CHANGED
data/lib/rubocop/cop/i18n.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rubocop'
|
2
4
|
require 'rubocop/cop/i18n/gettext'
|
3
5
|
require 'rubocop/cop/i18n/gettext/decorate_string'
|
@@ -7,3 +9,4 @@ require 'rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent'
|
|
7
9
|
|
8
10
|
require 'rubocop/cop/i18n/rails_i18n'
|
9
11
|
require 'rubocop/cop/i18n/rails_i18n/decorate_string'
|
12
|
+
require 'rubocop/cop/i18n/rails_i18n/decorate_string_formatting_using_interpolation'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module I18n
|
@@ -7,7 +9,8 @@ module RuboCop
|
|
7
9
|
method_name = node.loc.selector.source
|
8
10
|
return unless GetText.supported_method?(method_name)
|
9
11
|
|
10
|
-
|
12
|
+
method_name = node.method_name
|
13
|
+
arg_nodes = node.arguments
|
11
14
|
if !arg_nodes.empty? && !already_decorated?(node) && (contains_string?(arg_nodes) || string_constant?(arg_nodes))
|
12
15
|
message_section = if string_constant?(arg_nodes)
|
13
16
|
arg_nodes[1]
|
@@ -53,7 +56,7 @@ module RuboCop
|
|
53
56
|
errors = how_bad_is_it(message_section)
|
54
57
|
return if errors.empty?
|
55
58
|
|
56
|
-
error_message = "'#{method_name}' function, "
|
59
|
+
error_message = ["'#{method_name}' function, "]
|
57
60
|
errors.each do |error|
|
58
61
|
error_message << 'message string should be decorated. ' if error == :simple
|
59
62
|
error_message << 'message should not be a concatenated string. ' if error == :concatenation
|
@@ -61,6 +64,7 @@ module RuboCop
|
|
61
64
|
error_message << 'message should use correctly formatted interpolation. ' if error == :interpolation
|
62
65
|
error_message << 'message should be decorated. ' if error == :no_decoration
|
63
66
|
end
|
67
|
+
error_message = error_message.join('\n')
|
64
68
|
add_offense(message_section, message: error_message)
|
65
69
|
end
|
66
70
|
|
@@ -37,6 +37,10 @@ module RuboCop
|
|
37
37
|
check_for_parent_decorator(node)
|
38
38
|
end
|
39
39
|
|
40
|
+
def autocorrect(node)
|
41
|
+
single_string_correct(node) if node.str_type?
|
42
|
+
end
|
43
|
+
|
40
44
|
private
|
41
45
|
|
42
46
|
def sentence?(node)
|
@@ -63,11 +67,18 @@ module RuboCop
|
|
63
67
|
if parent.respond_to?(:type) && parent.send_type?
|
64
68
|
method_name = parent.loc.selector.source
|
65
69
|
return if GetText.supported_decorator?(method_name)
|
66
|
-
elsif parent.respond_to?(:method_name) && parent.
|
70
|
+
elsif parent.respond_to?(:method_name) && parent.method?(:[])
|
67
71
|
return
|
68
72
|
end
|
69
73
|
add_offense(node, message: 'decorator is missing around sentence')
|
70
74
|
end
|
75
|
+
|
76
|
+
def single_string_correct(node)
|
77
|
+
lambda { |corrector|
|
78
|
+
corrector.insert_before(node.source_range, '_(')
|
79
|
+
corrector.insert_after(node.source_range, ')')
|
80
|
+
}
|
81
|
+
end
|
71
82
|
end
|
72
83
|
end
|
73
84
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module I18n
|
@@ -25,11 +27,12 @@ module RuboCop
|
|
25
27
|
decorator_name = node.loc.selector.source
|
26
28
|
return unless GetText.supported_decorator?(decorator_name)
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
method_name = node.method_name
|
31
|
+
arg_nodes = node.arguments
|
32
|
+
return unless !arg_nodes.empty? && contains_string_formatting_with_interpolation?(arg_nodes)
|
33
|
+
|
34
|
+
message_section = arg_nodes[0]
|
35
|
+
add_offense(message_section, message: "'#{method_name}' function, message string should not contain \#{} formatting")
|
33
36
|
end
|
34
37
|
|
35
38
|
private
|
@@ -39,19 +42,11 @@ module RuboCop
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def contains_string_formatting_with_interpolation?(node)
|
42
|
-
if node.is_a?(Array)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
if node.respond_to?(:
|
47
|
-
if node.str_type? || node.dstr_type?
|
48
|
-
return string_contains_interpolation_format?(node.source)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
if node.respond_to?(:children)
|
53
|
-
return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) }
|
54
|
-
end
|
45
|
+
return node.any? { |n| contains_string_formatting_with_interpolation?(n) } if node.is_a?(Array)
|
46
|
+
|
47
|
+
return string_contains_interpolation_format?(node.source) if node.respond_to?(:type) && (node.str_type? || node.dstr_type?)
|
48
|
+
|
49
|
+
return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) } if node.respond_to?(:children)
|
55
50
|
|
56
51
|
false
|
57
52
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module I18n
|
@@ -28,7 +30,8 @@ module RuboCop
|
|
28
30
|
decorator_name = node.loc.selector.source
|
29
31
|
return unless GetText.supported_decorator?(decorator_name)
|
30
32
|
|
31
|
-
|
33
|
+
method_name = node.method_name
|
34
|
+
arg_nodes = node.arguments
|
32
35
|
if !arg_nodes.empty? && contains_string_with_percent_format?(arg_nodes)
|
33
36
|
message_section = arg_nodes[0]
|
34
37
|
add_offense(message_section, message: "'#{method_name}' function, message string should not contain sprintf style formatting (ie %s)")
|
@@ -6,6 +6,18 @@ module RuboCop
|
|
6
6
|
# The Rails I18n module contains cops used to lint and enforce the use of strings
|
7
7
|
# in rails applications that want to use the I18n gem.
|
8
8
|
module RailsI18n
|
9
|
+
def self.supported_decorators
|
10
|
+
%w[
|
11
|
+
t
|
12
|
+
t!
|
13
|
+
translate
|
14
|
+
translate!
|
15
|
+
].freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.supported_decorator?(decorator_name)
|
19
|
+
supported_decorators.include?(decorator_name)
|
20
|
+
end
|
9
21
|
end
|
10
22
|
end
|
11
23
|
end
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module I18n
|
6
6
|
module RailsI18n
|
7
7
|
# This cop is looks for strings that appear to be sentences but are not decorated.
|
8
|
-
# Sentences are determined by the
|
8
|
+
# Sentences are determined by the SENTENCE_REGEXP. (Upper case character, at least one space,
|
9
9
|
# and sentence punctuation at the end)
|
10
10
|
#
|
11
11
|
# @example
|
@@ -21,8 +21,59 @@ module RuboCop
|
|
21
21
|
# t("result_is_good")
|
22
22
|
# I18n.t("result_is_good")
|
23
23
|
#
|
24
|
+
# There are several options for configuration.
|
25
|
+
#
|
26
|
+
# @example IgnoreExceptions: true
|
27
|
+
# # OK
|
28
|
+
#
|
29
|
+
# raise "Some string sentence"
|
30
|
+
#
|
31
|
+
# @example EnforcedSentenceType: sentence
|
32
|
+
# # bad
|
33
|
+
#
|
34
|
+
# "Result is bad."
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
#
|
38
|
+
# t("result_is_good")
|
39
|
+
# I18n.t("result_is_good")
|
40
|
+
#
|
41
|
+
# @example EnforcedSentenceType: fragmented_sentence
|
42
|
+
# # bad
|
43
|
+
#
|
44
|
+
# "Result is bad" # Contains a capital to start
|
45
|
+
# "result is bad." # Ends in punctuation
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
#
|
49
|
+
# t("result_is_good")
|
50
|
+
# I18n.t("result_is_good")
|
51
|
+
#
|
52
|
+
# @example EnforcedSentenceType: fragment
|
53
|
+
# # bad
|
54
|
+
#
|
55
|
+
# "result is bad" # A series of words
|
56
|
+
#
|
57
|
+
# # good
|
58
|
+
#
|
59
|
+
# t("result_is_good")
|
60
|
+
# I18n.t("result_is_good")
|
61
|
+
#
|
62
|
+
# @example Regexp: ^only-this-text$
|
63
|
+
#
|
64
|
+
# # bad
|
65
|
+
#
|
66
|
+
# "only-this-text"
|
67
|
+
#
|
68
|
+
# # good
|
69
|
+
#
|
70
|
+
# "Any other string is fine now"
|
71
|
+
# t("only_this_text")
|
72
|
+
#
|
24
73
|
class DecorateString < Cop
|
25
|
-
|
74
|
+
SENTENCE_REGEXP = /^\s*[[:upper:]][[:alpha:]]*[[:blank:]]+.*[.!?]$/.freeze
|
75
|
+
FRAGMENTED_SENTENCE_REGEXP = /^\s*([[:upper:]][[:alpha:]]*[[:blank:]]+.*)|([[:alpha:]]*[[:blank:]]+.*[.!?])$/.freeze
|
76
|
+
FRAGMENT_REGEXP = /^\s*[[:alpha:]]*[[:blank:]]+.*$/.freeze
|
26
77
|
SUPPORTED_DECORATORS = %w[
|
27
78
|
t
|
28
79
|
t!
|
@@ -51,7 +102,7 @@ module RuboCop
|
|
51
102
|
child = node.children[0]
|
52
103
|
if child.is_a?(String)
|
53
104
|
if child.valid_encoding?
|
54
|
-
child.encode(Encoding::UTF_8).chomp =~
|
105
|
+
child.encode(Encoding::UTF_8).chomp =~ regexp
|
55
106
|
else
|
56
107
|
false
|
57
108
|
end
|
@@ -62,6 +113,24 @@ module RuboCop
|
|
62
113
|
end
|
63
114
|
end
|
64
115
|
|
116
|
+
def regexp
|
117
|
+
@regexp ||= regexp_from_config || regexp_from_string_type
|
118
|
+
end
|
119
|
+
|
120
|
+
def regexp_from_string_type
|
121
|
+
case cop_config['EnforcedSentenceType'].to_s.downcase
|
122
|
+
when 'sentence' then SENTENCE_REGEXP
|
123
|
+
when 'fragmented_sentence' then FRAGMENTED_SENTENCE_REGEXP
|
124
|
+
when 'fragment' then FRAGMENT_REGEXP
|
125
|
+
else
|
126
|
+
SENTENCE_REGEXP
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def regexp_from_config
|
131
|
+
Regexp.new(cop_config['Regexp']) if cop_config['Regexp']
|
132
|
+
end
|
133
|
+
|
65
134
|
def dstr_contains_sentence?(node)
|
66
135
|
node.children.any? { |child| sentence?(child) }
|
67
136
|
end
|
@@ -80,19 +149,19 @@ module RuboCop
|
|
80
149
|
return true if parent.respond_to?(:method_name) && %i[raise fail].include?(parent.method_name)
|
81
150
|
|
82
151
|
# Commonly exceptions are initialized manually.
|
83
|
-
return ignoring_raised_parent?(parent.parent) if parent.respond_to?(:method_name) && parent.
|
152
|
+
return ignoring_raised_parent?(parent.parent) if parent.respond_to?(:method_name) && parent.method?(:new)
|
84
153
|
|
85
154
|
false
|
86
155
|
end
|
87
156
|
|
88
157
|
def parent_is_indexer?(parent)
|
89
|
-
parent.respond_to?(:method_name) && parent.
|
158
|
+
parent.respond_to?(:method_name) && parent.method?(:[])
|
90
159
|
end
|
91
160
|
|
92
161
|
def parent_is_translator?(parent)
|
93
162
|
if parent.respond_to?(:type) && parent.send_type?
|
94
163
|
method_name = parent.loc.selector.source
|
95
|
-
if supported_decorator?(method_name)
|
164
|
+
if RailsI18n.supported_decorator?(method_name)
|
96
165
|
# Implicit receiver is assumed correct.
|
97
166
|
return true if parent.receiver.nil?
|
98
167
|
return true if parent.receiver.children == [nil, :I18n]
|
@@ -100,10 +169,6 @@ module RuboCop
|
|
100
169
|
end
|
101
170
|
false
|
102
171
|
end
|
103
|
-
|
104
|
-
def supported_decorator?(decorator_name)
|
105
|
-
SUPPORTED_DECORATORS.include?(decorator_name)
|
106
|
-
end
|
107
172
|
end
|
108
173
|
end
|
109
174
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module I18n
|
6
|
+
module RailsI18n
|
7
|
+
# When using an decorated string to support I18N, any strings inside the decoration should not contain
|
8
|
+
# the '#{}' interpolation string as this makes it hard to translate the strings.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
#
|
14
|
+
# t("status.#{status_string}")
|
15
|
+
# t("status." + "accepted")
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
#
|
21
|
+
# t("status.accepted")
|
22
|
+
#
|
23
|
+
class DecorateStringFormattingUsingInterpolation < Cop
|
24
|
+
def on_send(node)
|
25
|
+
return unless node&.loc&.selector
|
26
|
+
|
27
|
+
decorator_name = node.loc.selector.source
|
28
|
+
return unless RailsI18n.supported_decorator?(decorator_name)
|
29
|
+
|
30
|
+
method_name = node.method_name
|
31
|
+
arg_nodes = node.arguments
|
32
|
+
return unless !arg_nodes.empty? && contains_string_formatting_with_interpolation?(arg_nodes)
|
33
|
+
|
34
|
+
message_section = arg_nodes[0]
|
35
|
+
add_offense(message_section, message: error_message(method_name))
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def error_message(method_name)
|
41
|
+
"'#{method_name}' function, message key string should not contain \#{} formatting"
|
42
|
+
end
|
43
|
+
|
44
|
+
def string_contains_interpolation_format?(str)
|
45
|
+
str.match(/\#{[^}]+}/)
|
46
|
+
end
|
47
|
+
|
48
|
+
def contains_string_formatting_with_interpolation?(node)
|
49
|
+
return node.any? { |n| contains_string_formatting_with_interpolation?(n) } if node.is_a?(Array)
|
50
|
+
|
51
|
+
return string_contains_interpolation_format?(node.source) if node.respond_to?(:type) && (node.str_type? || node.dstr_type?)
|
52
|
+
|
53
|
+
return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) } if node.respond_to?(:children)
|
54
|
+
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/rubocop-i18n.gemspec
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path('lib', __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
rubocop_version = '~> 0.51'
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
8
|
spec.name = 'rubocop-i18n'
|
7
|
-
spec.version = '2.0.
|
9
|
+
spec.version = '2.0.2'
|
8
10
|
spec.authors = ['Puppet', 'Brandon High', 'TP Honey', 'Helen Campbell']
|
9
11
|
spec.email = ['team-modules@puppet.com', 'brandon.high@puppet.com', 'tp@puppet.com', 'helen@puppet.com']
|
10
12
|
|
@@ -20,9 +22,9 @@ Gem::Specification.new do |spec|
|
|
20
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
23
|
spec.require_paths = ['lib']
|
22
24
|
|
23
|
-
spec.add_development_dependency 'bundler', '
|
24
|
-
spec.add_development_dependency 'pry', '~> 0.
|
25
|
-
spec.add_development_dependency 'rake', '
|
25
|
+
spec.add_development_dependency 'bundler', '>= 1.17.3'
|
26
|
+
spec.add_development_dependency 'pry', '~> 0.13.1'
|
27
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
26
28
|
spec.add_development_dependency 'rb-readline', '~> 0.5.5'
|
27
29
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
30
|
spec.add_development_dependency 'rubocop', rubocop_version
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
@@ -11,50 +11,50 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2020-05-19 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
19
19
|
requirements:
|
20
|
-
- - "
|
20
|
+
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 1.17.3
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 1.17.3
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: pry
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
34
|
- - "~>"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 0.
|
36
|
+
version: 0.13.1
|
37
37
|
type: :development
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.13.1
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: rake
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
|
-
- - "
|
48
|
+
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
50
|
+
version: 12.3.3
|
51
51
|
type: :development
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
|
-
- - "
|
55
|
+
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version:
|
57
|
+
version: 12.3.3
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rb-readline
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,8 +125,10 @@ files:
|
|
125
125
|
- ".gitignore"
|
126
126
|
- ".rubocop.yml"
|
127
127
|
- ".rubocop_todo.yml"
|
128
|
+
- ".ruby-version"
|
128
129
|
- ".travis.yml"
|
129
130
|
- CHANGELOG.md
|
131
|
+
- CODEOWNERS
|
130
132
|
- CODE_OF_CONDUCT.md
|
131
133
|
- Gemfile
|
132
134
|
- LICENSE
|
@@ -143,7 +145,7 @@ files:
|
|
143
145
|
- lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb
|
144
146
|
- lib/rubocop/cop/i18n/rails_i18n.rb
|
145
147
|
- lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb
|
146
|
-
- lib/rubocop/
|
148
|
+
- lib/rubocop/cop/i18n/rails_i18n/decorate_string_formatting_using_interpolation.rb
|
147
149
|
- rubocop-i18n.gemspec
|
148
150
|
homepage: https://github.com/puppetlabs/rubocop-i18n
|
149
151
|
licenses:
|
@@ -164,7 +166,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
166
|
- !ruby/object:Gem::Version
|
165
167
|
version: '0'
|
166
168
|
requirements: []
|
167
|
-
|
169
|
+
rubyforge_project:
|
170
|
+
rubygems_version: 2.7.6.2
|
168
171
|
signing_key:
|
169
172
|
specification_version: 4
|
170
173
|
summary: RuboCop rules for i18n
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'tempfile'
|
4
|
-
|
5
|
-
# This module provides methods that make it easier to test Cops.
|
6
|
-
module CopHelper
|
7
|
-
extend RSpec::SharedContext
|
8
|
-
|
9
|
-
let(:ruby_version) { 2.2 }
|
10
|
-
let(:enabled_rails) { false }
|
11
|
-
let(:rails_version) { false }
|
12
|
-
|
13
|
-
def inspect_source_file(source)
|
14
|
-
Tempfile.open('tmp') { |f| inspect_source(source, f) }
|
15
|
-
end
|
16
|
-
|
17
|
-
def inspect_gemfile(source)
|
18
|
-
inspect_source(source, 'Gemfile')
|
19
|
-
end
|
20
|
-
|
21
|
-
def inspect_source(source, file = nil)
|
22
|
-
if source.is_a?(Array) && source.size == 1
|
23
|
-
raise "Don't use an array for a single line of code: #{source}"
|
24
|
-
end
|
25
|
-
|
26
|
-
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
|
27
|
-
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
|
28
|
-
processed_source = parse_source(source, file)
|
29
|
-
raise 'Error parsing example code' unless processed_source.valid_syntax?
|
30
|
-
|
31
|
-
_investigate(cop, processed_source)
|
32
|
-
end
|
33
|
-
|
34
|
-
def parse_source(source, file = nil)
|
35
|
-
source = source.join($RS) if source.is_a?(Array)
|
36
|
-
|
37
|
-
if file && file.respond_to?(:write)
|
38
|
-
file.write(source)
|
39
|
-
file.rewind
|
40
|
-
file = file.path
|
41
|
-
end
|
42
|
-
|
43
|
-
RuboCop::ProcessedSource.new(source, ruby_version, file)
|
44
|
-
end
|
45
|
-
|
46
|
-
def autocorrect_source_file(source)
|
47
|
-
Tempfile.open('tmp') { |f| autocorrect_source(source, f) }
|
48
|
-
end
|
49
|
-
|
50
|
-
def autocorrect_source(source, file = nil)
|
51
|
-
cop.instance_variable_get(:@options)[:auto_correct] = true
|
52
|
-
processed_source = parse_source(source, file)
|
53
|
-
_investigate(cop, processed_source)
|
54
|
-
|
55
|
-
corrector =
|
56
|
-
RuboCop::Cop::Corrector.new(processed_source.buffer, cop.corrections)
|
57
|
-
corrector.rewrite
|
58
|
-
end
|
59
|
-
|
60
|
-
def autocorrect_source_with_loop(source, file = nil)
|
61
|
-
loop do
|
62
|
-
cop.instance_variable_set(:@corrections, [])
|
63
|
-
new_source = autocorrect_source(source, file)
|
64
|
-
return new_source if new_source == source
|
65
|
-
|
66
|
-
source = new_source
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def _investigate(cop, processed_source)
|
71
|
-
forces = RuboCop::Cop::Force.all.each_with_object([]) do |klass, instances|
|
72
|
-
next unless cop.join_force?(klass)
|
73
|
-
|
74
|
-
instances << klass.new([cop])
|
75
|
-
end
|
76
|
-
|
77
|
-
commissioner =
|
78
|
-
RuboCop::Cop::Commissioner.new([cop], forces, raise_error: true)
|
79
|
-
commissioner.investigate(processed_source)
|
80
|
-
commissioner
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
module RuboCop
|
85
|
-
module Cop
|
86
|
-
# Monkey-patch Cop for tests to provide easy access to messages and
|
87
|
-
# highlights.
|
88
|
-
class Cop
|
89
|
-
def messages
|
90
|
-
offenses.sort.map(&:message)
|
91
|
-
end
|
92
|
-
|
93
|
-
def highlights
|
94
|
-
offenses.sort.map { |o| o.location.source }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
RSpec.configure do |config|
|
101
|
-
config.include CopHelper
|
102
|
-
end
|