rubocop-i18n 1.1.0 → 1.2.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/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +69 -0
- data/CHANGELOG.md +4 -0
- data/README.md +34 -3
- data/Rakefile +9 -3
- data/bin/console +3 -3
- data/lib/rubocop/cop/i18n/gettext.rb +35 -0
- data/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb +38 -46
- data/lib/rubocop/cop/i18n/gettext/decorate_string.rb +45 -10
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb +6 -13
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb +4 -11
- data/rubocop-i18n.gemspec +18 -15
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e23a0dde90c58003d524a1baeca709a66c900822
|
4
|
+
data.tar.gz: 1ddec0669b48c044937bcc2b9c52eeb551eb3651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 855e9c7119359d442e3fc9b0833afaaa0adcb6f72de12403d4b4b3cab1e0cc3dea733b82cd001ca7c8bb9728302d3417fa8deae0056f0f56686e62b24737422f
|
7
|
+
data.tar.gz: 26b98a062a7634ca03c17037f46c7864cdc9bd31e95b2f9a6fd85ed9f8ed381053f36c6449fa95130da881f9afcebe7334c9dc6ead5ee20f2e3c566d362d3d21
|
data/.rubocop.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-10-13 16:58:50 -0700 using RuboCop version 0.49.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
# Offense count: 4
|
9
|
+
Metrics/AbcSize:
|
10
|
+
Max: 31
|
11
|
+
|
12
|
+
# Offense count: 5
|
13
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Max: 68
|
16
|
+
|
17
|
+
# Offense count: 1
|
18
|
+
# Configuration parameters: CountComments.
|
19
|
+
Metrics/ClassLength:
|
20
|
+
Max: 106
|
21
|
+
|
22
|
+
# Offense count: 3
|
23
|
+
Metrics/CyclomaticComplexity:
|
24
|
+
Max: 8
|
25
|
+
|
26
|
+
# Offense count: 86
|
27
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
28
|
+
# URISchemes: http, https
|
29
|
+
Metrics/LineLength:
|
30
|
+
Max: 174
|
31
|
+
|
32
|
+
# Offense count: 6
|
33
|
+
# Configuration parameters: CountComments.
|
34
|
+
Metrics/MethodLength:
|
35
|
+
Max: 26
|
36
|
+
|
37
|
+
# Offense count: 2
|
38
|
+
Metrics/PerceivedComplexity:
|
39
|
+
Max: 8
|
40
|
+
|
41
|
+
# Offense count: 2
|
42
|
+
Style/Documentation:
|
43
|
+
Exclude:
|
44
|
+
- 'spec/**/*'
|
45
|
+
- 'test/**/*'
|
46
|
+
- 'lib/rubocop/cop/i18n/gettext.rb'
|
47
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
48
|
+
|
49
|
+
# Offense count: 1
|
50
|
+
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
51
|
+
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
|
52
|
+
Style/FileName:
|
53
|
+
Exclude:
|
54
|
+
- 'lib/rubocop-i18n.rb'
|
55
|
+
|
56
|
+
# Offense count: 7
|
57
|
+
# Configuration parameters: SupportedStyles.
|
58
|
+
# SupportedStyles: annotated, template
|
59
|
+
Style/FormatStringToken:
|
60
|
+
EnforcedStyle: template
|
61
|
+
|
62
|
+
# Offense count: 4
|
63
|
+
# Configuration parameters: MinBodyLength.
|
64
|
+
Style/GuardClause:
|
65
|
+
Exclude:
|
66
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
67
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_string.rb'
|
68
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb'
|
69
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb'
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## master (unreleased)
|
4
4
|
|
5
|
+
* Updated DecorateString to look for sentences using a regular expression that should be decorated. This limits the number of strings that it finds to things that look like a sentence.
|
6
|
+
* Code restructure (no API changes)
|
7
|
+
* RuboCop lint fixes
|
8
|
+
|
5
9
|
### 1.1.0
|
6
10
|
|
7
11
|
* Added support for DecorateStringFormattingUsingPercent
|
data/README.md
CHANGED
@@ -26,7 +26,7 @@ require:
|
|
26
26
|
- rubocop-i18n
|
27
27
|
...
|
28
28
|
GetText/DecorateString:
|
29
|
-
Enabled:
|
29
|
+
Enabled: true
|
30
30
|
GetText/DecorateFunctionMessage:
|
31
31
|
Enabled: true
|
32
32
|
GetText/DecorateStringFormattingUsingInterpolation
|
@@ -37,6 +37,36 @@ GetText/DecorateStringFormattingUsingPercent
|
|
37
37
|
|
38
38
|
## Cops
|
39
39
|
|
40
|
+
### GetText/DecorateString
|
41
|
+
|
42
|
+
This cop is looks for strings that appear to be sentences but are not decorated.
|
43
|
+
Sentences are determined by the STRING_REGEXP.
|
44
|
+
|
45
|
+
##### Error message thrown
|
46
|
+
|
47
|
+
```
|
48
|
+
decorator is missing around sentence
|
49
|
+
```
|
50
|
+
|
51
|
+
##### Bad
|
52
|
+
|
53
|
+
``` ruby
|
54
|
+
"Result is bad."
|
55
|
+
```
|
56
|
+
|
57
|
+
##### Good
|
58
|
+
|
59
|
+
``` ruby
|
60
|
+
_("Result is good.")
|
61
|
+
```
|
62
|
+
|
63
|
+
##### Ignored
|
64
|
+
``` ruby
|
65
|
+
"string"
|
66
|
+
"A string with out a punctuation at the end"
|
67
|
+
"a string that doesn't start with a capital letter."
|
68
|
+
```
|
69
|
+
|
40
70
|
### GetText/DecorateFunctionMessage
|
41
71
|
|
42
72
|
This cop looks for any raise or fail functions and checks that the user visible message is using gettext decoration with the _() function.
|
@@ -207,8 +237,9 @@ raise(_("Warning is %{value}") % { value: 'bad' })
|
|
207
237
|
|
208
238
|
It may be necessary to ignore a cop for a particular piece of code. We follow standard rubocop idioms.
|
209
239
|
``` ruby
|
210
|
-
raise("We don't want this translated")
|
211
|
-
raise(
|
240
|
+
raise("We don't want this translated.") # rubocop:disable GetText/DecorateString
|
241
|
+
raise("We don't want this translated") # rubocop:disable GetText/DecorateFunctionMessage
|
242
|
+
raise(_("We don't want this translated #{crazy}") # rubocop:disable GetText/DecorateStringFormattingUsingInterpolation)
|
212
243
|
raise(_("We don't want this translated %s") % ['crazy'] # rubocop:disable GetText/DecorateStringFormattingUsingPercent)
|
213
244
|
```
|
214
245
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
-
task :
|
6
|
+
task default: :test
|
7
|
+
|
8
|
+
task test: %i[rubocop spec]
|
9
|
+
|
10
|
+
task :rubocop do
|
11
|
+
sh 'rubocop -P'
|
12
|
+
end
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rubocop/i18n'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "rubocop/i18n"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start(__FILE__)
|
@@ -4,6 +4,41 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module I18n
|
6
6
|
module GetText
|
7
|
+
def self.supported_methods
|
8
|
+
%w[raise fail]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Supports decorators from
|
12
|
+
# * mutoh/gettext https://github.com/mutoh/gettext/blob/master/lib/gettext.rb
|
13
|
+
# * grosser/fast_gettext https://github.com/grosser/fast_gettext/blob/master/lib/fast_gettext/translation.rb
|
14
|
+
def self.supported_decorators
|
15
|
+
%w[
|
16
|
+
_
|
17
|
+
n_
|
18
|
+
np_
|
19
|
+
ns_
|
20
|
+
N_
|
21
|
+
Nn_
|
22
|
+
D_
|
23
|
+
Dn_
|
24
|
+
Ds_
|
25
|
+
Dns_
|
26
|
+
d_
|
27
|
+
dn_
|
28
|
+
ds_
|
29
|
+
dns_
|
30
|
+
p_
|
31
|
+
s_
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.supported_method?(method_name)
|
36
|
+
supported_methods.include?(method_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.supported_decorator?(decorator_name)
|
40
|
+
supported_decorators.include?(decorator_name)
|
41
|
+
end
|
7
42
|
end
|
8
43
|
end
|
9
44
|
end
|
@@ -3,19 +3,16 @@ module RuboCop
|
|
3
3
|
module I18n
|
4
4
|
module GetText
|
5
5
|
class DecorateFunctionMessage < Cop
|
6
|
-
SUPPORTED_METHODS = ['raise', 'fail']
|
7
|
-
SUPPORTED_DECORATORS = ['_', 'n_', 'N_']
|
8
|
-
|
9
6
|
def on_send(node)
|
10
7
|
method_name = node.loc.selector.source
|
11
|
-
return
|
8
|
+
return unless GetText.supported_method?(method_name)
|
12
9
|
_, method_name, *arg_nodes = *node
|
13
10
|
if !arg_nodes.empty? && !already_decorated?(node) && (contains_string?(arg_nodes) || string_constant?(arg_nodes))
|
14
|
-
if string_constant?(arg_nodes)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
message_section = if string_constant?(arg_nodes)
|
12
|
+
arg_nodes[1]
|
13
|
+
else
|
14
|
+
arg_nodes[0]
|
15
|
+
end
|
19
16
|
|
20
17
|
detect_and_report(node, message_section, method_name)
|
21
18
|
end
|
@@ -23,15 +20,11 @@ module RuboCop
|
|
23
20
|
|
24
21
|
private
|
25
22
|
|
26
|
-
def supported_method_name?(method_name)
|
27
|
-
SUPPORTED_METHODS.include?(method_name)
|
28
|
-
end
|
29
|
-
|
30
23
|
def already_decorated?(node, parent = nil)
|
31
24
|
parent ||= node
|
32
25
|
|
33
26
|
if node.respond_to?(:loc) && node.loc.respond_to?(:selector)
|
34
|
-
return true if
|
27
|
+
return true if GetText.supported_decorator?(node.loc.selector.source)
|
35
28
|
end
|
36
29
|
|
37
30
|
return false unless node.respond_to?(:children)
|
@@ -44,10 +37,10 @@ module RuboCop
|
|
44
37
|
end
|
45
38
|
|
46
39
|
def contains_string?(nodes)
|
47
|
-
nodes[0].inspect.include?(
|
40
|
+
nodes[0].inspect.include?(':str') || nodes[0].inspect.include?(':dstr')
|
48
41
|
end
|
49
42
|
|
50
|
-
def detect_and_report(
|
43
|
+
def detect_and_report(_node, message_section, method_name)
|
51
44
|
errors = how_bad_is_it(message_section)
|
52
45
|
return if errors.empty?
|
53
46
|
error_message = "'#{method_name}' function, "
|
@@ -68,7 +61,7 @@ module RuboCop
|
|
68
61
|
errors.push :multiline if message_section.multiline?
|
69
62
|
errors.push :concatenation if concatenation_offense?(message_section)
|
70
63
|
errors.push :interpolation if interpolation_offense?(message_section)
|
71
|
-
errors.push :no_decoration
|
64
|
+
errors.push :no_decoration unless already_decorated?(message_section)
|
72
65
|
|
73
66
|
# only display no_decoration, if that is the only problem.
|
74
67
|
if errors.size > 1 && errors.include?(:no_decoration)
|
@@ -92,7 +85,7 @@ module RuboCop
|
|
92
85
|
def interpolation_offense?(node, parent = nil)
|
93
86
|
parent ||= node
|
94
87
|
|
95
|
-
return true if node.class == RuboCop::AST::Node
|
88
|
+
return true if node.class == RuboCop::AST::Node && node.dstr_type?
|
96
89
|
|
97
90
|
return false unless node.respond_to?(:children)
|
98
91
|
|
@@ -103,52 +96,51 @@ module RuboCop
|
|
103
96
|
if node.str_type?
|
104
97
|
single_string_correct(node)
|
105
98
|
elsif interpolation_offense?(node)
|
106
|
-
# interpolation_correct(node)
|
99
|
+
# interpolation_correct(node)
|
107
100
|
end
|
108
101
|
end
|
109
102
|
|
110
103
|
def single_string_correct(node)
|
111
|
-
|
112
|
-
corrector.insert_before(node.source_range
|
113
|
-
|
104
|
+
lambda { |corrector|
|
105
|
+
corrector.insert_before(node.source_range, '_(')
|
106
|
+
corrector.insert_after(node.source_range, ')')
|
107
|
+
}
|
114
108
|
end
|
115
109
|
|
116
110
|
def interpolation_correct(node)
|
117
|
-
interpolated_values_string =
|
111
|
+
interpolated_values_string = ''
|
118
112
|
count = 0
|
119
|
-
|
113
|
+
lambda { |corrector|
|
120
114
|
node.children.each do |child|
|
121
115
|
# dstrs are split into "str" segments and other segments.
|
122
116
|
# The "other" segments are the interpolated values.
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
138
|
-
interpolated_values_string << "#{hash_key}: #{value.loc.expression.source}, "
|
139
|
-
|
140
|
-
# Replace interpolation with format string
|
141
|
-
corrector.replace(child.loc.expression, "%{#{hash_key}}")
|
117
|
+
next unless child.type == :begin
|
118
|
+
value = child.children[0]
|
119
|
+
hash_key = 'value'
|
120
|
+
if value.type == :lvar
|
121
|
+
# Use the variable's name as the format key
|
122
|
+
hash_key = value.loc.name.source
|
123
|
+
else
|
124
|
+
# These are placeholders that will manually need to be given
|
125
|
+
# a descriptive name
|
126
|
+
hash_key << count.to_s
|
127
|
+
count += 1
|
128
|
+
end
|
129
|
+
if interpolated_values_string.empty?
|
130
|
+
interpolated_values_string << '{ '
|
142
131
|
end
|
132
|
+
interpolated_values_string << "#{hash_key}: #{value.loc.expression.source}, "
|
133
|
+
|
134
|
+
# Replace interpolation with format string
|
135
|
+
corrector.replace(child.loc.expression, "%{#{hash_key}}")
|
143
136
|
end
|
144
|
-
|
145
|
-
interpolated_values_string <<
|
137
|
+
unless interpolated_values_string.empty?
|
138
|
+
interpolated_values_string << '}'
|
146
139
|
end
|
147
140
|
corrector.insert_before(node.source_range, '_(')
|
148
141
|
corrector.insert_after(node.source_range, ") % #{interpolated_values_string}")
|
149
142
|
}
|
150
143
|
end
|
151
|
-
|
152
144
|
end
|
153
145
|
end
|
154
146
|
end
|
@@ -4,35 +4,70 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module I18n
|
6
6
|
module GetText
|
7
|
-
# This cop
|
8
|
-
#
|
7
|
+
# This cop is looks for strings that appear to be sentences but are not decorated.
|
8
|
+
# Sentences are determined by the STRING_REGEXP. (Upper case character, at least one space,
|
9
|
+
# and sentence punctuation at the end)
|
9
10
|
#
|
10
11
|
# @example
|
11
12
|
#
|
12
13
|
# # bad
|
13
14
|
#
|
14
|
-
# "
|
15
|
+
# "Result is bad."
|
15
16
|
#
|
16
17
|
# @example
|
17
18
|
#
|
18
19
|
# # good
|
19
20
|
#
|
20
|
-
# "
|
21
|
+
# _("Result is good.")
|
21
22
|
class DecorateString < Cop
|
23
|
+
STRING_REGEXP = /^\s*[[:upper:]][[:alpha:]]*[[:blank:]]+.*[.!?]$/
|
24
|
+
|
25
|
+
def on_dstr(node)
|
26
|
+
check_for_parent_decorator(node) if dstr_contains_sentence?(node)
|
27
|
+
end
|
28
|
+
|
22
29
|
def on_str(node)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
return unless sentence?(node)
|
31
|
+
|
32
|
+
parent = node.parent
|
33
|
+
if parent.respond_to?(:type)
|
34
|
+
return if parent.type == :regexp || parent.type == :dstr
|
27
35
|
end
|
36
|
+
|
37
|
+
check_for_parent_decorator(node)
|
28
38
|
end
|
29
39
|
|
30
40
|
private
|
31
41
|
|
32
|
-
def
|
33
|
-
node.
|
42
|
+
def sentence?(node)
|
43
|
+
child = node.children[0]
|
44
|
+
if child.is_a?(String)
|
45
|
+
if child.valid_encoding?
|
46
|
+
child.encode(Encoding::UTF_8).chomp =~ STRING_REGEXP
|
47
|
+
else
|
48
|
+
false
|
49
|
+
end
|
50
|
+
elsif child.respond_to?(:type) && child.type == :str
|
51
|
+
sentence?(child)
|
52
|
+
else
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def dstr_contains_sentence?(node)
|
58
|
+
node.children.any? { |child| sentence?(child) }
|
34
59
|
end
|
35
60
|
|
61
|
+
def check_for_parent_decorator(node)
|
62
|
+
parent = node.parent
|
63
|
+
if parent.respond_to?(:type) && parent.type == :send
|
64
|
+
method_name = parent.loc.selector.source
|
65
|
+
return if GetText.supported_decorator?(method_name)
|
66
|
+
elsif parent.respond_to?(:method_name) && parent.method_name == :[]
|
67
|
+
return
|
68
|
+
end
|
69
|
+
add_offense(node, :expression, 'decorator is missing around sentence')
|
70
|
+
end
|
36
71
|
end
|
37
72
|
end
|
38
73
|
end
|
@@ -3,8 +3,9 @@ module RuboCop
|
|
3
3
|
module I18n
|
4
4
|
module GetText
|
5
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.
|
7
|
-
#
|
6
|
+
# the '#{}' interpolation string as this makes it hard to translate the strings.
|
7
|
+
#
|
8
|
+
# Check GetText.supported_decorators for a list of decorators that can be used.
|
8
9
|
#
|
9
10
|
# @example
|
10
11
|
#
|
@@ -20,12 +21,9 @@ module RuboCop
|
|
20
21
|
# _("result is %{detail}" % {detail: message})
|
21
22
|
#
|
22
23
|
class DecorateStringFormattingUsingInterpolation < Cop
|
23
|
-
|
24
|
-
SUPPORTED_DECORATORS = ['_', 'n_', 'N_']
|
25
|
-
|
26
24
|
def on_send(node)
|
27
25
|
decorator_name = node.loc.selector.source
|
28
|
-
return
|
26
|
+
return unless GetText.supported_decorator?(decorator_name)
|
29
27
|
_, method_name, *arg_nodes = *node
|
30
28
|
if !arg_nodes.empty? && contains_string_formatting_with_interpolation?(arg_nodes)
|
31
29
|
message_section = arg_nodes[0]
|
@@ -35,10 +33,6 @@ module RuboCop
|
|
35
33
|
|
36
34
|
private
|
37
35
|
|
38
|
-
def supported_decorator_name?(decorator_name)
|
39
|
-
SUPPORTED_DECORATORS.include?(decorator_name)
|
40
|
-
end
|
41
|
-
|
42
36
|
def string_contains_interpolation_format?(str)
|
43
37
|
str.match(/\#{[^}]+}/)
|
44
38
|
end
|
@@ -49,7 +43,7 @@ module RuboCop
|
|
49
43
|
end
|
50
44
|
|
51
45
|
if node.respond_to?(:type)
|
52
|
-
if node.type == :str
|
46
|
+
if node.type == :str || node.type == :dstr
|
53
47
|
return string_contains_interpolation_format?(node.source)
|
54
48
|
end
|
55
49
|
end
|
@@ -57,9 +51,8 @@ module RuboCop
|
|
57
51
|
if node.respond_to?(:children)
|
58
52
|
return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) }
|
59
53
|
end
|
60
|
-
|
54
|
+
false
|
61
55
|
end
|
62
|
-
|
63
56
|
end
|
64
57
|
end
|
65
58
|
end
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module GetText
|
5
5
|
# When using a decorated string to support I18N, any strings inside the decoration should not contain sprintf
|
6
6
|
# style formatting as this makes it hard to translate the string. This cop checks the decorators listed in
|
7
|
-
#
|
7
|
+
# GetText.supported_decorators and checks for each of the formats in SUPPORTED_FORMATS. NOTE: this cop does not
|
8
8
|
# check for all possible sprintf formats.
|
9
9
|
#
|
10
10
|
# @example
|
@@ -22,13 +22,11 @@ module RuboCop
|
|
22
22
|
# _("result is %{detail}" % {detail: message})
|
23
23
|
#
|
24
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]
|
25
|
+
SUPPORTED_FORMATS = %w[b B d i o u x X e E f g G a A c p s].freeze
|
28
26
|
|
29
27
|
def on_send(node)
|
30
28
|
decorator_name = node.loc.selector.source
|
31
|
-
return
|
29
|
+
return unless GetText.supported_decorator?(decorator_name)
|
32
30
|
_, method_name, *arg_nodes = *node
|
33
31
|
if !arg_nodes.empty? && contains_string_with_percent_format?(arg_nodes)
|
34
32
|
message_section = arg_nodes[0]
|
@@ -38,10 +36,6 @@ module RuboCop
|
|
38
36
|
|
39
37
|
private
|
40
38
|
|
41
|
-
def supported_decorator_name?(decorator_name)
|
42
|
-
SUPPORTED_DECORATORS.include?(decorator_name)
|
43
|
-
end
|
44
|
-
|
45
39
|
def string_contains_percent_format?(str)
|
46
40
|
SUPPORTED_FORMATS.any? { |format| str.match(/%([-+])?[0-9]*(\.[0-9]*)?#{format}/) }
|
47
41
|
end
|
@@ -52,7 +46,7 @@ module RuboCop
|
|
52
46
|
end
|
53
47
|
|
54
48
|
if node.respond_to?(:type)
|
55
|
-
if node.type == :str
|
49
|
+
if node.type == :str || node.type == :dstr
|
56
50
|
return string_contains_percent_format?(node.source)
|
57
51
|
end
|
58
52
|
end
|
@@ -62,7 +56,6 @@ module RuboCop
|
|
62
56
|
end
|
63
57
|
false
|
64
58
|
end
|
65
|
-
|
66
59
|
end
|
67
60
|
end
|
68
61
|
end
|
data/rubocop-i18n.gemspec
CHANGED
@@ -1,29 +1,32 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
rubocop_version = '~> 0.49.0'
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
-
spec.version = '1.
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.name = 'rubocop-i18n'
|
9
|
+
spec.version = '1.2.0'
|
10
|
+
spec.authors = ['Puppet', 'Brandon High', 'TP Honey', 'Helen Campbell']
|
11
|
+
spec.email = ['team-modules@puppet.com', 'brandon.high@puppet.com', 'tp@puppet.com', 'helen@puppet.com']
|
10
12
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
13
|
+
spec.summary = 'RuboCop rules for i18n'
|
14
|
+
spec.description = 'RuboCop rules for detecting and autocorrecting undecorated strings for i18n'
|
15
|
+
spec.homepage = 'https://github.com/puppetlabs/rubocop-i18n'
|
14
16
|
spec.license = 'Apache-2'
|
15
17
|
|
16
18
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
19
|
f.match(%r{^(test|spec|features)/})
|
18
20
|
end
|
19
|
-
spec.bindir =
|
21
|
+
spec.bindir = 'exe'
|
20
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
23
|
+
spec.require_paths = ['lib']
|
22
24
|
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'rb-readline'
|
29
|
+
spec.add_development_dependency 'pry'
|
30
|
+
spec.add_development_dependency 'rubocop', rubocop_version
|
31
|
+
spec.add_runtime_dependency 'rubocop', rubocop_version
|
29
32
|
end
|
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: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-10-
|
14
|
+
date: 2017-10-17 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -89,14 +89,28 @@ dependencies:
|
|
89
89
|
requirements:
|
90
90
|
- - "~>"
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
92
|
+
version: 0.49.0
|
93
|
+
type: :development
|
94
|
+
prerelease: false
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 0.49.0
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: rubocop
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 0.49.0
|
93
107
|
type: :runtime
|
94
108
|
prerelease: false
|
95
109
|
version_requirements: !ruby/object:Gem::Requirement
|
96
110
|
requirements:
|
97
111
|
- - "~>"
|
98
112
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
113
|
+
version: 0.49.0
|
100
114
|
description: RuboCop rules for detecting and autocorrecting undecorated strings for
|
101
115
|
i18n
|
102
116
|
email:
|
@@ -109,6 +123,8 @@ extensions: []
|
|
109
123
|
extra_rdoc_files: []
|
110
124
|
files:
|
111
125
|
- ".gitignore"
|
126
|
+
- ".rubocop.yml"
|
127
|
+
- ".rubocop_todo.yml"
|
112
128
|
- ".travis.yml"
|
113
129
|
- CHANGELOG.md
|
114
130
|
- CODE_OF_CONDUCT.md
|