i18n-tasks 0.9.6 → 0.9.7
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/README.md +1 -1
- data/Rakefile +2 -1
- data/bin/i18n-tasks +1 -0
- data/config/locales/en.yml +15 -9
- data/config/locales/ru.yml +80 -74
- data/i18n-tasks.gemspec +9 -8
- data/lib/i18n/tasks.rb +2 -5
- data/lib/i18n/tasks/cli.rb +14 -18
- data/lib/i18n/tasks/command/commander.rb +2 -3
- data/lib/i18n/tasks/command/commands/health.rb +1 -1
- data/lib/i18n/tasks/command/commands/meta.rb +2 -2
- data/lib/i18n/tasks/command/commands/missing.rb +17 -19
- data/lib/i18n/tasks/command/commands/tree.rb +3 -3
- data/lib/i18n/tasks/command/commands/usages.rb +6 -5
- data/lib/i18n/tasks/command/commands/xlsx.rb +1 -1
- data/lib/i18n/tasks/command/dsl.rb +1 -2
- data/lib/i18n/tasks/command/option_parsers/enum.rb +6 -6
- data/lib/i18n/tasks/command/option_parsers/locale.rb +3 -1
- data/lib/i18n/tasks/command/options/data.rb +22 -21
- data/lib/i18n/tasks/command_error.rb +1 -3
- data/lib/i18n/tasks/configuration.rb +37 -27
- data/lib/i18n/tasks/console_context.rb +3 -2
- data/lib/i18n/tasks/data.rb +5 -4
- data/lib/i18n/tasks/data/adapter/json_adapter.rb +13 -12
- data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +13 -14
- data/lib/i18n/tasks/data/file_formats.rb +15 -10
- data/lib/i18n/tasks/data/file_system_base.rb +18 -22
- data/lib/i18n/tasks/data/router/conservative_router.rb +3 -6
- data/lib/i18n/tasks/data/router/pattern_router.rb +4 -5
- data/lib/i18n/tasks/data/tree/node.rb +20 -19
- data/lib/i18n/tasks/data/tree/nodes.rb +4 -3
- data/lib/i18n/tasks/data/tree/siblings.rb +36 -29
- data/lib/i18n/tasks/data/tree/traversal.rb +32 -35
- data/lib/i18n/tasks/google_translation.rb +22 -25
- data/lib/i18n/tasks/html_keys.rb +2 -0
- data/lib/i18n/tasks/ignore_keys.rb +3 -2
- data/lib/i18n/tasks/key_pattern_matching.rb +9 -8
- data/lib/i18n/tasks/locale_list.rb +4 -6
- data/lib/i18n/tasks/locale_pathname.rb +8 -8
- data/lib/i18n/tasks/logging.rb +3 -3
- data/lib/i18n/tasks/missing_keys.rb +29 -31
- data/lib/i18n/tasks/plural_keys.rb +6 -7
- data/lib/i18n/tasks/references.rb +72 -41
- data/lib/i18n/tasks/reports/base.rb +8 -7
- data/lib/i18n/tasks/reports/spreadsheet.rb +15 -16
- data/lib/i18n/tasks/reports/terminal.rb +32 -32
- data/lib/i18n/tasks/scanners/file_scanner.rb +6 -5
- data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +1 -2
- data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +0 -1
- data/lib/i18n/tasks/scanners/files/file_finder.rb +12 -15
- data/lib/i18n/tasks/scanners/files/file_reader.rb +0 -1
- data/lib/i18n/tasks/scanners/occurrence_from_position.rb +8 -7
- data/lib/i18n/tasks/scanners/pattern_mapper.rb +2 -2
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +9 -7
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +1 -2
- data/lib/i18n/tasks/scanners/relative_keys.rb +11 -11
- data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -4
- data/lib/i18n/tasks/scanners/results/occurrence.rb +8 -7
- data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +2 -2
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +39 -31
- data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +9 -3
- data/lib/i18n/tasks/split_key.rb +5 -6
- data/lib/i18n/tasks/stats.rb +10 -8
- data/lib/i18n/tasks/string_interpolation.rb +1 -1
- data/lib/i18n/tasks/unused_keys.rb +2 -2
- data/lib/i18n/tasks/used_keys.rb +47 -43
- data/lib/i18n/tasks/version.rb +1 -1
- data/templates/rspec/i18n_spec.rb +2 -2
- metadata +30 -3
@@ -7,12 +7,11 @@ module I18n::Tasks::Scanners::Files
|
|
7
7
|
# @note This class is thread-safe. All methods are cached.
|
8
8
|
# @since 0.9.0
|
9
9
|
class CachingFileFinderProvider
|
10
|
-
|
11
10
|
# @param exclude [Array<String>]
|
12
11
|
def initialize(exclude: [])
|
13
12
|
@cache = {}
|
14
13
|
@mutex = Mutex.new
|
15
|
-
@defaults = {exclude: exclude}
|
14
|
+
@defaults = { exclude: exclude }
|
16
15
|
end
|
17
16
|
|
18
17
|
# Initialize a {CachingFileFinder} or get one from cache based on the constructor arguments.
|
@@ -13,7 +13,7 @@ module I18n::Tasks::Scanners::Files
|
|
13
13
|
# @param exclude [Arry<String>] {File.fnmatch}-compatible patterns of files to exclude.
|
14
14
|
# Files matching any of the exclusion patterns will be excluded even if they match an inclusion pattern.
|
15
15
|
def initialize(paths: ['.'], only: nil, exclude: [])
|
16
|
-
|
16
|
+
fail 'paths argument is required' if paths.nil?
|
17
17
|
@paths = paths
|
18
18
|
@include = only
|
19
19
|
@exclude = exclude || []
|
@@ -29,22 +29,19 @@ module I18n::Tasks::Scanners::Files
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# @return [Array<String>] found files
|
32
|
-
def find_files
|
32
|
+
def find_files # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
33
33
|
results = []
|
34
34
|
paths = @paths.select { |p| File.exist?(p) }
|
35
|
-
if paths.empty?
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
else
|
46
|
-
results << path
|
47
|
-
end
|
35
|
+
log_warn "None of the search.paths exist #{@paths.inspect}" if paths.empty?
|
36
|
+
Find.find(*paths) do |path|
|
37
|
+
is_dir = File.directory?(path)
|
38
|
+
hidden = File.basename(path).start_with?('.') && !%w(. ./).include?(path)
|
39
|
+
not_incl = @include && !path_fnmatch_any?(path, @include)
|
40
|
+
excl = path_fnmatch_any?(path, @exclude)
|
41
|
+
if is_dir || hidden || not_incl || excl
|
42
|
+
Find.prune if is_dir && (hidden || excl)
|
43
|
+
else
|
44
|
+
results << path
|
48
45
|
end
|
49
46
|
end
|
50
47
|
results
|
@@ -8,18 +8,19 @@ module I18n
|
|
8
8
|
#
|
9
9
|
# @param path [String]
|
10
10
|
# @param contents [String] contents of the file at the path.
|
11
|
-
# @param position [
|
11
|
+
# @param position [Integer] position just before the beginning of the match.
|
12
12
|
# @return [Results::Occurrence]
|
13
13
|
def occurrence_from_position(path, contents, position, raw_key: nil)
|
14
14
|
line_begin = contents.rindex(/^/, position - 1)
|
15
15
|
line_end = contents.index(/.(?=\r?\n|$)/, position)
|
16
16
|
Results::Occurrence.new(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
path: path,
|
18
|
+
pos: position,
|
19
|
+
line_num: contents[0..position].count("\n") + 1,
|
20
|
+
line_pos: position - line_begin + 1,
|
21
|
+
line: contents[line_begin..line_end],
|
22
|
+
raw_key: raw_key
|
23
|
+
)
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -40,7 +40,7 @@ module I18n::Tasks::Scanners
|
|
40
40
|
next unless valid_key?(matches[:key])
|
41
41
|
end
|
42
42
|
result << [absolute_key(key % matches, path),
|
43
|
-
|
43
|
+
occurrence_from_position(path, text, match.offset(0).first)]
|
44
44
|
end
|
45
45
|
result
|
46
46
|
end
|
@@ -52,7 +52,7 @@ module I18n::Tasks::Scanners
|
|
52
52
|
|
53
53
|
def configure_patterns(patterns)
|
54
54
|
patterns.map do |(pattern, key)|
|
55
|
-
[pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern % {key: KEY_GROUP}), key]
|
55
|
+
[pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern % { key: KEY_GROUP }), key]
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -13,8 +13,10 @@ module I18n::Tasks::Scanners
|
|
13
13
|
|
14
14
|
def initialize(**args)
|
15
15
|
super
|
16
|
-
@pattern
|
17
|
-
@ignore_lines_res = (config[:ignore_lines] || []).
|
16
|
+
@pattern = config[:pattern].present? ? Regexp.new(config[:pattern]) : default_pattern
|
17
|
+
@ignore_lines_res = (config[:ignore_lines] || []).each_with_object({}) do |(ext, re), h|
|
18
|
+
h[ext.to_s] = Regexp.new(re)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
|
20
22
|
protected
|
@@ -25,17 +27,17 @@ module I18n::Tasks::Scanners
|
|
25
27
|
keys = []
|
26
28
|
text = read_file(path)
|
27
29
|
text.scan(@pattern) do |match|
|
28
|
-
src_pos
|
30
|
+
src_pos = Regexp.last_match.offset(0).first
|
29
31
|
location = occurrence_from_position(path, text, src_pos, raw_key: strip_literal(match[0]))
|
30
32
|
next if exclude_line?(location.line, path)
|
31
33
|
key = match_to_key(match, path, location)
|
32
34
|
next unless key
|
33
|
-
key
|
35
|
+
key += ':' if key.end_with?('.')
|
34
36
|
next unless valid_key?(key)
|
35
37
|
keys << [key, location]
|
36
38
|
end
|
37
39
|
keys
|
38
|
-
rescue Exception => e
|
40
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
39
41
|
raise ::I18n::Tasks::CommandError.new(e, "Error scanning #{path}: #{e.message}")
|
40
42
|
end
|
41
43
|
|
@@ -67,8 +69,8 @@ module I18n::Tasks::Scanners
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def closest_method(occurrence)
|
70
|
-
method = File.readlines(occurrence.path, encoding: 'UTF-8'
|
71
|
-
|
72
|
+
method = File.readlines(occurrence.path, encoding: 'UTF-8')
|
73
|
+
.first(occurrence.line_num - 1).reverse_each.find { |x| x =~ /\bdef\b/ }
|
72
74
|
method && method.strip.sub(/^def\s*/, '').sub(/[\(\s;].*$/, '')
|
73
75
|
end
|
74
76
|
|
@@ -6,7 +6,6 @@ module I18n::Tasks::Scanners
|
|
6
6
|
# both scope: "literal", and scope: [:array, :of, 'literals'] forms are supported
|
7
7
|
# Caveat: scope is only detected when it is the first argument
|
8
8
|
class PatternWithScopeScanner < PatternScanner
|
9
|
-
|
10
9
|
protected
|
11
10
|
|
12
11
|
def default_pattern
|
@@ -24,7 +23,7 @@ module I18n::Tasks::Scanners
|
|
24
23
|
key = super
|
25
24
|
scope = match[1]
|
26
25
|
if scope
|
27
|
-
scope_ns = scope.gsub(/[\[\]\s]+/, ''
|
26
|
+
scope_ns = scope.gsub(/[\[\]\s]+/, '').split(',').map { |arg| strip_literal(arg) } * '.'
|
28
27
|
"#{scope_ns}.#{key}"
|
29
28
|
else
|
30
29
|
key unless match[0] =~ /\A\w/
|
@@ -12,40 +12,40 @@ module I18n
|
|
12
12
|
return key unless key.start_with?(DOT)
|
13
13
|
fail 'roots argument is required' unless roots.present?
|
14
14
|
normalized_path = File.expand_path(path)
|
15
|
-
root = path_root(normalized_path, roots)
|
16
|
-
|
17
|
-
|
18
|
-
normalized_path.sub!(root, ''
|
15
|
+
(root = path_root(normalized_path, roots)) ||
|
16
|
+
fail(CommandError, "Cannot resolve relative key \"#{key}\".\n" \
|
17
|
+
"Set search.relative_roots in config/i18n-tasks.yml (currently #{roots.inspect})")
|
18
|
+
normalized_path.sub!(root, '')
|
19
19
|
"#{prefix(normalized_path, calling_method: calling_method)}#{key}"
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
DOT = '.'
|
24
|
+
DOT = '.'
|
25
25
|
|
26
26
|
# Detect the appropriate relative path root
|
27
27
|
# @param [String] path /full/path
|
28
28
|
# @param [Array<String>] roots array of full paths
|
29
29
|
# @return [String] the closest ancestor root for path, with a trailing {File::SEPARATOR}.
|
30
30
|
def path_root(path, roots)
|
31
|
-
roots.map
|
31
|
+
roots.map do |p|
|
32
32
|
File.expand_path(p) + File::SEPARATOR
|
33
|
-
|
33
|
+
end.sort.reverse_each.detect do |root|
|
34
34
|
path.start_with?(root)
|
35
|
-
|
35
|
+
end
|
36
36
|
end
|
37
37
|
|
38
38
|
# @param normalized_path [String] path/relative/to/a/root
|
39
39
|
# @param calling_method [#call, Symbol, String, false, nil]
|
40
40
|
def prefix(normalized_path, calling_method: nil)
|
41
|
-
file_key = normalized_path.gsub(%r(
|
41
|
+
file_key = normalized_path.gsub(%r{(\.[^/]+)*$}, '').tr(File::SEPARATOR, DOT)
|
42
42
|
calling_method = calling_method.call if calling_method.respond_to?(:call)
|
43
43
|
if calling_method && calling_method.present?
|
44
44
|
# Relative keys in mailers have a `_mailer` infix, but relative keys in controllers do not have one:
|
45
|
-
"#{file_key.sub(/_controller$/, ''
|
45
|
+
"#{file_key.sub(/_controller$/, '')}.#{calling_method}"
|
46
46
|
else
|
47
47
|
# Remove _ prefix from partials
|
48
|
-
file_key.gsub(
|
48
|
+
file_key.gsub(/\._/, DOT)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -40,15 +40,14 @@ module I18n::Tasks::Scanners::Results
|
|
40
40
|
# @param keys_occurrences [Enumerable<KeyOccurrences>]
|
41
41
|
# @return [Array<KeyOccurrences>] a new array.
|
42
42
|
def self.merge_keys(keys_occurrences)
|
43
|
-
keys_occurrences.
|
43
|
+
keys_occurrences.each_with_object({}) do |key_occurrences, results_by_key|
|
44
44
|
(results_by_key[key_occurrences.key] ||= []) << key_occurrences.occurrences
|
45
|
-
|
46
|
-
}.map { |key, all_occurrences|
|
45
|
+
end.map do |key, all_occurrences|
|
47
46
|
occurrences = all_occurrences.flatten(1)
|
48
47
|
occurrences.sort_by!(&:path)
|
49
48
|
occurrences.uniq!
|
50
49
|
new(key: key, occurrences: occurrences)
|
51
|
-
|
50
|
+
end
|
52
51
|
end
|
53
52
|
end
|
54
53
|
end
|
@@ -9,13 +9,13 @@ module I18n::Tasks
|
|
9
9
|
# @return [String] source path relative to the current working directory.
|
10
10
|
attr_reader :path
|
11
11
|
|
12
|
-
# @return [
|
12
|
+
# @return [Integer] count of characters in the file before the occurrence.
|
13
13
|
attr_reader :pos
|
14
14
|
|
15
|
-
# @return [
|
15
|
+
# @return [Integer] line number of the occurrence, counting from 1.
|
16
16
|
attr_reader :line_num
|
17
17
|
|
18
|
-
# @return [
|
18
|
+
# @return [Integer] position of the start of the occurrence in the line, counting from 1.
|
19
19
|
attr_reader :line_pos
|
20
20
|
|
21
21
|
# @return [String] the line of the occurrence, excluding the last LF or CRLF.
|
@@ -28,12 +28,13 @@ module I18n::Tasks
|
|
28
28
|
attr_accessor :raw_key
|
29
29
|
|
30
30
|
# @param path [String]
|
31
|
-
# @param pos [
|
32
|
-
# @param line_num [
|
33
|
-
# @param line_pos [
|
31
|
+
# @param pos [Integer]
|
32
|
+
# @param line_num [Integer]
|
33
|
+
# @param line_pos [Integer]
|
34
34
|
# @param line [String]
|
35
35
|
# @param raw_key [String, nil]
|
36
36
|
# @param default_arg [String, nil]
|
37
|
+
# rubocop:disable Metrics/ParameterLists
|
37
38
|
def initialize(path:, pos:, line_num:, line_pos:, line:, raw_key: nil, default_arg: nil)
|
38
39
|
@path = path
|
39
40
|
@pos = pos
|
@@ -50,7 +51,7 @@ module I18n::Tasks
|
|
50
51
|
|
51
52
|
def ==(other)
|
52
53
|
other.path == @path && other.pos == @pos && other.line_num == @line_num && other.line == @line &&
|
53
|
-
|
54
|
+
other.raw_key == @raw_key && other.default_arg == @default_arg
|
54
55
|
end
|
55
56
|
|
56
57
|
def eql?(other)
|
@@ -46,8 +46,8 @@ module I18n::Tasks::Scanners
|
|
46
46
|
receiver = send_node.children[0]
|
47
47
|
message = send_node.children[1]
|
48
48
|
if @messages.include?(message) &&
|
49
|
-
|
50
|
-
|
49
|
+
# use `any?` because `include?` checks type equality, but the receiver is a Parser::AST::Node != AST::Node.
|
50
|
+
@receivers.any? { |r| r == receiver }
|
51
51
|
@callback.call(send_node, @method_name)
|
52
52
|
else
|
53
53
|
handler_missing send_node
|
@@ -4,13 +4,16 @@ require 'i18n/tasks/scanners/relative_keys'
|
|
4
4
|
require 'i18n/tasks/scanners/ruby_ast_call_finder'
|
5
5
|
require 'parser/current'
|
6
6
|
|
7
|
+
# rubocop:disable Metrics/AbcSize,Metrics/BlockNesting,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
8
|
+
# TODO: make this class more readable.
|
9
|
+
|
7
10
|
module I18n::Tasks::Scanners
|
8
11
|
# Scan for I18n.translate calls using whitequark/parser
|
9
|
-
class RubyAstScanner < FileScanner
|
12
|
+
class RubyAstScanner < FileScanner # rubocop:disable Metrics/ClassLength
|
10
13
|
include RelativeKeys
|
11
14
|
include AST::Sexp
|
12
15
|
|
13
|
-
MAGIC_COMMENT_PREFIX = /\A.\s*i18n-tasks-use\s
|
16
|
+
MAGIC_COMMENT_PREFIX = /\A.\s*i18n-tasks-use\s+/
|
14
17
|
|
15
18
|
def initialize(messages: %i(t translate), receivers: [nil, s(:const, nil, :I18n)], **args)
|
16
19
|
super(args)
|
@@ -41,13 +44,13 @@ module I18n::Tasks::Scanners
|
|
41
44
|
@parser.reset
|
42
45
|
associated_node = comment_to_node[comment]
|
43
46
|
@call_finder.collect_calls(
|
44
|
-
|
47
|
+
@parser.parse(make_buffer(path, comment.text.sub(MAGIC_COMMENT_PREFIX, '').split(/\s+(?=t)/).join('; ')))
|
45
48
|
) do |send_node, _method_name|
|
46
49
|
# method_name is not available at this stage
|
47
50
|
send_node_to_key_occurrence(send_node, nil, location: associated_node || comment.location)
|
48
51
|
end
|
49
52
|
end
|
50
|
-
rescue Exception => e
|
53
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
51
54
|
raise ::I18n::Tasks::CommandError.new(e, "Error scanning #{path}: #{e.message}")
|
52
55
|
end
|
53
56
|
|
@@ -57,16 +60,16 @@ module I18n::Tasks::Scanners
|
|
57
60
|
# @return [nil, [key, Occurrence]] full absolute key name and the occurrence.
|
58
61
|
def send_node_to_key_occurrence(send_node, method_name, location: send_node.loc)
|
59
62
|
if (first_arg_node = send_node.children[2]) &&
|
60
|
-
|
63
|
+
(key = extract_string(first_arg_node))
|
61
64
|
if (second_arg_node = send_node.children[3]) &&
|
62
|
-
|
63
|
-
if (scope_node = extract_hash_pair(second_arg_node, 'scope'
|
65
|
+
second_arg_node.type == :hash
|
66
|
+
if (scope_node = extract_hash_pair(second_arg_node, 'scope'))
|
64
67
|
scope = extract_string(scope_node.children[1],
|
65
|
-
array_join_with: '.'
|
68
|
+
array_join_with: '.', array_flatten: true, array_reject_blank: true)
|
66
69
|
return nil if scope.nil? && scope_node.type != :nil
|
67
|
-
key = [scope, key].join('.') unless scope == ''
|
70
|
+
key = [scope, key].join('.') unless scope == ''
|
68
71
|
end
|
69
|
-
default_arg = if (default_arg_node = extract_hash_pair(second_arg_node, 'default'
|
72
|
+
default_arg = if (default_arg_node = extract_hash_pair(second_arg_node, 'default'))
|
70
73
|
extract_string(default_arg_node.children[1])
|
71
74
|
end
|
72
75
|
end
|
@@ -86,11 +89,11 @@ module I18n::Tasks::Scanners
|
|
86
89
|
# @param key [String] node key as a string (indifferent symbol-string matching).
|
87
90
|
# @return [AST::Node, nil] a node of type `:pair` or nil.
|
88
91
|
def extract_hash_pair(node, key)
|
89
|
-
node.children.detect
|
92
|
+
node.children.detect do |child|
|
90
93
|
next unless child.type == :pair
|
91
94
|
key_node = child.children[0]
|
92
95
|
%i(sym str).include?(key_node.type) && key_node.children[0].to_s == key
|
93
|
-
|
96
|
+
end
|
94
97
|
end
|
95
98
|
|
96
99
|
# If the node type is of `%i(sym str int false true)`, return the value as a string.
|
@@ -111,16 +114,17 @@ module I18n::Tasks::Scanners
|
|
111
114
|
elsif %i(true false).include?(node.type)
|
112
115
|
node.type.to_s
|
113
116
|
elsif :nil == node.type
|
114
|
-
''
|
117
|
+
''
|
115
118
|
elsif :array == node.type && array_join_with
|
116
119
|
extract_array_as_string(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
120
|
+
node,
|
121
|
+
array_join_with: array_join_with,
|
122
|
+
array_flatten: array_flatten,
|
123
|
+
array_reject_blank: array_reject_blank
|
124
|
+
).tap do |str|
|
121
125
|
# `nil` is returned when a dynamic value is encountered in strict mode. Propagate:
|
122
126
|
return nil if str.nil?
|
123
|
-
|
127
|
+
end
|
124
128
|
elsif !config[:strict] && %i(dsym dstr).include?(node.type)
|
125
129
|
node.children.map do |child|
|
126
130
|
if %i(sym str).include?(child.type)
|
@@ -153,10 +157,12 @@ module I18n::Tasks::Scanners
|
|
153
157
|
end
|
154
158
|
end
|
155
159
|
end
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
+
if array_reject_blank
|
161
|
+
children_strings.reject! do |x|
|
162
|
+
# empty strings and nils in the scope argument are ignored by i18n
|
163
|
+
x == ''
|
164
|
+
end
|
165
|
+
end
|
160
166
|
children_strings.join(array_join_with)
|
161
167
|
end
|
162
168
|
|
@@ -170,13 +176,14 @@ module I18n::Tasks::Scanners
|
|
170
176
|
# @return [Results::Occurrence]
|
171
177
|
def range_to_occurrence(raw_key, range, default_arg: nil)
|
172
178
|
Results::Occurrence.new(
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
179
|
+
path: range.source_buffer.name,
|
180
|
+
pos: range.begin_pos,
|
181
|
+
line_num: range.line,
|
182
|
+
line_pos: range.column,
|
183
|
+
line: range.source_line,
|
184
|
+
raw_key: raw_key,
|
185
|
+
default_arg: default_arg
|
186
|
+
)
|
180
187
|
end
|
181
188
|
|
182
189
|
# Create an {Parser::Source::Buffer} with the given contents.
|
@@ -186,9 +193,10 @@ module I18n::Tasks::Scanners
|
|
186
193
|
# @param contents [String]
|
187
194
|
# @return [Parser::Source::Buffer] file contents
|
188
195
|
def make_buffer(path, contents = read_file(path))
|
189
|
-
Parser::Source::Buffer.new(path).tap
|
196
|
+
Parser::Source::Buffer.new(path).tap do |buffer|
|
190
197
|
buffer.raw_source = contents
|
191
|
-
|
198
|
+
end
|
192
199
|
end
|
193
200
|
end
|
194
201
|
end
|
202
|
+
# rubocop:enable Metrics/AbcSize,Metrics/BlockNesting,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|