i18n-tasks 0.2.15 → 0.2.17
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/CHANGES.md +10 -1
- data/README.md +10 -6
- data/lib/i18n/tasks/configuration.rb +0 -23
- data/lib/i18n/tasks/data/yaml.rb +4 -9
- data/lib/i18n/tasks/key_pattern_matching.rb +1 -4
- data/lib/i18n/tasks/relative_keys.rb +16 -13
- data/lib/i18n/tasks/scanners/base_scanner.rb +65 -0
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +26 -0
- data/lib/i18n/tasks/source_keys.rb +11 -42
- data/lib/i18n/tasks/version.rb +1 -1
- data/spec/{source_keys_spec.rb → pattern_scanner_spec.rb} +3 -4
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5078ec1751923ec5ebfcd79893a7bdca8ae618f
|
4
|
+
data.tar.gz: e29ebefde17fdbefc0408452466e5f1a19a2be71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55359af166cef34bd9c4708a0a482d5107d54d347615172b39803559355d8738e6da03901562a509ae8b6474cdda7ee6b19d4044a1978520d7cee9e9d81bfacb
|
7
|
+
data.tar.gz: a05eb27caad0776691685f6e70ce271084adf7ae4d71c97f1898736501ddd9b7a5a47627dd1f4623349764dd281aa6ef344aa763190ce38799d882bd565933f5
|
data/CHANGES.md
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
-
## v0.2.
|
1
|
+
## v0.2.16
|
2
|
+
|
3
|
+
* Key search extracted into its own class, and a custom scanner can now be provided.
|
4
|
+
* Removed support for deprecated settings
|
5
|
+
|
6
|
+
## v0.2.15
|
7
|
+
|
8
|
+
* More robust I18n.t call detection (detect I18n.translate and multiline calls)
|
9
|
+
|
10
|
+
## v0.2.14
|
2
11
|
|
3
12
|
* Google Translate fixes: preserve interpolations, set correct format based on the key (text or html).
|
4
13
|
|
data/README.md
CHANGED
@@ -172,6 +172,9 @@ relative_roots:
|
|
172
172
|
- app/views-mobile
|
173
173
|
```
|
174
174
|
|
175
|
+
It is also possible to use a key scanner by setting `search.scanner`.
|
176
|
+
See [the default scanner](/lib/i18n/tasks/scanners/pattern_scanner.rb) for reference.
|
177
|
+
|
175
178
|
|
176
179
|
### Fine-tuning
|
177
180
|
|
@@ -224,18 +227,19 @@ This is how you can do it with rspec:
|
|
224
227
|
require 'i18n/tasks'
|
225
228
|
require 'i18n/tasks/base_task'
|
226
229
|
|
227
|
-
# spec/
|
230
|
+
# spec/i18n_keys_spec.rb
|
228
231
|
require 'spec_helper'
|
229
|
-
describe '
|
232
|
+
describe 'translation keys' do
|
230
233
|
let(:i18n) { I18n::Tasks::BaseTask.new }
|
231
234
|
|
232
|
-
it 'are all
|
233
|
-
i18n.
|
235
|
+
it 'are all present' do
|
236
|
+
expect(i18n.untranslated_keys).to have(0).keys
|
234
237
|
end
|
235
238
|
|
236
|
-
it 'are all
|
237
|
-
i18n.
|
239
|
+
it 'are all used' do
|
240
|
+
expect(i18n.unused_keys).to have(0).keys
|
238
241
|
end
|
242
|
+
|
239
243
|
end
|
240
244
|
```
|
241
245
|
|
@@ -26,33 +26,10 @@ module I18n::Tasks::Configuration
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
DEFAULT_PATTERN = /\bt(?:ranslate)?[( ]\s*(:?".+?"|:?'.+?'|:\w+)/
|
30
|
-
# search config
|
31
|
-
# @return [Hash{String => String,Hash,Array}]
|
32
|
-
def search_config
|
33
|
-
@config_sections[:search] ||= begin
|
34
|
-
if config.key?(:grep)
|
35
|
-
config[:search] ||= config.delete(:grep)
|
36
|
-
I18n::Tasks.warn_deprecated 'please rename "grep" key to "search" in config/i18n-tasks.yml'
|
37
|
-
end
|
38
|
-
search_config = (config[:search] || {}).with_indifferent_access
|
39
|
-
search_config.tap do |conf|
|
40
|
-
conf[:paths] = %w(app/) if conf[:paths].blank?
|
41
|
-
conf[:include] = Array(conf[:include]) if conf[:include].present?
|
42
|
-
conf[:exclude] = Array(conf[:exclude])
|
43
|
-
conf[:pattern] = conf[:pattern].present? ? Regexp.new(conf[:pattern]) : DEFAULT_PATTERN
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
29
|
def relative_roots
|
49
30
|
@config_sections[:relative_roots] ||= config[:relative_roots].presence || %w(app/views)
|
50
31
|
end
|
51
32
|
|
52
|
-
def relative_roots=(paths)
|
53
|
-
@config_sections[:relative_roots] = paths
|
54
|
-
end
|
55
|
-
|
56
33
|
# translation config
|
57
34
|
# @return [Hash{String => String,Hash,Array}]
|
58
35
|
def translation_config
|
data/lib/i18n/tasks/data/yaml.rb
CHANGED
@@ -19,14 +19,9 @@ module I18n::Tasks
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def config=(config)
|
22
|
-
opt
|
23
|
-
|
24
|
-
|
25
|
-
::I18n::Tasks.warn_deprecated 'please rename "data.paths" key to "data.read" in config/i18n-tasks.yml'
|
26
|
-
end
|
27
|
-
opt = DEFAULTS.deep_merge(opt)
|
28
|
-
@read = opt[:read]
|
29
|
-
@write = opt[:write].map { |x| x.is_a?(String) ? ['*', x] : x }.map { |x|
|
22
|
+
opt = DEFAULTS.deep_merge((config || {}).with_indifferent_access)
|
23
|
+
@read = opt[:read]
|
24
|
+
@write = opt[:write].map { |x| x.is_a?(String) ? ['*', x] : x }.map { |x|
|
30
25
|
[compile_key_pattern(x[0]), x[1]]
|
31
26
|
}
|
32
27
|
@locale_data = {}
|
@@ -34,7 +29,7 @@ module I18n::Tasks
|
|
34
29
|
|
35
30
|
# get locale tree
|
36
31
|
def get(locale)
|
37
|
-
locale
|
32
|
+
locale = locale.to_s
|
38
33
|
@locale_data[locale] ||= begin
|
39
34
|
@read.map do |path|
|
40
35
|
Dir.glob path % {locale: locale}
|
@@ -17,9 +17,6 @@ module I18n::Tasks::KeyPatternMatching
|
|
17
17
|
# : matches a single key
|
18
18
|
# {a, b.c} match any in set, can use : and *, match is captured
|
19
19
|
def compile_key_pattern(key_pattern)
|
20
|
-
if key_pattern.end_with? '.'
|
21
|
-
I18n::Tasks.warn_deprecated %Q(please change pattern "#{key_pattern}" to "#{key_pattern += '*'}" in config/i18n-tasks.yml)
|
22
|
-
end
|
23
20
|
/^#{key_pattern.
|
24
21
|
gsub(/\./, '\.').
|
25
22
|
gsub(/\*/, '.*').
|
@@ -43,4 +40,4 @@ module I18n::Tasks::KeyPatternMatching
|
|
43
40
|
/^(?:#{prefixes.map { |p| Regexp.escape(p) }.join('|')})/
|
44
41
|
end
|
45
42
|
end
|
46
|
-
end
|
43
|
+
end
|
@@ -1,15 +1,18 @@
|
|
1
|
-
module I18n
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
module I18n
|
2
|
+
module Tasks
|
3
|
+
module RelativeKeys
|
4
|
+
# @param key [String] relative i18n key (starts with a .)
|
5
|
+
# @param path [String] path to the file containing the key
|
6
|
+
# @return [String] absolute version of the key
|
7
|
+
def absolutize_key(key, path, roots = relative_roots)
|
8
|
+
# normalized path
|
9
|
+
path = File.expand_path path
|
10
|
+
(path_root = roots.map { |path| File.expand_path path }.sort.reverse.detect { |root| path.start_with?(root + '/') }) or
|
11
|
+
raise "No relative key root detected for \"#{key}\" at #{path}. Please set relative_roots in config/i18n-tasks.yml (currently set to #{relative_roots})"
|
12
|
+
# key prefix based on path
|
13
|
+
prefix = path.gsub(%r(#{path_root}/|(\.[^/]+)*$), '').tr('/', '.').gsub(%r(\._), '.')
|
14
|
+
"#{prefix}#{key}"
|
15
|
+
end
|
16
|
+
end
|
14
17
|
end
|
15
18
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'i18n/tasks/relative_keys'
|
2
|
+
module I18n::Tasks::Scanners
|
3
|
+
class BaseScanner
|
4
|
+
include ::I18n::Tasks::RelativeKeys
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config.dup.with_indifferent_access.tap do |conf|
|
9
|
+
conf[:paths] = %w(app/) if conf[:paths].blank?
|
10
|
+
conf[:include] = Array(conf[:include]) if conf[:include].present?
|
11
|
+
conf[:exclude] = Array(conf[:exclude])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array] found key usages, absolutized and unique
|
16
|
+
def keys
|
17
|
+
@keys ||= traverse_files { |path| scan_file(path) }.flatten.uniq
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] keys used in file (unimplemented)
|
21
|
+
def scan_file(path)
|
22
|
+
raise 'Unimplemented'
|
23
|
+
end
|
24
|
+
|
25
|
+
# Run given block for every relevant file, according to config
|
26
|
+
# @return [Array] Results of block calls
|
27
|
+
def traverse_files
|
28
|
+
result = []
|
29
|
+
Find.find(*config[:paths]) do |path|
|
30
|
+
next if File.directory?(path)
|
31
|
+
next if config[:include] and !config[:include].any? { |glob| File.fnmatch(glob, path) }
|
32
|
+
next if config[:exclude].any? { |glob| File.fnmatch(glob, path) }
|
33
|
+
result << yield(path)
|
34
|
+
end
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def extract_key_from_match(match, path)
|
41
|
+
key = strip_literal(match[0])
|
42
|
+
key = absolutize_key(key, path) if path && key.start_with?('.')
|
43
|
+
key
|
44
|
+
end
|
45
|
+
|
46
|
+
# remove the leading colon and unwrap quotes from the key match
|
47
|
+
def strip_literal(literal)
|
48
|
+
key = literal
|
49
|
+
key.slice!(0) if ':' == key[0]
|
50
|
+
key = key[1..-2] if %w(' ").include?(key[0])
|
51
|
+
key
|
52
|
+
end
|
53
|
+
|
54
|
+
VALID_KEY_RE = /^[\w.\#{}]+$/
|
55
|
+
|
56
|
+
def valid_key?(key)
|
57
|
+
key =~ VALID_KEY_RE
|
58
|
+
end
|
59
|
+
|
60
|
+
def relative_roots
|
61
|
+
config[:relative_roots]
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Scans for I18n.t usages
|
2
|
+
require 'i18n/tasks/scanners/base_scanner'
|
3
|
+
module I18n::Tasks::Scanners
|
4
|
+
class PatternScanner < BaseScanner
|
5
|
+
LITERAL_RE = /:?".+?"|:?'.+?'|:\w+/
|
6
|
+
DEFAULT_PATTERN = /\bt(?:ranslate)?[( ]\s*(#{LITERAL_RE})/
|
7
|
+
|
8
|
+
# Extract i18n keys from file based on the pattern. The pattern must capture key literal.
|
9
|
+
# @return [String] keys found in file
|
10
|
+
def scan_file(path)
|
11
|
+
keys = []
|
12
|
+
File.open(path, 'rb') do |f|
|
13
|
+
f.read.scan(pattern) do |match|
|
14
|
+
key = extract_key_from_match(match, path)
|
15
|
+
keys << key if valid_key?(key)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
keys
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def pattern
|
23
|
+
@pattern ||= config[:pattern].present? ? Regexp.new(config[:pattern]) : DEFAULT_PATTERN
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,12 +1,19 @@
|
|
1
1
|
require 'find'
|
2
|
+
require 'i18n/tasks/scanners/pattern_scanner'
|
2
3
|
|
3
4
|
module I18n::Tasks::SourceKeys
|
4
|
-
# find all keys in the source (relative keys are
|
5
|
+
# find all keys in the source (relative keys are absolutized)
|
5
6
|
# @return [Array<String>]
|
6
7
|
def find_source_keys
|
7
|
-
@source_keys ||=
|
8
|
-
|
9
|
-
|
8
|
+
@source_keys ||= scanner.keys
|
9
|
+
end
|
10
|
+
|
11
|
+
def scanner
|
12
|
+
@scanner ||= begin
|
13
|
+
search_config = config[:search].with_indifferent_access
|
14
|
+
class_name = search_config[:scanner] || '::I18n::Tasks::Scanners::PatternScanner'
|
15
|
+
class_name.constantize.new search_config.merge(relative_roots: relative_roots)
|
16
|
+
end
|
10
17
|
end
|
11
18
|
|
12
19
|
# whether the key is used in the source
|
@@ -26,42 +33,4 @@ module I18n::Tasks::SourceKeys
|
|
26
33
|
@pattern_keys_prefixes ||=
|
27
34
|
find_source_keys.select { |k| k =~ /\#{.*?}/ || k.ends_with?('.') }.map { |k| k.split(/\.?#/)[0].presence }.compact
|
28
35
|
end
|
29
|
-
|
30
|
-
# Run given block for every relevant file, according to search_config
|
31
|
-
# @return [Array] Results of block calls
|
32
|
-
def traverse_files
|
33
|
-
result = []
|
34
|
-
Find.find(*search_config[:paths]) do |path|
|
35
|
-
next if File.directory?(path)
|
36
|
-
next if search_config[:include] and !search_config[:include].any? { |glob| File.fnmatch(glob, path) }
|
37
|
-
next if search_config[:exclude].any? { |glob| File.fnmatch(glob, path) }
|
38
|
-
result << yield(path)
|
39
|
-
end
|
40
|
-
result
|
41
|
-
end
|
42
|
-
|
43
|
-
# Extract i18n keys from file
|
44
|
-
# @return [String] keys used in file (absolutized and unique)
|
45
|
-
def extract_keys(path)
|
46
|
-
keys = []
|
47
|
-
File.open(path, 'rb') do |f|
|
48
|
-
f.read.scan(search_config[:pattern]) do |match|
|
49
|
-
key = parse_key(match)
|
50
|
-
key = absolutize_key(key, path) if key.start_with? '.'
|
51
|
-
if key =~ /^[\w.\#{}]+$/
|
52
|
-
keys << key
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
keys
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
# remove the leading colon and unwrap quotes from the key match
|
61
|
-
def parse_key(match)
|
62
|
-
key = match[0]
|
63
|
-
key.slice!(0) if ':' == key[0]
|
64
|
-
key = key[1..-2] if %w(' ").include?(key[0])
|
65
|
-
key
|
66
|
-
end
|
67
36
|
end
|
data/lib/i18n/tasks/version.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe '
|
4
|
-
|
5
|
-
|
6
|
-
let!(:pattern) { task.search_config[:pattern] }
|
3
|
+
describe 'Pattern Scanner' do
|
4
|
+
describe 'default pattern' do
|
5
|
+
let!(:pattern) { I18n::Tasks::Scanners::PatternScanner::DEFAULT_PATTERN }
|
7
6
|
|
8
7
|
['t "a.b"', "t 'a.b'", 't("a.b")', "t('a.b')",
|
9
8
|
"t('a.b', :arg => val)", "t('a.b', arg: val)",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -213,6 +213,8 @@ files:
|
|
213
213
|
- lib/i18n/tasks/reports/base.rb
|
214
214
|
- lib/i18n/tasks/reports/spreadsheet.rb
|
215
215
|
- lib/i18n/tasks/reports/terminal.rb
|
216
|
+
- lib/i18n/tasks/scanners/base_scanner.rb
|
217
|
+
- lib/i18n/tasks/scanners/pattern_scanner.rb
|
216
218
|
- lib/i18n/tasks/source_keys.rb
|
217
219
|
- lib/i18n/tasks/translation_data.rb
|
218
220
|
- lib/i18n/tasks/untranslated_keys.rb
|
@@ -227,9 +229,9 @@ files:
|
|
227
229
|
- spec/google_translate_spec.rb
|
228
230
|
- spec/i18n_tasks_spec.rb
|
229
231
|
- spec/key_pattern_matching_spec.rb
|
232
|
+
- spec/pattern_scanner_spec.rb
|
230
233
|
- spec/readme_spec.rb
|
231
234
|
- spec/relative_keys_spec.rb
|
232
|
-
- spec/source_keys_spec.rb
|
233
235
|
- spec/spec_helper.rb
|
234
236
|
- spec/support/fixtures.rb
|
235
237
|
- spec/support/i18n_tasks_output_matcher.rb
|
@@ -272,9 +274,9 @@ test_files:
|
|
272
274
|
- spec/google_translate_spec.rb
|
273
275
|
- spec/i18n_tasks_spec.rb
|
274
276
|
- spec/key_pattern_matching_spec.rb
|
277
|
+
- spec/pattern_scanner_spec.rb
|
275
278
|
- spec/readme_spec.rb
|
276
279
|
- spec/relative_keys_spec.rb
|
277
|
-
- spec/source_keys_spec.rb
|
278
280
|
- spec/spec_helper.rb
|
279
281
|
- spec/support/fixtures.rb
|
280
282
|
- spec/support/i18n_tasks_output_matcher.rb
|