rubocop-i18n 1.0.0 → 1.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/.gitignore +1 -0
- data/CHANGELOG.md +16 -0
- data/README.md +58 -1
- data/lib/rubocop/cop/i18n.rb +2 -0
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb +67 -0
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb +70 -0
- data/rubocop-i18n.gemspec +3 -3
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e4f819b3b4f5bc73ec0b02ee1bd567ab2d3a40e
|
4
|
+
data.tar.gz: 4d0ec4a7cc1e6046d32421c9253c97a117e74b57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b7502eadea26d2982e80cf6c9e49926656cd1c572f12ec1fe8213279ffbf603d222841f522620d77f33a847a1acf365fb661eb59315e0ab70e377d09e2fccde
|
7
|
+
data.tar.gz: 9fca0a7581cf5cd57ca7741826d558463bef5e641aa1c96053ee2e3d0b6facaf4da6bb77a21b6bab9b6ff18b77042689a61f9d7ca18848c2b2038d0864c1cc12
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## master (unreleased)
|
4
|
+
|
5
|
+
### 1.1.0
|
6
|
+
|
7
|
+
* Added support for DecorateStringFormattingUsingPercent
|
8
|
+
* Added support for DecorateStringFormattingUsingInterpolation
|
9
|
+
|
10
|
+
### 1.0.0
|
11
|
+
|
12
|
+
* Improvements to DecorateFunctionMessage
|
13
|
+
|
14
|
+
### 0.0.1
|
15
|
+
|
16
|
+
* Initial import of rubocop rules from https://github.com/tphoney/puppetlabs-mysql/tree/poc_i18nTesting/rubocop by [@tphoney]
|
data/README.md
CHANGED
@@ -29,6 +29,10 @@ GetText/DecorateString:
|
|
29
29
|
Enabled: false
|
30
30
|
GetText/DecorateFunctionMessage:
|
31
31
|
Enabled: true
|
32
|
+
GetText/DecorateStringFormattingUsingInterpolation
|
33
|
+
Enabled: true
|
34
|
+
GetText/DecorateStringFormattingUsingPercent
|
35
|
+
Enabled: true
|
32
36
|
```
|
33
37
|
|
34
38
|
## Cops
|
@@ -149,16 +153,69 @@ raise(someOtherFuntioncall(foo, "bar"))
|
|
149
153
|
In this raise or fail function, the message does not contain any decoration at all and the message is not a simple string. It may make sense to convert the message to a simple string. eg [Simple decoration of a message](#Simple-decoration-of-a-message).
|
150
154
|
Or ignore this raise or fail function following this [How to ignore rules in code](#How-to-ignore-rules-in-code) section.
|
151
155
|
|
156
|
+
### GetText/DecorateStringFormattingUsingInterpolation
|
157
|
+
|
158
|
+
This cop looks for decorated gettext methods _() and checks that all strings contained
|
159
|
+
within do not use string interpolation '#{}'
|
160
|
+
|
161
|
+
#### Simple decoration of a message
|
162
|
+
|
163
|
+
Simple message strings should be decorated with the _() function
|
164
|
+
|
165
|
+
##### Error message thrown
|
166
|
+
|
167
|
+
```
|
168
|
+
'_' function, message string should not contain #{} formatting
|
169
|
+
```
|
170
|
+
|
171
|
+
##### Bad
|
172
|
+
|
173
|
+
``` ruby
|
174
|
+
puts _("a message with a #{'interpolation'}")
|
175
|
+
```
|
176
|
+
|
177
|
+
##### Good
|
178
|
+
|
179
|
+
``` ruby
|
180
|
+
puts _("a message that is %{type}") % { type: 'translatable' }
|
181
|
+
```
|
182
|
+
|
183
|
+
### GetText/DecorateStringFormattingUsingPercent
|
184
|
+
|
185
|
+
This cop looks for decorated gettext methods _() and checks that all strings contained
|
186
|
+
within do not use sprintf formatting '%s' etc
|
187
|
+
|
188
|
+
##### Error message thrown
|
189
|
+
|
190
|
+
```
|
191
|
+
'_' function, message string should not contain sprintf style formatting (ie %s)
|
192
|
+
```
|
193
|
+
|
194
|
+
##### Bad
|
195
|
+
|
196
|
+
``` ruby
|
197
|
+
raise(_("Warning is %s") % ['bad'])
|
198
|
+
```
|
199
|
+
|
200
|
+
##### Good
|
201
|
+
|
202
|
+
``` ruby
|
203
|
+
raise(_("Warning is %{value}") % { value: 'bad' })
|
204
|
+
```
|
205
|
+
|
152
206
|
## How to ignore rules in code
|
153
207
|
|
154
208
|
It may be necessary to ignore a cop for a particular piece of code. We follow standard rubocop idioms.
|
155
209
|
``` ruby
|
156
|
-
raise("We don't want this translated") # rubocop:disable GetText/DecorateFunctionMessage
|
210
|
+
raise("We don't want this translated") # rubocop:disable GetText/DecorateFunctionMessage
|
211
|
+
raise(_("We don't want this translated #{crazy}") # rubocop:disable GetText/DecorateStringFormattingUsingInterpolation)
|
212
|
+
raise(_("We don't want this translated %s") % ['crazy'] # rubocop:disable GetText/DecorateStringFormattingUsingPercent)
|
157
213
|
```
|
158
214
|
|
159
215
|
## Known Issues
|
160
216
|
|
161
217
|
Rubocop currently does not detect Heredoc style messages in functions correctly, which in turn prevents this plugin from detecting them correctly.
|
218
|
+
Not all sprintf formatting strings are detected.
|
162
219
|
|
163
220
|
## Development
|
164
221
|
|
data/lib/rubocop/cop/i18n.rb
CHANGED
@@ -2,3 +2,5 @@ require 'rubocop'
|
|
2
2
|
require 'rubocop/cop/i18n/gettext'
|
3
3
|
require 'rubocop/cop/i18n/gettext/decorate_string'
|
4
4
|
require 'rubocop/cop/i18n/gettext/decorate_function_message'
|
5
|
+
require 'rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation'
|
6
|
+
require 'rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cop
|
3
|
+
module I18n
|
4
|
+
module GetText
|
5
|
+
# When using an decorated string to support I18N, any strings inside the decoration should not contain
|
6
|
+
# the '#{}' interpolation string as this makes it hard to translate the strings. This cop checks the
|
7
|
+
# decorators listed in SUPPORTED_DECORATORS
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
#
|
13
|
+
# _("result is #{this_is_the_result}")
|
14
|
+
# n_("a string" + "a string with a #{float_value}")
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
#
|
20
|
+
# _("result is %{detail}" % {detail: message})
|
21
|
+
#
|
22
|
+
class DecorateStringFormattingUsingInterpolation < Cop
|
23
|
+
|
24
|
+
SUPPORTED_DECORATORS = ['_', 'n_', 'N_']
|
25
|
+
|
26
|
+
def on_send(node)
|
27
|
+
decorator_name = node.loc.selector.source
|
28
|
+
return if !supported_decorator_name?(decorator_name)
|
29
|
+
_, method_name, *arg_nodes = *node
|
30
|
+
if !arg_nodes.empty? && contains_string_formatting_with_interpolation?(arg_nodes)
|
31
|
+
message_section = arg_nodes[0]
|
32
|
+
add_offense(message_section, :expression, "'#{method_name}' function, message string should not contain \#{} formatting")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def supported_decorator_name?(decorator_name)
|
39
|
+
SUPPORTED_DECORATORS.include?(decorator_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def string_contains_interpolation_format?(str)
|
43
|
+
str.match(/\#{[^}]+}/)
|
44
|
+
end
|
45
|
+
|
46
|
+
def contains_string_formatting_with_interpolation?(node)
|
47
|
+
if node.is_a?(Array)
|
48
|
+
return node.any? { |n| contains_string_formatting_with_interpolation?(n) }
|
49
|
+
end
|
50
|
+
|
51
|
+
if node.respond_to?(:type)
|
52
|
+
if node.type == :str or node.type == :dstr
|
53
|
+
return string_contains_interpolation_format?(node.source)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if node.respond_to?(:children)
|
58
|
+
return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) }
|
59
|
+
end
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cop
|
3
|
+
module I18n
|
4
|
+
module GetText
|
5
|
+
# When using a decorated string to support I18N, any strings inside the decoration should not contain sprintf
|
6
|
+
# style formatting as this makes it hard to translate the string. This cop checks the decorators listed in
|
7
|
+
# SUPPORTED_DECORATORS and checks for each of the formats in SUPPORTED_FORMATS. NOTE: this cop does not
|
8
|
+
# check for all possible sprintf formats.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
#
|
14
|
+
# _("result is %s" % ["value"])
|
15
|
+
# n_("a string" + "a string with a %-3.1f" % [size])
|
16
|
+
# N_("a string" + "a string with a %04d" % [size])
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
#
|
22
|
+
# _("result is %{detail}" % {detail: message})
|
23
|
+
#
|
24
|
+
class DecorateStringFormattingUsingPercent < Cop
|
25
|
+
|
26
|
+
SUPPORTED_DECORATORS = ['_', 'n_', 'N_']
|
27
|
+
SUPPORTED_FORMATS = %w[b B d i o u x X e E f g G a A c p s]
|
28
|
+
|
29
|
+
def on_send(node)
|
30
|
+
decorator_name = node.loc.selector.source
|
31
|
+
return if !supported_decorator_name?(decorator_name)
|
32
|
+
_, method_name, *arg_nodes = *node
|
33
|
+
if !arg_nodes.empty? && contains_string_with_percent_format?(arg_nodes)
|
34
|
+
message_section = arg_nodes[0]
|
35
|
+
add_offense(message_section, :expression, "'#{method_name}' function, message string should not contain sprintf style formatting (ie %s)")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def supported_decorator_name?(decorator_name)
|
42
|
+
SUPPORTED_DECORATORS.include?(decorator_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def string_contains_percent_format?(str)
|
46
|
+
SUPPORTED_FORMATS.any? { |format| str.match(/%([-+])?[0-9]*(\.[0-9]*)?#{format}/) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def contains_string_with_percent_format?(node)
|
50
|
+
if node.is_a?(Array)
|
51
|
+
return node.any? { |n| contains_string_with_percent_format?(n) }
|
52
|
+
end
|
53
|
+
|
54
|
+
if node.respond_to?(:type)
|
55
|
+
if node.type == :str or node.type == :dstr
|
56
|
+
return string_contains_percent_format?(node.source)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if node.respond_to?(:children)
|
61
|
+
return node.children.any? { |child| contains_string_with_percent_format?(child) }
|
62
|
+
end
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/rubocop-i18n.gemspec
CHANGED
@@ -4,9 +4,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "rubocop-i18n"
|
7
|
-
spec.version = '1.
|
8
|
-
spec.authors = ["Brandon High", "TP Honey", "Helen Campbell"]
|
9
|
-
spec.email = ["brandon.high@puppet.com", "tp@puppet.com", "helen@puppet.com"]
|
7
|
+
spec.version = '1.1.0'
|
8
|
+
spec.authors = ["Puppet", "Brandon High", "TP Honey", "Helen Campbell"]
|
9
|
+
spec.email = ["team-modules@puppet.com", "brandon.high@puppet.com", "tp@puppet.com", "helen@puppet.com"]
|
10
10
|
|
11
11
|
spec.summary = %q{RuboCop rules for i18n}
|
12
12
|
spec.description = %q{RuboCop rules for detecting and autocorrecting undecorated strings for i18n}
|
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- Puppet
|
7
8
|
- Brandon High
|
8
9
|
- TP Honey
|
9
10
|
- Helen Campbell
|
10
11
|
autorequire:
|
11
12
|
bindir: exe
|
12
13
|
cert_chain: []
|
13
|
-
date: 2017-
|
14
|
+
date: 2017-10-13 00:00:00.000000000 Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: bundler
|
@@ -99,6 +100,7 @@ dependencies:
|
|
99
100
|
description: RuboCop rules for detecting and autocorrecting undecorated strings for
|
100
101
|
i18n
|
101
102
|
email:
|
103
|
+
- team-modules@puppet.com
|
102
104
|
- brandon.high@puppet.com
|
103
105
|
- tp@puppet.com
|
104
106
|
- helen@puppet.com
|
@@ -108,6 +110,7 @@ extra_rdoc_files: []
|
|
108
110
|
files:
|
109
111
|
- ".gitignore"
|
110
112
|
- ".travis.yml"
|
113
|
+
- CHANGELOG.md
|
111
114
|
- CODE_OF_CONDUCT.md
|
112
115
|
- Gemfile
|
113
116
|
- LICENSE
|
@@ -120,6 +123,8 @@ files:
|
|
120
123
|
- lib/rubocop/cop/i18n/gettext.rb
|
121
124
|
- lib/rubocop/cop/i18n/gettext/decorate_function_message.rb
|
122
125
|
- lib/rubocop/cop/i18n/gettext/decorate_string.rb
|
126
|
+
- lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb
|
127
|
+
- lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb
|
123
128
|
- lib/rubocop/rspec/cop_helper.rb
|
124
129
|
- rubocop-i18n.gemspec
|
125
130
|
homepage: https://github.com/puppetlabs/rubocop-i18n
|