rubocop-i18n 1.3.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +41 -31
- data/.ruby-version +1 -0
- data/.travis.yml +9 -4
- data/CHANGELOG.md +26 -1
- data/CODEOWNERS +5 -0
- data/Gemfile +2 -0
- data/README.md +89 -14
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/lib/rubocop-i18n.rb +2 -0
- data/lib/rubocop/cop/i18n.rb +6 -0
- data/lib/rubocop/cop/i18n/gettext/decorate_function_message.rb +9 -2
- data/lib/rubocop/cop/i18n/gettext/decorate_string.rb +13 -2
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb +15 -18
- data/lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb +6 -1
- data/lib/rubocop/cop/i18n/rails_i18n.rb +24 -0
- data/lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb +176 -0
- data/lib/rubocop/cop/i18n/rails_i18n/decorate_string_formatting_using_interpolation.rb +61 -0
- data/rubocop-i18n.gemspec +12 -10
- metadata +32 -41
- data/lib/rubocop/rspec/cop_helper.rb +0 -98
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 900bad082ace7d17bf13e8a01691f33c021fb683f5bf4963b1a4f217d98720c8
|
4
|
+
data.tar.gz: df4f70a869ae98441bb1d98b8b9365a8a06368ffeb6b63c16138291ff241fb32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 666a5de6a09a035d64937dcdf1441faaef249ebc6df44572f37d858ffdf00f2509abc56581900fb839d857e2e4da2c7a9e71f0d20476ab67c8d83022670052b7
|
7
|
+
data.tar.gz: 9c5cc9f02c4408c8f3a2667125b65bb1a6385bf7d885b38787521961646240d4684d81988592298009ec54660f3533f8722b8c1118809528f2d6641f0ac808b2
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Create a report to help us improve
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Describe the bug**
|
11
|
+
A clear and concise description of what the bug is.
|
12
|
+
|
13
|
+
**To Reproduce**
|
14
|
+
Steps to reproduce the behavior:
|
15
|
+
1. Go to '...'
|
16
|
+
2. Click on '....'
|
17
|
+
3. Scroll down to '....'
|
18
|
+
4. See error
|
19
|
+
|
20
|
+
**Expected behavior**
|
21
|
+
A clear and concise description of what you expected to happen.
|
22
|
+
|
23
|
+
**Screenshots**
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
25
|
+
|
26
|
+
**Desktop (please complete the following information):**
|
27
|
+
- OS: [e.g. iOS]
|
28
|
+
- Browser [e.g. chrome, safari]
|
29
|
+
- Version [e.g. 22]
|
30
|
+
|
31
|
+
**Smartphone (please complete the following information):**
|
32
|
+
- Device: [e.g. iPhone6]
|
33
|
+
- OS: [e.g. iOS8.1]
|
34
|
+
- Browser [e.g. stock browser, safari]
|
35
|
+
- Version [e.g. 22]
|
36
|
+
|
37
|
+
**Additional context**
|
38
|
+
Add any other context about the problem here.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
12
|
+
|
13
|
+
**Describe the solution you'd like**
|
14
|
+
A clear and concise description of what you want to happen.
|
15
|
+
|
16
|
+
**Describe alternatives you've considered**
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
18
|
+
|
19
|
+
**Additional context**
|
20
|
+
Add any other context or screenshots about the feature request here.
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,43 +1,50 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on
|
3
|
+
# on 2020-10-25 09:49:30 UTC using RuboCop version 1.0.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 1
|
10
|
+
# Configuration parameters: Include.
|
11
|
+
# Include: **/*.gemspec
|
12
|
+
Gemspec/RequiredRubyVersion:
|
13
|
+
Exclude:
|
14
|
+
- 'rubocop-i18n.gemspec'
|
15
|
+
|
16
|
+
# Offense count: 1
|
17
|
+
# Cop supports --auto-correct.
|
10
18
|
Lint/InterpolationCheck:
|
11
19
|
Exclude:
|
12
|
-
- 'spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb'
|
13
20
|
- 'spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb'
|
14
21
|
|
15
|
-
# Offense count:
|
22
|
+
# Offense count: 2
|
23
|
+
# Configuration parameters: IgnoredMethods.
|
16
24
|
Metrics/AbcSize:
|
17
25
|
Max: 29
|
18
26
|
|
19
|
-
# Offense count: 6
|
20
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
21
|
-
Metrics/BlockLength:
|
22
|
-
Max: 61
|
23
|
-
|
24
27
|
# Offense count: 1
|
25
|
-
# Configuration parameters: CountComments.
|
28
|
+
# Configuration parameters: CountComments, CountAsOne.
|
26
29
|
Metrics/ClassLength:
|
27
|
-
Max:
|
30
|
+
Max: 108
|
28
31
|
|
29
|
-
# Offense count:
|
32
|
+
# Offense count: 5
|
33
|
+
# Configuration parameters: IgnoredMethods.
|
30
34
|
Metrics/CyclomaticComplexity:
|
31
35
|
Max: 8
|
32
36
|
|
33
37
|
# Offense count: 7
|
34
|
-
# Configuration parameters: CountComments.
|
38
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
35
39
|
Metrics/MethodLength:
|
36
40
|
Max: 25
|
37
41
|
|
38
|
-
# Offense count:
|
39
|
-
|
40
|
-
|
42
|
+
# Offense count: 1
|
43
|
+
# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
44
|
+
# 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
|
45
|
+
Naming/FileName:
|
46
|
+
Exclude:
|
47
|
+
- 'lib/rubocop-i18n.rb'
|
41
48
|
|
42
49
|
# Offense count: 2
|
43
50
|
Style/Documentation:
|
@@ -47,35 +54,38 @@ Style/Documentation:
|
|
47
54
|
- 'lib/rubocop/cop/i18n/gettext.rb'
|
48
55
|
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
49
56
|
|
50
|
-
# Offense count:
|
51
|
-
# Configuration parameters:
|
57
|
+
# Offense count: 12
|
58
|
+
# Configuration parameters: MaxUnannotatedPlaceholdersAllowed.
|
52
59
|
# SupportedStyles: annotated, template, unannotated
|
53
60
|
Style/FormatStringToken:
|
54
|
-
|
55
|
-
- 'spec/rubocop/cop/i18n/gettext/decorate_function_message_spec.rb'
|
56
|
-
- 'spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation_spec.rb'
|
57
|
-
- 'spec/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent_spec.rb'
|
58
|
-
- 'spec/rubocop/cop/i18n/gettext/decorate_string_spec.rb'
|
61
|
+
EnforcedStyle: template
|
59
62
|
|
60
|
-
# Offense count:
|
63
|
+
# Offense count: 2
|
61
64
|
# Configuration parameters: MinBodyLength.
|
62
65
|
Style/GuardClause:
|
63
66
|
Exclude:
|
64
67
|
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
65
|
-
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb'
|
66
68
|
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb'
|
67
69
|
|
68
|
-
# Offense count:
|
70
|
+
# Offense count: 6
|
69
71
|
# Cop supports --auto-correct.
|
70
72
|
Style/IfUnlessModifier:
|
71
73
|
Exclude:
|
72
74
|
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
73
|
-
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb'
|
74
75
|
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb'
|
75
|
-
- 'lib/rubocop/rspec/cop_helper.rb'
|
76
76
|
|
77
|
-
# Offense count:
|
78
|
-
# Configuration parameters:
|
77
|
+
# Offense count: 5
|
78
|
+
# Configuration parameters: AllowModifier.
|
79
|
+
Style/SoleNestedConditional:
|
80
|
+
Exclude:
|
81
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_function_message.rb'
|
82
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_string.rb'
|
83
|
+
- 'lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb'
|
84
|
+
- 'lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb'
|
85
|
+
|
86
|
+
# Offense count: 50
|
87
|
+
# Cop supports --auto-correct.
|
88
|
+
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
79
89
|
# URISchemes: http, https
|
80
|
-
|
90
|
+
Layout/LineLength:
|
81
91
|
Max: 174
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.2
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,31 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
|
3
|
+
### [master (Unreleased)](https://github.com/puppetlabs/rubocop-i18n/compare/v3.0.0...master)
|
4
|
+
### [3.0.0](https://github.com/puppetlabs/rubocop-i18n/compare/v2.0.2...v3.0.0)
|
5
|
+
|
6
|
+
* Update Rubocop version to 1.0! Thank you @mvz!
|
7
|
+
* Cop namespace fixes, documentation updates, loading issues. Thank you again @mvz !
|
8
|
+
* Gem maintainership has been passed to @highb. Thank you @binford2k and @lucywyman!
|
9
|
+
* Update Ruby versions in gemspec, Travis, .ruby-version. Thank you @sfeuga!
|
10
|
+
|
11
|
+
### [2.0.2](https://github.com/puppetlabs/rubocop-i18n/compare/v2.0.1...v2.0.2)
|
12
|
+
|
13
|
+
* Add auto-correct for `DecorateString` (#40) Thanks @mvz!
|
14
|
+
* Update rake and bundler requirements to be more permissive of newer versions (#43)
|
15
|
+
|
16
|
+
### 2.0.1
|
17
|
+
|
18
|
+
* `chmod` all the files to be world readable and ensured that `gem
|
19
|
+
build` doesn't emit any warnings.
|
20
|
+
* fixes license name
|
21
|
+
* specifies version for pry and rb-readline
|
22
|
+
* bump Z version
|
23
|
+
|
24
|
+
### 2.0.0
|
25
|
+
|
26
|
+
* Add rails-i18n support and documentation in README. Thanks @kbacha!
|
27
|
+
|
28
|
+
### 1.3.1, 1.3.0, 1.2.0
|
4
29
|
|
5
30
|
* 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
31
|
* Code restructure (no API changes)
|
data/CODEOWNERS
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
# Rubocop::I18n
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/puppetlabs/rubocop-i18n.svg?branch=master)](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
|
|
7
|
+
Supports the following framework styles:
|
8
|
+
|
9
|
+
- gettext
|
10
|
+
- rails-i18n
|
11
|
+
|
5
12
|
## Installation
|
6
13
|
|
7
14
|
Add this line to your application's Gemfile:
|
@@ -25,19 +32,35 @@ In your `rubocop.yml`:
|
|
25
32
|
require:
|
26
33
|
- rubocop-i18n
|
27
34
|
...
|
28
|
-
GetText
|
35
|
+
# You *must* choose GetText or Rails-i18n style checking
|
36
|
+
# If you want GetText-style checking
|
37
|
+
I18n/GetText:
|
29
38
|
Enabled: true
|
30
|
-
|
31
|
-
Enabled:
|
32
|
-
|
33
|
-
|
34
|
-
GetText/DecorateStringFormattingUsingPercent
|
39
|
+
I18n/RailsI18n:
|
40
|
+
Enabled: false
|
41
|
+
# If you want rails-i18n-style checking
|
42
|
+
I18n/RailsI18n:
|
35
43
|
Enabled: true
|
44
|
+
I18n/GetText:
|
45
|
+
Enabled: false
|
46
|
+
# If you want custom control of all the cops
|
47
|
+
I18n/GetText/DecorateString:
|
48
|
+
Enabled: false
|
49
|
+
# Disable the autocorrect
|
50
|
+
AutoCorrect: false
|
51
|
+
I18n/GetText/DecorateFunctionMessage:
|
52
|
+
Enabled: false
|
53
|
+
I18n/GetText/DecorateStringFormattingUsingInterpolation:
|
54
|
+
Enabled: false
|
55
|
+
I18n/GetText/DecorateStringFormattingUsingPercent:
|
56
|
+
Enabled: false
|
57
|
+
I18n/RailsI18n/DecorateString:
|
58
|
+
Enabled: false
|
36
59
|
```
|
37
60
|
|
38
61
|
## Cops
|
39
62
|
|
40
|
-
### GetText/DecorateString
|
63
|
+
### I18n/GetText/DecorateString
|
41
64
|
|
42
65
|
This cop is looks for strings that appear to be sentences but are not decorated.
|
43
66
|
Sentences are determined by the STRING_REGEXP.
|
@@ -67,7 +90,7 @@ _("Result is good.")
|
|
67
90
|
"a string that doesn't start with a capital letter."
|
68
91
|
```
|
69
92
|
|
70
|
-
### GetText/DecorateFunctionMessage
|
93
|
+
### I18n/GetText/DecorateFunctionMessage
|
71
94
|
|
72
95
|
This cop looks for any raise or fail functions and checks that the user visible message is using gettext decoration with the _() function.
|
73
96
|
This cop makes sure the message is decorated, as well as checking that the formatting of the message is compliant according to the follow rules.
|
@@ -183,7 +206,7 @@ raise(someOtherFuntioncall(foo, "bar"))
|
|
183
206
|
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).
|
184
207
|
Or ignore this raise or fail function following this [How to ignore rules in code](#How-to-ignore-rules-in-code) section.
|
185
208
|
|
186
|
-
### GetText/DecorateStringFormattingUsingInterpolation
|
209
|
+
### I18n/GetText/DecorateStringFormattingUsingInterpolation
|
187
210
|
|
188
211
|
This cop looks for decorated gettext methods _() and checks that all strings contained
|
189
212
|
within do not use string interpolation '#{}'
|
@@ -210,7 +233,7 @@ puts _("a message with a #{'interpolation'}")
|
|
210
233
|
puts _("a message that is %{type}") % { type: 'translatable' }
|
211
234
|
```
|
212
235
|
|
213
|
-
### GetText/DecorateStringFormattingUsingPercent
|
236
|
+
### I18n/GetText/DecorateStringFormattingUsingPercent
|
214
237
|
|
215
238
|
This cop looks for decorated gettext methods _() and checks that all strings contained
|
216
239
|
within do not use sprintf formatting '%s' etc
|
@@ -233,14 +256,66 @@ raise(_("Warning is %s") % ['bad'])
|
|
233
256
|
raise(_("Warning is %{value}") % { value: 'bad' })
|
234
257
|
```
|
235
258
|
|
259
|
+
### I18n/RailsI18n/DecorateString
|
260
|
+
|
261
|
+
This cop looks for decorated rails-i18n methods.
|
262
|
+
|
263
|
+
##### Error message thrown
|
264
|
+
|
265
|
+
```
|
266
|
+
decorator is missing around sentence
|
267
|
+
```
|
268
|
+
|
269
|
+
##### Bad
|
270
|
+
|
271
|
+
``` ruby
|
272
|
+
raise("Warning is %s" % ['bad'])
|
273
|
+
```
|
274
|
+
|
275
|
+
##### Good
|
276
|
+
|
277
|
+
``` ruby
|
278
|
+
raise(t("Warning is %{value}") % { value: 'good' })
|
279
|
+
raise(translate("Warning is %{value}") % { value: 'good' })
|
280
|
+
raise(I18n.t("Warning is %{value}") % { value: 'good' })
|
281
|
+
```
|
282
|
+
|
283
|
+
### I18n/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
|
+
|
236
310
|
## How to ignore rules in code
|
237
311
|
|
238
312
|
It may be necessary to ignore a cop for a particular piece of code. We follow standard rubocop idioms.
|
239
313
|
``` ruby
|
240
|
-
raise("We don't want this translated.") # rubocop:disable GetText/DecorateString
|
241
|
-
raise("We don't want this translated")
|
242
|
-
raise(
|
243
|
-
raise(_("We don't want this translated
|
314
|
+
raise("We don't want this translated.") # rubocop:disable I18n/GetText/DecorateString
|
315
|
+
raise("We don't want this translated.") # rubocop:disable I18n/RailsI18n/DecorateString
|
316
|
+
raise("We don't want this translated") # rubocop:disable I18n/GetText/DecorateFunctionMessage
|
317
|
+
raise(_("We don't want this translated #{crazy}") # rubocop:disable I18n/GetText/DecorateStringFormattingUsingInterpolation)
|
318
|
+
raise(_("We don't want this translated %s") % ['crazy'] # rubocop:disable I18n/GetText/DecorateStringFormattingUsingPercent)
|
244
319
|
```
|
245
320
|
|
246
321
|
## Known Issues
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/lib/rubocop-i18n.rb
CHANGED
data/lib/rubocop/cop/i18n.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
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'
|
4
6
|
require 'rubocop/cop/i18n/gettext/decorate_function_message'
|
5
7
|
require 'rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation'
|
6
8
|
require 'rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent'
|
9
|
+
|
10
|
+
require 'rubocop/cop/i18n/rails_i18n'
|
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
|
@@ -6,7 +8,9 @@ module RuboCop
|
|
6
8
|
def on_send(node)
|
7
9
|
method_name = node.loc.selector.source
|
8
10
|
return unless GetText.supported_method?(method_name)
|
9
|
-
|
11
|
+
|
12
|
+
method_name = node.method_name
|
13
|
+
arg_nodes = node.arguments
|
10
14
|
if !arg_nodes.empty? && !already_decorated?(node) && (contains_string?(arg_nodes) || string_constant?(arg_nodes))
|
11
15
|
message_section = if string_constant?(arg_nodes)
|
12
16
|
arg_nodes[1]
|
@@ -51,7 +55,8 @@ module RuboCop
|
|
51
55
|
def detect_and_report(_node, message_section, method_name)
|
52
56
|
errors = how_bad_is_it(message_section)
|
53
57
|
return if errors.empty?
|
54
|
-
|
58
|
+
|
59
|
+
error_message = ["'#{method_name}' function, "]
|
55
60
|
errors.each do |error|
|
56
61
|
error_message << 'message string should be decorated. ' if error == :simple
|
57
62
|
error_message << 'message should not be a concatenated string. ' if error == :concatenation
|
@@ -59,6 +64,7 @@ module RuboCop
|
|
59
64
|
error_message << 'message should use correctly formatted interpolation. ' if error == :interpolation
|
60
65
|
error_message << 'message should be decorated. ' if error == :no_decoration
|
61
66
|
end
|
67
|
+
error_message = error_message.join('\n')
|
62
68
|
add_offense(message_section, message: error_message)
|
63
69
|
end
|
64
70
|
|
@@ -115,6 +121,7 @@ module RuboCop
|
|
115
121
|
# dstrs are split into "str" segments and other segments.
|
116
122
|
# The "other" segments are the interpolated values.
|
117
123
|
next unless child.begin_type?
|
124
|
+
|
118
125
|
value = child.children[0]
|
119
126
|
hash_key = 'value'
|
120
127
|
if value.lvar_type?
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
#
|
21
21
|
# _("Result is good.")
|
22
22
|
class DecorateString < Cop
|
23
|
-
STRING_REGEXP = /^\s*[[:upper:]][[:alpha:]]*[[:blank:]]+.*[.!?]
|
23
|
+
STRING_REGEXP = /^\s*[[:upper:]][[:alpha:]]*[[:blank:]]+.*[.!?]$/.freeze
|
24
24
|
|
25
25
|
def on_dstr(node)
|
26
26
|
check_for_parent_decorator(node) if dstr_contains_sentence?(node)
|
@@ -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
|
@@ -24,11 +26,13 @@ module RuboCop
|
|
24
26
|
def on_send(node)
|
25
27
|
decorator_name = node.loc.selector.source
|
26
28
|
return unless GetText.supported_decorator?(decorator_name)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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: "'#{method_name}' function, message string should not contain \#{} formatting")
|
32
36
|
end
|
33
37
|
|
34
38
|
private
|
@@ -38,19 +42,12 @@ module RuboCop
|
|
38
42
|
end
|
39
43
|
|
40
44
|
def contains_string_formatting_with_interpolation?(node)
|
41
|
-
if node.is_a?(Array)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
if node.respond_to?(:
|
46
|
-
|
47
|
-
return string_contains_interpolation_format?(node.source)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
if node.respond_to?(:children)
|
52
|
-
return node.children.any? { |child| contains_string_formatting_with_interpolation?(child) }
|
53
|
-
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)
|
50
|
+
|
54
51
|
false
|
55
52
|
end
|
56
53
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module I18n
|
@@ -27,7 +29,9 @@ module RuboCop
|
|
27
29
|
def on_send(node)
|
28
30
|
decorator_name = node.loc.selector.source
|
29
31
|
return unless GetText.supported_decorator?(decorator_name)
|
30
|
-
|
32
|
+
|
33
|
+
method_name = node.method_name
|
34
|
+
arg_nodes = node.arguments
|
31
35
|
if !arg_nodes.empty? && contains_string_with_percent_format?(arg_nodes)
|
32
36
|
message_section = arg_nodes[0]
|
33
37
|
add_offense(message_section, message: "'#{method_name}' function, message string should not contain sprintf style formatting (ie %s)")
|
@@ -54,6 +58,7 @@ module RuboCop
|
|
54
58
|
if node.respond_to?(:children)
|
55
59
|
return node.children.any? { |child| contains_string_with_percent_format?(child) }
|
56
60
|
end
|
61
|
+
|
57
62
|
false
|
58
63
|
end
|
59
64
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module I18n
|
6
|
+
# The Rails I18n module contains cops used to lint and enforce the use of strings
|
7
|
+
# in rails applications that want to use the I18n gem.
|
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
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module I18n
|
6
|
+
module RailsI18n
|
7
|
+
# This cop is looks for strings that appear to be sentences but are not decorated.
|
8
|
+
# Sentences are determined by the SENTENCE_REGEXP. (Upper case character, at least one space,
|
9
|
+
# and sentence punctuation at the end)
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# # bad
|
14
|
+
#
|
15
|
+
# "Result is bad."
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
#
|
21
|
+
# t("result_is_good")
|
22
|
+
# I18n.t("result_is_good")
|
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
|
+
#
|
73
|
+
class DecorateString < Cop
|
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
|
77
|
+
SUPPORTED_DECORATORS = %w[
|
78
|
+
t
|
79
|
+
t!
|
80
|
+
translate
|
81
|
+
translate!
|
82
|
+
].freeze
|
83
|
+
|
84
|
+
def on_dstr(node)
|
85
|
+
check_for_parent_decorator(node) if dstr_contains_sentence?(node)
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_str(node)
|
89
|
+
return unless sentence?(node)
|
90
|
+
|
91
|
+
parent = node.parent
|
92
|
+
if parent.respond_to?(:type)
|
93
|
+
return if parent.regexp_type? || parent.dstr_type?
|
94
|
+
end
|
95
|
+
|
96
|
+
check_for_parent_decorator(node)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def sentence?(node)
|
102
|
+
child = node.children[0]
|
103
|
+
if child.is_a?(String)
|
104
|
+
if child.valid_encoding?
|
105
|
+
child.encode(Encoding::UTF_8).chomp =~ regexp
|
106
|
+
else
|
107
|
+
false
|
108
|
+
end
|
109
|
+
elsif child.respond_to?(:type) && child.str_type?
|
110
|
+
sentence?(child)
|
111
|
+
else
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
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
|
+
|
134
|
+
def dstr_contains_sentence?(node)
|
135
|
+
node.children.any? { |child| sentence?(child) }
|
136
|
+
end
|
137
|
+
|
138
|
+
def check_for_parent_decorator(node)
|
139
|
+
return if parent_is_translator?(node.parent)
|
140
|
+
return if parent_is_indexer?(node.parent)
|
141
|
+
return if ignoring_raised_parent?(node.parent)
|
142
|
+
|
143
|
+
add_offense(node, message: 'decorator is missing around sentence')
|
144
|
+
end
|
145
|
+
|
146
|
+
def ignoring_raised_parent?(parent)
|
147
|
+
return false unless cop_config['IgnoreExceptions']
|
148
|
+
|
149
|
+
return true if parent.respond_to?(:method_name) && %i[raise fail].include?(parent.method_name)
|
150
|
+
|
151
|
+
# Commonly exceptions are initialized manually.
|
152
|
+
return ignoring_raised_parent?(parent.parent) if parent.respond_to?(:method_name) && parent.method?(:new)
|
153
|
+
|
154
|
+
false
|
155
|
+
end
|
156
|
+
|
157
|
+
def parent_is_indexer?(parent)
|
158
|
+
parent.respond_to?(:method_name) && parent.method?(:[])
|
159
|
+
end
|
160
|
+
|
161
|
+
def parent_is_translator?(parent)
|
162
|
+
if parent.respond_to?(:type) && parent.send_type?
|
163
|
+
method_name = parent.loc.selector.source
|
164
|
+
if RailsI18n.supported_decorator?(method_name)
|
165
|
+
# Implicit receiver is assumed correct.
|
166
|
+
return true if parent.receiver.nil?
|
167
|
+
return true if parent.receiver.children == [nil, :I18n]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
false
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
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,17 +1,18 @@
|
|
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
|
-
rubocop_version = '~> 0.51'
|
4
5
|
|
5
6
|
Gem::Specification.new do |spec|
|
6
7
|
spec.name = 'rubocop-i18n'
|
7
|
-
spec.version = '
|
8
|
+
spec.version = '3.0.0'
|
8
9
|
spec.authors = ['Puppet', 'Brandon High', 'TP Honey', 'Helen Campbell']
|
9
10
|
spec.email = ['team-modules@puppet.com', 'brandon.high@puppet.com', 'tp@puppet.com', 'helen@puppet.com']
|
10
11
|
|
11
12
|
spec.summary = 'RuboCop rules for i18n'
|
12
|
-
spec.description = 'RuboCop rules for detecting and autocorrecting undecorated strings for i18n'
|
13
|
+
spec.description = 'RuboCop rules for detecting and autocorrecting undecorated strings for i18n (gettext and rails-i18n)'
|
13
14
|
spec.homepage = 'https://github.com/puppetlabs/rubocop-i18n'
|
14
|
-
spec.license = 'Apache-2'
|
15
|
+
spec.license = 'Apache-2.0'
|
15
16
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
18
|
f.match(%r{^(test|spec|features)/})
|
@@ -20,11 +21,12 @@ Gem::Specification.new do |spec|
|
|
20
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
22
|
spec.require_paths = ['lib']
|
22
23
|
|
23
|
-
spec.
|
24
|
-
|
25
|
-
spec.add_development_dependency '
|
26
|
-
spec.add_development_dependency '
|
24
|
+
spec.required_ruby_version = '>= 2.5.8'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '>= 1.17.3'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0.13.1'
|
28
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
29
|
+
spec.add_development_dependency 'rb-readline', '~> 0.5.5'
|
27
30
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
-
spec.
|
29
|
-
spec.add_runtime_dependency 'rubocop', rubocop_version
|
31
|
+
spec.add_runtime_dependency 'rubocop', '~> 1.0'
|
30
32
|
end
|
metadata
CHANGED
@@ -1,118 +1,104 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
- Brandon High
|
9
9
|
- TP Honey
|
10
10
|
- Helen Campbell
|
11
|
-
autorequire:
|
11
|
+
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2020-12-14 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
18
|
-
requirement: !ruby/object:Gem::Requirement
|
19
|
-
requirements:
|
20
|
-
- - "~>"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '1.14'
|
23
|
-
type: :development
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1.14'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: pry
|
32
18
|
requirement: !ruby/object:Gem::Requirement
|
33
19
|
requirements:
|
34
20
|
- - ">="
|
35
21
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
22
|
+
version: 1.17.3
|
37
23
|
type: :development
|
38
24
|
prerelease: false
|
39
25
|
version_requirements: !ruby/object:Gem::Requirement
|
40
26
|
requirements:
|
41
27
|
- - ">="
|
42
28
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
29
|
+
version: 1.17.3
|
44
30
|
- !ruby/object:Gem::Dependency
|
45
|
-
name:
|
31
|
+
name: pry
|
46
32
|
requirement: !ruby/object:Gem::Requirement
|
47
33
|
requirements:
|
48
34
|
- - "~>"
|
49
35
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
36
|
+
version: 0.13.1
|
51
37
|
type: :development
|
52
38
|
prerelease: false
|
53
39
|
version_requirements: !ruby/object:Gem::Requirement
|
54
40
|
requirements:
|
55
41
|
- - "~>"
|
56
42
|
- !ruby/object:Gem::Version
|
57
|
-
version:
|
43
|
+
version: 0.13.1
|
58
44
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
45
|
+
name: rake
|
60
46
|
requirement: !ruby/object:Gem::Requirement
|
61
47
|
requirements:
|
62
48
|
- - ">="
|
63
49
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
50
|
+
version: 12.3.3
|
65
51
|
type: :development
|
66
52
|
prerelease: false
|
67
53
|
version_requirements: !ruby/object:Gem::Requirement
|
68
54
|
requirements:
|
69
55
|
- - ">="
|
70
56
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
57
|
+
version: 12.3.3
|
72
58
|
- !ruby/object:Gem::Dependency
|
73
|
-
name:
|
59
|
+
name: rb-readline
|
74
60
|
requirement: !ruby/object:Gem::Requirement
|
75
61
|
requirements:
|
76
62
|
- - "~>"
|
77
63
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
64
|
+
version: 0.5.5
|
79
65
|
type: :development
|
80
66
|
prerelease: false
|
81
67
|
version_requirements: !ruby/object:Gem::Requirement
|
82
68
|
requirements:
|
83
69
|
- - "~>"
|
84
70
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
71
|
+
version: 0.5.5
|
86
72
|
- !ruby/object:Gem::Dependency
|
87
|
-
name:
|
73
|
+
name: rspec
|
88
74
|
requirement: !ruby/object:Gem::Requirement
|
89
75
|
requirements:
|
90
76
|
- - "~>"
|
91
77
|
- !ruby/object:Gem::Version
|
92
|
-
version: '0
|
78
|
+
version: '3.0'
|
93
79
|
type: :development
|
94
80
|
prerelease: false
|
95
81
|
version_requirements: !ruby/object:Gem::Requirement
|
96
82
|
requirements:
|
97
83
|
- - "~>"
|
98
84
|
- !ruby/object:Gem::Version
|
99
|
-
version: '0
|
85
|
+
version: '3.0'
|
100
86
|
- !ruby/object:Gem::Dependency
|
101
87
|
name: rubocop
|
102
88
|
requirement: !ruby/object:Gem::Requirement
|
103
89
|
requirements:
|
104
90
|
- - "~>"
|
105
91
|
- !ruby/object:Gem::Version
|
106
|
-
version: '0
|
92
|
+
version: '1.0'
|
107
93
|
type: :runtime
|
108
94
|
prerelease: false
|
109
95
|
version_requirements: !ruby/object:Gem::Requirement
|
110
96
|
requirements:
|
111
97
|
- - "~>"
|
112
98
|
- !ruby/object:Gem::Version
|
113
|
-
version: '0
|
99
|
+
version: '1.0'
|
114
100
|
description: RuboCop rules for detecting and autocorrecting undecorated strings for
|
115
|
-
i18n
|
101
|
+
i18n (gettext and rails-i18n)
|
116
102
|
email:
|
117
103
|
- team-modules@puppet.com
|
118
104
|
- brandon.high@puppet.com
|
@@ -122,11 +108,15 @@ executables: []
|
|
122
108
|
extensions: []
|
123
109
|
extra_rdoc_files: []
|
124
110
|
files:
|
111
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
112
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
125
113
|
- ".gitignore"
|
126
114
|
- ".rubocop.yml"
|
127
115
|
- ".rubocop_todo.yml"
|
116
|
+
- ".ruby-version"
|
128
117
|
- ".travis.yml"
|
129
118
|
- CHANGELOG.md
|
119
|
+
- CODEOWNERS
|
130
120
|
- CODE_OF_CONDUCT.md
|
131
121
|
- Gemfile
|
132
122
|
- LICENSE
|
@@ -141,13 +131,15 @@ files:
|
|
141
131
|
- lib/rubocop/cop/i18n/gettext/decorate_string.rb
|
142
132
|
- lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_interpolation.rb
|
143
133
|
- lib/rubocop/cop/i18n/gettext/decorate_string_formatting_using_percent.rb
|
144
|
-
- lib/rubocop/
|
134
|
+
- lib/rubocop/cop/i18n/rails_i18n.rb
|
135
|
+
- lib/rubocop/cop/i18n/rails_i18n/decorate_string.rb
|
136
|
+
- lib/rubocop/cop/i18n/rails_i18n/decorate_string_formatting_using_interpolation.rb
|
145
137
|
- rubocop-i18n.gemspec
|
146
138
|
homepage: https://github.com/puppetlabs/rubocop-i18n
|
147
139
|
licenses:
|
148
|
-
- Apache-2
|
140
|
+
- Apache-2.0
|
149
141
|
metadata: {}
|
150
|
-
post_install_message:
|
142
|
+
post_install_message:
|
151
143
|
rdoc_options: []
|
152
144
|
require_paths:
|
153
145
|
- lib
|
@@ -155,16 +147,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
147
|
requirements:
|
156
148
|
- - ">="
|
157
149
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
150
|
+
version: 2.5.8
|
159
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
152
|
requirements:
|
161
153
|
- - ">="
|
162
154
|
- !ruby/object:Gem::Version
|
163
155
|
version: '0'
|
164
156
|
requirements: []
|
165
|
-
|
166
|
-
|
167
|
-
signing_key:
|
157
|
+
rubygems_version: 3.1.4
|
158
|
+
signing_key:
|
168
159
|
specification_version: 4
|
169
160
|
summary: RuboCop rules for i18n
|
170
161
|
test_files: []
|
@@ -1,98 +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
|
-
RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {}
|
26
|
-
RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {}
|
27
|
-
processed_source = parse_source(source, file)
|
28
|
-
raise 'Error parsing example code' unless processed_source.valid_syntax?
|
29
|
-
_investigate(cop, processed_source)
|
30
|
-
end
|
31
|
-
|
32
|
-
def parse_source(source, file = nil)
|
33
|
-
source = source.join($RS) if source.is_a?(Array)
|
34
|
-
|
35
|
-
if file && file.respond_to?(:write)
|
36
|
-
file.write(source)
|
37
|
-
file.rewind
|
38
|
-
file = file.path
|
39
|
-
end
|
40
|
-
|
41
|
-
RuboCop::ProcessedSource.new(source, ruby_version, file)
|
42
|
-
end
|
43
|
-
|
44
|
-
def autocorrect_source_file(source)
|
45
|
-
Tempfile.open('tmp') { |f| autocorrect_source(source, f) }
|
46
|
-
end
|
47
|
-
|
48
|
-
def autocorrect_source(source, file = nil)
|
49
|
-
cop.instance_variable_get(:@options)[:auto_correct] = true
|
50
|
-
processed_source = parse_source(source, file)
|
51
|
-
_investigate(cop, processed_source)
|
52
|
-
|
53
|
-
corrector =
|
54
|
-
RuboCop::Cop::Corrector.new(processed_source.buffer, cop.corrections)
|
55
|
-
corrector.rewrite
|
56
|
-
end
|
57
|
-
|
58
|
-
def autocorrect_source_with_loop(source, file = nil)
|
59
|
-
loop do
|
60
|
-
cop.instance_variable_set(:@corrections, [])
|
61
|
-
new_source = autocorrect_source(source, file)
|
62
|
-
return new_source if new_source == source
|
63
|
-
source = new_source
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def _investigate(cop, processed_source)
|
68
|
-
forces = RuboCop::Cop::Force.all.each_with_object([]) do |klass, instances|
|
69
|
-
next unless cop.join_force?(klass)
|
70
|
-
instances << klass.new([cop])
|
71
|
-
end
|
72
|
-
|
73
|
-
commissioner =
|
74
|
-
RuboCop::Cop::Commissioner.new([cop], forces, raise_error: true)
|
75
|
-
commissioner.investigate(processed_source)
|
76
|
-
commissioner
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
module RuboCop
|
81
|
-
module Cop
|
82
|
-
# Monkey-patch Cop for tests to provide easy access to messages and
|
83
|
-
# highlights.
|
84
|
-
class Cop
|
85
|
-
def messages
|
86
|
-
offenses.sort.map(&:message)
|
87
|
-
end
|
88
|
-
|
89
|
-
def highlights
|
90
|
-
offenses.sort.map { |o| o.location.source }
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
RSpec.configure do |config|
|
97
|
-
config.include CopHelper
|
98
|
-
end
|