i18n-tasks 1.0.15 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +85 -13
- data/Rakefile +4 -4
- data/bin/i18n-tasks +3 -3
- data/config/locales/en.yml +6 -0
- data/config/locales/ru.yml +7 -0
- data/i18n-tasks.gemspec +28 -41
- data/lib/i18n/tasks/base_task.rb +19 -19
- data/lib/i18n/tasks/cli.rb +37 -30
- data/lib/i18n/tasks/command/collection.rb +4 -4
- data/lib/i18n/tasks/command/commander.rb +5 -5
- data/lib/i18n/tasks/command/commands/check_prism.rb +126 -0
- data/lib/i18n/tasks/command/commands/data.rb +33 -33
- data/lib/i18n/tasks/command/commands/eq_base.rb +3 -3
- data/lib/i18n/tasks/command/commands/health.rb +6 -5
- data/lib/i18n/tasks/command/commands/interpolations.rb +14 -3
- data/lib/i18n/tasks/command/commands/meta.rb +6 -6
- data/lib/i18n/tasks/command/commands/missing.rb +25 -25
- data/lib/i18n/tasks/command/commands/tree.rb +33 -33
- data/lib/i18n/tasks/command/commands/usages.rb +24 -24
- data/lib/i18n/tasks/command/dsl.rb +1 -1
- data/lib/i18n/tasks/command/option_parsers/enum.rb +5 -5
- data/lib/i18n/tasks/command/option_parsers/locale.rb +4 -4
- data/lib/i18n/tasks/command/options/common.rb +16 -16
- data/lib/i18n/tasks/command/options/data.rb +18 -18
- data/lib/i18n/tasks/command/options/locales.rb +32 -32
- data/lib/i18n/tasks/commands.rb +14 -12
- data/lib/i18n/tasks/concurrent/cache.rb +1 -1
- data/lib/i18n/tasks/concurrent/cached_value.rb +1 -1
- data/lib/i18n/tasks/configuration.rb +22 -21
- data/lib/i18n/tasks/console_context.rb +11 -11
- data/lib/i18n/tasks/data/adapter/json_adapter.rb +1 -1
- data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +5 -5
- data/lib/i18n/tasks/data/file_formats.rb +3 -3
- data/lib/i18n/tasks/data/file_system.rb +5 -5
- data/lib/i18n/tasks/data/file_system_base.rb +26 -26
- data/lib/i18n/tasks/data/language_names.rb +202 -0
- data/lib/i18n/tasks/data/router/conservative_router.rb +3 -3
- data/lib/i18n/tasks/data/router/isolating_router.rb +19 -19
- data/lib/i18n/tasks/data/router/pattern_router.rb +5 -5
- data/lib/i18n/tasks/data/tree/node.rb +27 -27
- data/lib/i18n/tasks/data/tree/nodes.rb +10 -10
- data/lib/i18n/tasks/data/tree/siblings.rb +20 -20
- data/lib/i18n/tasks/data/tree/traversal.rb +5 -5
- data/lib/i18n/tasks/data.rb +4 -4
- data/lib/i18n/tasks/html_keys.rb +2 -2
- data/lib/i18n/tasks/ignore_keys.rb +9 -9
- data/lib/i18n/tasks/interpolations.rb +21 -1
- data/lib/i18n/tasks/key_pattern_matching.rb +8 -8
- data/lib/i18n/tasks/logging.rb +2 -1
- data/lib/i18n/tasks/missing_keys.rb +24 -8
- data/lib/i18n/tasks/plural_keys.rb +6 -4
- data/lib/i18n/tasks/references.rb +4 -4
- data/lib/i18n/tasks/reports/base.rb +18 -14
- data/lib/i18n/tasks/reports/terminal.rb +64 -47
- data/lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/default_i18n_subject_matcher.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb +10 -10
- data/lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb +1 -1
- data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +69 -10
- data/lib/i18n/tasks/scanners/file_scanner.rb +5 -5
- data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +3 -3
- data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +3 -3
- data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +2 -2
- data/lib/i18n/tasks/scanners/files/file_finder.rb +8 -8
- data/lib/i18n/tasks/scanners/files/file_reader.rb +1 -1
- data/lib/i18n/tasks/scanners/local_ruby_parser.rb +8 -8
- data/lib/i18n/tasks/scanners/occurrence_from_position.rb +1 -1
- data/lib/i18n/tasks/scanners/pattern_mapper.rb +7 -7
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +20 -20
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +8 -8
- data/lib/i18n/tasks/scanners/prism_scanners/arguments_visitor.rb +8 -1
- data/lib/i18n/tasks/scanners/prism_scanners/nodes.rb +101 -61
- data/lib/i18n/tasks/scanners/prism_scanners/visitor.rb +169 -105
- data/lib/i18n/tasks/scanners/relative_keys.rb +8 -8
- data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -3
- data/lib/i18n/tasks/scanners/results/occurrence.rb +14 -10
- data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +1 -1
- data/lib/i18n/tasks/scanners/ruby_key_literals.rb +6 -6
- data/lib/i18n/tasks/scanners/ruby_parser_factory.rb +1 -1
- data/lib/i18n/tasks/scanners/ruby_scanner.rb +225 -0
- data/lib/i18n/tasks/scanners/scanner.rb +2 -2
- data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +1 -1
- data/lib/i18n/tasks/split_key.rb +4 -4
- data/lib/i18n/tasks/stats.rb +3 -3
- data/lib/i18n/tasks/translation.rb +5 -5
- data/lib/i18n/tasks/translators/base_translator.rb +40 -14
- data/lib/i18n/tasks/translators/deepl_translator.rb +17 -14
- data/lib/i18n/tasks/translators/google_translator.rb +169 -25
- data/lib/i18n/tasks/translators/openai_translator.rb +34 -23
- data/lib/i18n/tasks/translators/watsonx_translator.rb +16 -16
- data/lib/i18n/tasks/translators/yandex_translator.rb +8 -8
- data/lib/i18n/tasks/unused_keys.rb +1 -1
- data/lib/i18n/tasks/used_keys.rb +32 -33
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/i18n/tasks.rb +17 -17
- data/templates/config/i18n-tasks.yml +12 -0
- data/templates/minitest/i18n_test.rb +3 -3
- data/templates/rspec/i18n_spec.rb +7 -7
- metadata +25 -185
- data/lib/i18n/tasks/scanners/prism_scanner.rb +0 -83
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +0 -145
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "fileutils"
|
|
4
4
|
|
|
5
5
|
module I18n
|
|
6
6
|
module Tasks
|
|
@@ -21,7 +21,7 @@ module I18n
|
|
|
21
21
|
|
|
22
22
|
def adapter_op(op, format, tree, config)
|
|
23
23
|
self.class.adapter_by_name(format).send(op, tree, config)
|
|
24
|
-
rescue
|
|
24
|
+
rescue => e
|
|
25
25
|
raise CommandError, "#{format} #{op} error: #{e.message}"
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -44,7 +44,7 @@ module I18n
|
|
|
44
44
|
|
|
45
45
|
# @return [String]
|
|
46
46
|
def read_file(path)
|
|
47
|
-
::File.read(path, encoding:
|
|
47
|
+
::File.read(path, encoding: "UTF-8")
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def write_tree(path, tree, sort = true)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
3
|
+
require "i18n/tasks/data/file_system_base"
|
|
4
|
+
require "i18n/tasks/data/adapter/json_adapter"
|
|
5
|
+
require "i18n/tasks/data/adapter/yaml_adapter"
|
|
6
6
|
|
|
7
7
|
module I18n::Tasks
|
|
8
8
|
module Data
|
|
9
9
|
class FileSystem < FileSystemBase
|
|
10
|
-
register_adapter :yaml,
|
|
11
|
-
register_adapter :json,
|
|
10
|
+
register_adapter :yaml, "*.yml", Adapter::YamlAdapter
|
|
11
|
+
register_adapter :json, "*.json", Adapter::JsonAdapter
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
3
|
+
require "i18n/tasks/data/tree/node"
|
|
4
|
+
require "i18n/tasks/data/router/pattern_router"
|
|
5
|
+
require "i18n/tasks/data/router/conservative_router"
|
|
6
|
+
require "i18n/tasks/data/router/isolating_router"
|
|
7
|
+
require "i18n/tasks/data/file_formats"
|
|
8
|
+
require "i18n/tasks/key_pattern_matching"
|
|
9
9
|
|
|
10
10
|
module I18n::Tasks
|
|
11
11
|
module Data
|
|
@@ -18,8 +18,8 @@ module I18n::Tasks
|
|
|
18
18
|
attr_writer :router
|
|
19
19
|
|
|
20
20
|
DEFAULTS = {
|
|
21
|
-
read: [
|
|
22
|
-
write: [
|
|
21
|
+
read: ["config/locales/%{locale}.yml"],
|
|
22
|
+
write: ["config/locales/%{locale}.yml"]
|
|
23
23
|
}.freeze
|
|
24
24
|
|
|
25
25
|
def initialize(config = {})
|
|
@@ -29,9 +29,9 @@ module I18n::Tasks
|
|
|
29
29
|
locales = config[:locales].presence
|
|
30
30
|
@locales = LocaleList.normalize_locale_list(locales || available_locales, base_locale, true)
|
|
31
31
|
if locales.present?
|
|
32
|
-
log_verbose "locales read from config #{@locales *
|
|
32
|
+
log_verbose "locales read from config #{@locales * ", "}"
|
|
33
33
|
else
|
|
34
|
-
log_verbose "locales inferred from data: #{@locales *
|
|
34
|
+
log_verbose "locales inferred from data: #{@locales * ", "}"
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -43,7 +43,7 @@ module I18n::Tasks
|
|
|
43
43
|
@trees[locale] ||= read_locale(locale)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
alias_method :[], :get
|
|
47
47
|
|
|
48
48
|
# @param [String, Symbol] locale
|
|
49
49
|
# @return [::I18n::Tasks::Data::Siblings]
|
|
@@ -72,14 +72,14 @@ module I18n::Tasks
|
|
|
72
72
|
@available_locales = nil
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
alias_method :[]=, :set
|
|
76
76
|
|
|
77
77
|
# @param [String] locale
|
|
78
78
|
# @return [Array<String>] paths to files that are not normalized
|
|
79
79
|
def non_normalized_paths(locale)
|
|
80
80
|
router.route(locale, get(locale))
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
.reject { |path, tree_slice| normalized?(path, tree_slice) }
|
|
82
|
+
.map(&:first)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def write(forest)
|
|
@@ -107,7 +107,7 @@ module I18n::Tasks
|
|
|
107
107
|
|
|
108
108
|
# @return self
|
|
109
109
|
def reload
|
|
110
|
-
@trees
|
|
110
|
+
@trees = nil
|
|
111
111
|
@available_locales = nil
|
|
112
112
|
self
|
|
113
113
|
end
|
|
@@ -117,10 +117,10 @@ module I18n::Tasks
|
|
|
117
117
|
@available_locales ||= begin
|
|
118
118
|
locales = Set.new
|
|
119
119
|
Array(config[:read]).map do |pattern|
|
|
120
|
-
[pattern, Dir.glob(format(pattern, locale:
|
|
120
|
+
[pattern, Dir.glob(format(pattern, locale: "*"))] if pattern.include?("%{locale}")
|
|
121
121
|
end.compact.each do |pattern, paths|
|
|
122
|
-
p
|
|
123
|
-
p
|
|
122
|
+
p = pattern.gsub("\\", "\\\\").gsub("/", '\/').gsub(".", '\.')
|
|
123
|
+
p = p.gsub(/(\*+)/) { (Regexp.last_match(1) == "**") ? ".*" : "[^/]*?" }.gsub("%{locale}", "([^/.]+)")
|
|
124
124
|
re = /\A#{p}\z/
|
|
125
125
|
paths.each do |path|
|
|
126
126
|
locales << Regexp.last_match(1) if re =~ path
|
|
@@ -143,7 +143,7 @@ module I18n::Tasks
|
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
def with_router(router)
|
|
146
|
-
router_was
|
|
146
|
+
router_was = self.router
|
|
147
147
|
self.router = router
|
|
148
148
|
yield
|
|
149
149
|
ensure
|
|
@@ -151,13 +151,13 @@ module I18n::Tasks
|
|
|
151
151
|
end
|
|
152
152
|
|
|
153
153
|
ROUTER_NAME_ALIASES = {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
"conservative_router" => "I18n::Tasks::Data::Router::ConservativeRouter",
|
|
155
|
+
"isolating_router" => "I18n::Tasks::Data::Router::IsolatingRouter",
|
|
156
|
+
"pattern_router" => "I18n::Tasks::Data::Router::PatternRouter"
|
|
157
157
|
}.freeze
|
|
158
158
|
def router
|
|
159
159
|
@router ||= begin
|
|
160
|
-
name = @config[:router].presence ||
|
|
160
|
+
name = @config[:router].presence || "conservative_router"
|
|
161
161
|
name = ROUTER_NAME_ALIASES[name] || name
|
|
162
162
|
router_class = ActiveSupport::Inflector.constantize(name)
|
|
163
163
|
router_class.new(self, @config.merge(base_locale: base_locale, locales: locales))
|
|
@@ -173,7 +173,7 @@ module I18n::Tasks
|
|
|
173
173
|
[path.freeze, load_file(path) || {}]
|
|
174
174
|
end.map do |path, data|
|
|
175
175
|
if router.is_a?(I18n::Tasks::Data::Router::IsolatingRouter)
|
|
176
|
-
data.transform_values! { |tree| {
|
|
176
|
+
data.transform_values! { |tree| {"<#{router.alternate_path_for(path, base_locale)}>" => tree} }
|
|
177
177
|
end
|
|
178
178
|
filter_nil_keys! path, data
|
|
179
179
|
Data::Tree::Siblings.from_nested_hash(data).tap do |s|
|
|
@@ -188,11 +188,11 @@ module I18n::Tasks
|
|
|
188
188
|
data.delete(key)
|
|
189
189
|
log_warn <<~TEXT
|
|
190
190
|
Skipping a nil key found in #{path.inspect}:
|
|
191
|
-
key: #{suffix.join(
|
|
191
|
+
key: #{suffix.join(".")}.`nil`
|
|
192
192
|
value: #{value.inspect}
|
|
193
193
|
Nil keys are not supported by i18n.
|
|
194
194
|
The following unquoted YAML keys result in a nil key:
|
|
195
|
-
#{%w[null Null NULL ~].join(
|
|
195
|
+
#{%w[null Null NULL ~].join(", ")}
|
|
196
196
|
See http://yaml.org/type/null.html
|
|
197
197
|
TEXT
|
|
198
198
|
elsif value.is_a?(Hash)
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module I18n
|
|
4
|
+
module Tasks
|
|
5
|
+
module Data
|
|
6
|
+
module LanguageNames # rubocop:disable Metrics/ModuleLength
|
|
7
|
+
# Data loaded from https://github.com/grosser/i18n_data
|
|
8
|
+
# I18nData.languages.transform_keys!(&:to_sym).transform_values!{|v| v.split(";").first }
|
|
9
|
+
DATA = {
|
|
10
|
+
AA: "Afar",
|
|
11
|
+
AB: "Abkhazian",
|
|
12
|
+
AF: "Afrikaans",
|
|
13
|
+
AK: "Akan",
|
|
14
|
+
AM: "Amharic",
|
|
15
|
+
AR: "Arabic",
|
|
16
|
+
AN: "Aragonese",
|
|
17
|
+
AS: "Assamese",
|
|
18
|
+
AV: "Avaric",
|
|
19
|
+
AE: "Avestan",
|
|
20
|
+
AY: "Aymara",
|
|
21
|
+
AZ: "Azerbaijani",
|
|
22
|
+
BA: "Bashkir",
|
|
23
|
+
BM: "Bambara",
|
|
24
|
+
BE: "Belarusian",
|
|
25
|
+
BN: "Bengali",
|
|
26
|
+
BH: "Bihari languages",
|
|
27
|
+
BI: "Bislama",
|
|
28
|
+
BO: "Tibetan",
|
|
29
|
+
BS: "Bosnian",
|
|
30
|
+
BR: "Breton",
|
|
31
|
+
BG: "Bulgarian",
|
|
32
|
+
CA: "Catalan",
|
|
33
|
+
CS: "Czech",
|
|
34
|
+
CH: "Chamorro",
|
|
35
|
+
CE: "Chechen",
|
|
36
|
+
CU: "Church Slavic",
|
|
37
|
+
CV: "Chuvash",
|
|
38
|
+
KW: "Cornish",
|
|
39
|
+
CO: "Corsican",
|
|
40
|
+
CR: "Cree",
|
|
41
|
+
CY: "Welsh",
|
|
42
|
+
DA: "Danish",
|
|
43
|
+
DE: "German",
|
|
44
|
+
DV: "Divehi",
|
|
45
|
+
DZ: "Dzongkha",
|
|
46
|
+
EL: "Greek, Modern (1453-)",
|
|
47
|
+
EN: "English",
|
|
48
|
+
EO: "Esperanto",
|
|
49
|
+
ET: "Estonian",
|
|
50
|
+
EU: "Basque",
|
|
51
|
+
EE: "Ewe",
|
|
52
|
+
FO: "Faroese",
|
|
53
|
+
FA: "Persian",
|
|
54
|
+
FJ: "Fijian",
|
|
55
|
+
FI: "Finnish",
|
|
56
|
+
FR: "French",
|
|
57
|
+
FY: "Western Frisian",
|
|
58
|
+
FF: "Fulah",
|
|
59
|
+
GD: "Gaelic",
|
|
60
|
+
GA: "Irish",
|
|
61
|
+
GL: "Galician",
|
|
62
|
+
GV: "Manx",
|
|
63
|
+
GN: "Guarani",
|
|
64
|
+
GU: "Gujarati",
|
|
65
|
+
HT: "Haitian",
|
|
66
|
+
HA: "Hausa",
|
|
67
|
+
HE: "Hebrew",
|
|
68
|
+
HZ: "Herero",
|
|
69
|
+
HI: "Hindi",
|
|
70
|
+
HO: "Hiri Motu",
|
|
71
|
+
HR: "Croatian",
|
|
72
|
+
HU: "Hungarian",
|
|
73
|
+
HY: "Armenian",
|
|
74
|
+
IG: "Igbo",
|
|
75
|
+
IO: "Ido",
|
|
76
|
+
II: "Sichuan Yi",
|
|
77
|
+
IU: "Inuktitut",
|
|
78
|
+
IE: "Interlingue",
|
|
79
|
+
IA: "Interlingua (International Auxiliary Language Association)",
|
|
80
|
+
ID: "Indonesian",
|
|
81
|
+
IK: "Inupiaq",
|
|
82
|
+
IS: "Icelandic",
|
|
83
|
+
IT: "Italian",
|
|
84
|
+
JV: "Javanese",
|
|
85
|
+
JA: "Japanese",
|
|
86
|
+
KL: "Kalaallisut",
|
|
87
|
+
KN: "Kannada",
|
|
88
|
+
KS: "Kashmiri",
|
|
89
|
+
KA: "Georgian",
|
|
90
|
+
KR: "Kanuri",
|
|
91
|
+
KK: "Kazakh",
|
|
92
|
+
KM: "Central Khmer",
|
|
93
|
+
KI: "Kikuyu",
|
|
94
|
+
RW: "Kinyarwanda",
|
|
95
|
+
KY: "Kirghiz",
|
|
96
|
+
KV: "Komi",
|
|
97
|
+
KG: "Kongo",
|
|
98
|
+
KO: "Korean",
|
|
99
|
+
KJ: "Kuanyama",
|
|
100
|
+
KU: "Kurdish",
|
|
101
|
+
LO: "Lao",
|
|
102
|
+
LA: "Latin",
|
|
103
|
+
LV: "Latvian",
|
|
104
|
+
LI: "Limburgan",
|
|
105
|
+
LN: "Lingala",
|
|
106
|
+
LT: "Lithuanian",
|
|
107
|
+
LB: "Luxembourgish",
|
|
108
|
+
LU: "Luba-Katanga",
|
|
109
|
+
LG: "Ganda",
|
|
110
|
+
MH: "Marshallese",
|
|
111
|
+
ML: "Malayalam",
|
|
112
|
+
MR: "Marathi",
|
|
113
|
+
MK: "Macedonian",
|
|
114
|
+
MG: "Malagasy",
|
|
115
|
+
MT: "Maltese",
|
|
116
|
+
MN: "Mongolian",
|
|
117
|
+
MI: "Maori",
|
|
118
|
+
MS: "Malay",
|
|
119
|
+
MY: "Burmese",
|
|
120
|
+
NA: "Nauru",
|
|
121
|
+
NV: "Navajo",
|
|
122
|
+
NR: "Ndebele, South",
|
|
123
|
+
ND: "Ndebele, North",
|
|
124
|
+
NG: "Ndonga",
|
|
125
|
+
NE: "Nepali",
|
|
126
|
+
NL: "Dutch",
|
|
127
|
+
NN: "Norwegian Nynorsk",
|
|
128
|
+
NB: "Bokmål, Norwegian",
|
|
129
|
+
NO: "Norwegian",
|
|
130
|
+
NY: "Chichewa",
|
|
131
|
+
OC: "Occitan (post 1500)",
|
|
132
|
+
OJ: "Ojibwa",
|
|
133
|
+
OR: "Oriya",
|
|
134
|
+
OM: "Oromo",
|
|
135
|
+
OS: "Ossetian",
|
|
136
|
+
PA: "Panjabi",
|
|
137
|
+
PI: "Pali",
|
|
138
|
+
PL: "Polish",
|
|
139
|
+
PT: "Portuguese",
|
|
140
|
+
PS: "Pushto",
|
|
141
|
+
QU: "Quechua",
|
|
142
|
+
RM: "Romansh",
|
|
143
|
+
RO: "Romanian",
|
|
144
|
+
RN: "Rundi",
|
|
145
|
+
RU: "Russian",
|
|
146
|
+
SG: "Sango",
|
|
147
|
+
SA: "Sanskrit",
|
|
148
|
+
SI: "Sinhala",
|
|
149
|
+
SK: "Slovak",
|
|
150
|
+
SL: "Slovenian",
|
|
151
|
+
SE: "Northern Sami",
|
|
152
|
+
SM: "Samoan",
|
|
153
|
+
SN: "Shona",
|
|
154
|
+
SD: "Sindhi",
|
|
155
|
+
SO: "Somali",
|
|
156
|
+
ST: "Sotho, Southern",
|
|
157
|
+
ES: "Spanish",
|
|
158
|
+
SQ: "Albanian",
|
|
159
|
+
SC: "Sardinian",
|
|
160
|
+
SR: "Serbian",
|
|
161
|
+
SS: "Swati",
|
|
162
|
+
SU: "Sundanese",
|
|
163
|
+
SW: "Swahili",
|
|
164
|
+
SV: "Swedish",
|
|
165
|
+
TY: "Tahitian",
|
|
166
|
+
TA: "Tamil",
|
|
167
|
+
TT: "Tatar",
|
|
168
|
+
TE: "Telugu",
|
|
169
|
+
TG: "Tajik",
|
|
170
|
+
TL: "Tagalog",
|
|
171
|
+
TH: "Thai",
|
|
172
|
+
TI: "Tigrinya",
|
|
173
|
+
TO: "Tonga (Tonga Islands)",
|
|
174
|
+
TN: "Tswana",
|
|
175
|
+
TS: "Tsonga",
|
|
176
|
+
TK: "Turkmen",
|
|
177
|
+
TR: "Turkish",
|
|
178
|
+
TW: "Twi",
|
|
179
|
+
UG: "Uighur",
|
|
180
|
+
UK: "Ukrainian",
|
|
181
|
+
UR: "Urdu",
|
|
182
|
+
UZ: "Uzbek",
|
|
183
|
+
VE: "Venda",
|
|
184
|
+
VI: "Vietnamese",
|
|
185
|
+
VO: "Volapük",
|
|
186
|
+
WA: "Walloon",
|
|
187
|
+
WO: "Wolof",
|
|
188
|
+
XH: "Xhosa",
|
|
189
|
+
YI: "Yiddish",
|
|
190
|
+
YO: "Yoruba",
|
|
191
|
+
ZA: "Zhuang",
|
|
192
|
+
ZH: "Chinese",
|
|
193
|
+
ZU: "Zulu"
|
|
194
|
+
}.freeze
|
|
195
|
+
|
|
196
|
+
def language_name(locale)
|
|
197
|
+
DATA[locale.upcase.to_sym] || locale
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks/data/router/pattern_router"
|
|
4
4
|
|
|
5
5
|
module I18n::Tasks
|
|
6
6
|
module Data::Router
|
|
7
7
|
# Keep the path, or infer from base locale
|
|
8
8
|
class ConservativeRouter < PatternRouter
|
|
9
9
|
def initialize(adapter, config)
|
|
10
|
-
@adapter
|
|
10
|
+
@adapter = adapter
|
|
11
11
|
@base_locale = config[:base_locale]
|
|
12
|
-
@locales
|
|
12
|
+
@locales = config[:locales]
|
|
13
13
|
super
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "i18n/tasks/key_pattern_matching"
|
|
4
|
+
require "i18n/tasks/data/tree/node"
|
|
5
5
|
|
|
6
6
|
module I18n::Tasks
|
|
7
7
|
module Data::Router
|
|
@@ -52,11 +52,11 @@ module I18n::Tasks
|
|
|
52
52
|
source_path = source_path.dup
|
|
53
53
|
|
|
54
54
|
config_read_patterns.each do |pattern|
|
|
55
|
-
regexp = Glob.new(format(pattern, locale:
|
|
55
|
+
regexp = Glob.new(format(pattern, locale: "(*)")).to_regexp
|
|
56
56
|
next unless source_path.match?(regexp)
|
|
57
57
|
|
|
58
58
|
source_path.match(regexp) do |match_data|
|
|
59
|
-
(1..match_data.size - 1).reverse_each do |capture_index|
|
|
59
|
+
(1..(match_data.size - 1)).reverse_each do |capture_index|
|
|
60
60
|
capture_begin, capture_end = match_data.offset(capture_index)
|
|
61
61
|
source_path.slice!(Range.new(capture_begin, capture_end, true))
|
|
62
62
|
source_path.insert(capture_begin, locale.to_s)
|
|
@@ -92,29 +92,29 @@ module I18n::Tasks
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
case char
|
|
95
|
-
when
|
|
96
|
-
when
|
|
97
|
-
when
|
|
98
|
-
when
|
|
99
|
-
when
|
|
95
|
+
when "**" then "(?:[^/]+/)*"
|
|
96
|
+
when "*" then ".*"
|
|
97
|
+
when "?" then "."
|
|
98
|
+
when "." then '\.'
|
|
99
|
+
when "{"
|
|
100
100
|
curlies += 1
|
|
101
|
-
|
|
102
|
-
when
|
|
101
|
+
"("
|
|
102
|
+
when "}"
|
|
103
103
|
if curlies.positive?
|
|
104
104
|
curlies -= 1
|
|
105
|
-
|
|
105
|
+
")"
|
|
106
106
|
else
|
|
107
107
|
char
|
|
108
108
|
end
|
|
109
|
-
when
|
|
109
|
+
when ","
|
|
110
110
|
if curlies.positive?
|
|
111
|
-
|
|
111
|
+
"|"
|
|
112
112
|
else
|
|
113
113
|
char
|
|
114
114
|
end
|
|
115
|
-
when
|
|
115
|
+
when "\\"
|
|
116
116
|
escaping = true
|
|
117
|
-
|
|
117
|
+
"\\"
|
|
118
118
|
else char
|
|
119
119
|
end
|
|
120
120
|
end.join
|
|
@@ -130,10 +130,10 @@ module I18n::Tasks
|
|
|
130
130
|
out = []
|
|
131
131
|
until chars.empty?
|
|
132
132
|
char = chars.shift
|
|
133
|
-
if char ==
|
|
133
|
+
if char == "*" && chars.first == "*"
|
|
134
134
|
chars.shift
|
|
135
|
-
chars.shift if chars.first ==
|
|
136
|
-
out.push(
|
|
135
|
+
chars.shift if chars.first == "/"
|
|
136
|
+
out.push("**")
|
|
137
137
|
else
|
|
138
138
|
out.push(char)
|
|
139
139
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "i18n/tasks/key_pattern_matching"
|
|
4
|
+
require "i18n/tasks/data/tree/node"
|
|
5
5
|
|
|
6
6
|
module I18n::Tasks
|
|
7
7
|
module Data::Router
|
|
@@ -37,7 +37,7 @@ module I18n::Tasks
|
|
|
37
37
|
pattern, path = routes.detect { |route| route[0] =~ key }
|
|
38
38
|
if pattern
|
|
39
39
|
key_match = $~
|
|
40
|
-
path
|
|
40
|
+
path = format(path, locale: locale)
|
|
41
41
|
path.gsub!(/\\\d+/) { |m| key_match[m[1..].to_i] }
|
|
42
42
|
(out[path] ||= Set.new) << "#{locale}.#{key}"
|
|
43
43
|
else
|
|
@@ -46,14 +46,14 @@ module I18n::Tasks
|
|
|
46
46
|
end
|
|
47
47
|
out.each do |dest, keys|
|
|
48
48
|
block.yield dest,
|
|
49
|
-
|
|
49
|
+
forest.select_keys(root: true) { |key, _| keys.include?(key) }
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
55
|
def compile_routes(routes)
|
|
56
|
-
routes.map { |x| x.is_a?(String) ? [
|
|
56
|
+
routes.map { |x| x.is_a?(String) ? ["*", x] : x }.map do |x|
|
|
57
57
|
[compile_key_pattern(x[0]), x[1]]
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "i18n/tasks/data/tree/traversal"
|
|
4
|
+
require "i18n/tasks/data/tree/siblings"
|
|
5
5
|
module I18n::Tasks::Data::Tree
|
|
6
6
|
class Node # rubocop:disable Metrics/ClassLength
|
|
7
7
|
include Enumerable
|
|
@@ -23,26 +23,26 @@ module I18n::Tasks::Data::Tree
|
|
|
23
23
|
# rubocop:enable Metrics/ParameterLists
|
|
24
24
|
|
|
25
25
|
def attributes
|
|
26
|
-
{
|
|
26
|
+
{key: @key, value: @value, data: @data.try(:clone), parent: @parent, children: @children}
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def derive(new_attr = {})
|
|
30
|
-
self.class.new(**attributes
|
|
30
|
+
self.class.new(**attributes, **new_attr)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def children=(children)
|
|
34
34
|
@children = case children
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
when Siblings
|
|
36
|
+
(children.parent == self) ? children : children.derive(parent: self)
|
|
37
|
+
when NilClass
|
|
38
|
+
nil
|
|
39
|
+
else
|
|
40
|
+
Siblings.new(
|
|
41
|
+
nodes: children,
|
|
42
|
+
parent: self,
|
|
43
|
+
warn_about_add_children_to_leaf: @warn_about_add_children_to_leaf
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
46
|
dirty!
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -90,7 +90,7 @@ module I18n::Tasks::Data::Tree
|
|
|
90
90
|
children.get(key)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
alias_method :[], :get
|
|
94
94
|
|
|
95
95
|
# append and reparent nodes
|
|
96
96
|
def append!(nodes)
|
|
@@ -138,7 +138,7 @@ module I18n::Tasks::Data::Tree
|
|
|
138
138
|
node
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
alias_method :[]=, :set
|
|
142
142
|
|
|
143
143
|
def to_nodes
|
|
144
144
|
Nodes.new([self])
|
|
@@ -154,9 +154,9 @@ module I18n::Tasks::Data::Tree
|
|
|
154
154
|
if key.nil?
|
|
155
155
|
children_hash
|
|
156
156
|
elsif leaf?
|
|
157
|
-
{
|
|
157
|
+
{key => value}
|
|
158
158
|
else
|
|
159
|
-
{
|
|
159
|
+
{key => children_hash}
|
|
160
160
|
end
|
|
161
161
|
end
|
|
162
162
|
end
|
|
@@ -166,18 +166,18 @@ module I18n::Tasks::Data::Tree
|
|
|
166
166
|
|
|
167
167
|
def inspect(level = 0)
|
|
168
168
|
label = if key.nil?
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
[
|
|
169
|
+
Rainbow("∅").faint
|
|
170
|
+
else
|
|
171
|
+
[Rainbow(key).color(1 + (level % 15)),
|
|
172
|
+
(": #{format_value_for_inspect(value)}" if leaf?),
|
|
173
|
+
(" #{data}" if data?)].compact.join
|
|
174
|
+
end
|
|
175
|
+
[" " * level, label, ("\n#{children.map { |c| c.inspect(level + 1) }.join("\n")}" if children?)].compact.join
|
|
176
176
|
end
|
|
177
177
|
|
|
178
178
|
def format_value_for_inspect(value)
|
|
179
179
|
if value.is_a?(Symbol)
|
|
180
|
-
"#{Rainbow(
|
|
180
|
+
"#{Rainbow("⮕ ").bright.yellow}#{Rainbow(value).yellow}"
|
|
181
181
|
else
|
|
182
182
|
Rainbow(value).cyan
|
|
183
183
|
end
|