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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2792a2344ae871fa62e564786c03d892bd5072d
4
- data.tar.gz: 1354b5ac2e3a9606deb1b9c594edf8a23327db38
3
+ metadata.gz: 3e4f819b3b4f5bc73ec0b02ee1bd567ab2d3a40e
4
+ data.tar.gz: 4d0ec4a7cc1e6046d32421c9253c97a117e74b57
5
5
  SHA512:
6
- metadata.gz: 76633906bc7a3ad0612fff96eab7a80eb21bf26f58b95d6a31c8e24ca2958df6c95f079000c5002785ad184711e207b22b2059383d1791665728a3a73330697e
7
- data.tar.gz: 4f58a7770df70e74ea4d5150140ee35aaef1b31aacd65b776de7c6ceb6f638715756d71bf43dd5a4b870c724496e01fda0e3f95bdee02da3f7755e98935997bc
6
+ metadata.gz: 2b7502eadea26d2982e80cf6c9e49926656cd1c572f12ec1fe8213279ffbf603d222841f522620d77f33a847a1acf365fb661eb59315e0ab70e377d09e2fccde
7
+ data.tar.gz: 9fca0a7581cf5cd57ca7741826d558463bef5e641aa1c96053ee2e3d0b6facaf4da6bb77a21b6bab9b6ff18b77042689a61f9d7ca18848c2b2038d0864c1cc12
data/.gitignore CHANGED
@@ -9,6 +9,7 @@
9
9
  /test/tmp/
10
10
  /test/version_tmp/
11
11
  /tmp/
12
+ /.idea/
12
13
 
13
14
  # Used by dotenv library to load environment variables.
14
15
  # .env
@@ -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
 
@@ -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
@@ -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.0.0'
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.0.0
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-09-06 00:00:00.000000000 Z
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