i18n-tasks 0.3.6 → 0.3.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/CHANGES.md +5 -0
- data/README.md +13 -8
- data/bin/i18n-tasks +13 -9
- data/i18n-tasks.gemspec +2 -7
- data/lib/i18n/tasks.rb +1 -12
- data/lib/i18n/tasks/base_task.rb +6 -9
- data/lib/i18n/tasks/commands.rb +14 -15
- data/lib/i18n/tasks/commands_base.rb +2 -2
- data/lib/i18n/tasks/configuration.rb +20 -7
- data/lib/i18n/tasks/data.rb +78 -0
- data/lib/i18n/tasks/data/file_formats.rb +41 -0
- data/lib/i18n/tasks/data/file_system.rb +2 -3
- data/lib/i18n/tasks/data/file_system_base.rb +90 -0
- data/lib/i18n/tasks/data/locale_tree.rb +85 -0
- data/lib/i18n/tasks/data/router.rb +47 -0
- data/lib/i18n/tasks/key.rb +3 -0
- data/lib/i18n/tasks/key_group.rb +1 -0
- data/lib/i18n/tasks/logging.rb +4 -0
- data/lib/i18n/tasks/missing_keys.rb +18 -14
- data/lib/i18n/tasks/reports/terminal.rb +1 -1
- data/lib/i18n/tasks/scanners/base_scanner.rb +38 -36
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +2 -2
- data/lib/i18n/tasks/unused_keys.rb +11 -8
- data/lib/i18n/tasks/used_keys.rb +15 -6
- data/lib/i18n/tasks/version.rb +1 -1
- data/spec/file_system_data_spec.rb +2 -2
- data/spec/google_translate_spec.rb +1 -1
- data/spec/pattern_scanner_spec.rb +2 -2
- data/spec/relative_keys_spec.rb +3 -3
- data/spec/used_keys_spec.rb +4 -6
- metadata +39 -42
- data/lib/i18n/tasks/data/storage/file_storage.rb +0 -127
- data/lib/i18n/tasks/data_traversal.rb +0 -51
- data/lib/i18n/tasks/translation_data.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f92285f463714c33d1c83515dcd2aaf6767e4663
|
4
|
+
data.tar.gz: b82019313500a6dc1a2122b56d0bc118086071a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1cd49cb9ec3101e8ef38c75f5cace26f4dcf2afc613a89b15ea9741ec0ab420203d04039aefe79a5996cdef5736f2eb74b2503e076e2fd29cd7e05c6fda5258a
|
7
|
+
data.tar.gz: 4fec3b2eb4ad06d80429b653ede00d06522f4710ebdcdb21341d5723d2b696812086caeab0415abc8965878fd0d1d058f3346da293725b535c2a7900da36d9ec
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
i18n-tasks finds and manages missing and unused translations in your application.
|
4
4
|
|
5
|
-
The
|
5
|
+
The default approach to locale data management with gems such as [i18n][i18n-gem] is flawed.
|
6
6
|
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
7
|
-
in the resource files
|
7
|
+
in the resource files and introduce unnecessary overhead on the translators. Translation files can quickly turn to disarray.
|
8
8
|
|
9
|
-
i18n-tasks improves this by using static analysis. It scans calls such as `I18n.t('some.key')` and
|
10
|
-
|
11
|
-
|
9
|
+
i18n-tasks improves this by using static analysis. It scans calls such as `I18n.t('some.key')` and provides reports on key usage, missing, and unused keys.
|
10
|
+
It can also can pre-fill missing keys, including from Google Translate, and it can remove unused keys as well.
|
11
|
+
|
12
|
+
i18n-tasks can be used with any project using [i18n][i18n-gem] (default in Rails), or similar, even if it isn't ruby.
|
12
13
|
|
13
14
|
<img width="534" height="288" src="https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png">
|
14
15
|
|
@@ -16,9 +17,12 @@ and can also remove unused keys.
|
|
16
17
|
|
17
18
|
Add to Gemfile:
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
```ruby
|
21
|
+
gem 'i18n-tasks', '~> 0.3.7'
|
22
|
+
```
|
23
|
+
|
24
|
+
i18n-tasks does not load or execute any of the application's code but performs static-only analysic.
|
25
|
+
This means you can install the gem and run it on a project without adding it to Gemfile.
|
22
26
|
|
23
27
|
## Usage
|
24
28
|
|
@@ -295,4 +299,5 @@ This was originally developed for [Zuigo](http://zuigo.com/), a platform to orga
|
|
295
299
|
[badge-code-climate]: https://codeclimate.com/github/glebm/i18n-tasks.png
|
296
300
|
[badge-flattr]: https://api.flattr.com/button/flattr-badge-large.png
|
297
301
|
[flattr]: https://flattr.com/submit/auto?user_id=glebm&url=https%3A%2F%2Fgithub.com%2Fglebm%2Fi18n-tasks
|
302
|
+
[i18n-gem]: https://github.com/svenfuchs/i18n "svenfuchs/i18n on Github"
|
298
303
|
[screenshot-find]: https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-usages.png "i18n-tasks find output screenshot"
|
data/bin/i18n-tasks
CHANGED
@@ -24,16 +24,20 @@ end
|
|
24
24
|
if command
|
25
25
|
cmd = ::I18n::Tasks::Commands.new
|
26
26
|
meth = command[0]
|
27
|
-
opts = command[1].to_hash.reject{ |k, v| v.nil? }
|
27
|
+
opts = command[1].to_hash.reject { |k, v| v.nil? }
|
28
28
|
args = command[2]
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
begin
|
30
|
+
if opts.empty? && args.empty?
|
31
|
+
cmd.log_verbose "run #{meth.tr('_', '-')} without arguments"
|
32
|
+
cmd.send meth
|
33
|
+
else
|
34
|
+
opts = opts.merge(arguments: args) unless args.empty?
|
35
|
+
cmd.log_verbose "run #{meth.tr('_', '-')} with #{opts.map { |k, v| "#{k}=#{v}" } * ' '}"
|
36
|
+
cmd.send meth, opts
|
37
|
+
end
|
38
|
+
rescue Errno::EPIPE
|
39
|
+
# ignore Errno::EPIPE which is throw when pipe breaks, e.g.:
|
40
|
+
# i18n-tasks missing | head
|
37
41
|
end
|
38
42
|
else
|
39
43
|
STDERR.puts Term::ANSIColor.red "Command unknown: #{ARGV[0]}" if ARGV[0]
|
data/i18n-tasks.gemspec
CHANGED
@@ -12,13 +12,8 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.description = %q{
|
13
13
|
i18n-tasks finds and manages missing and unused translations in your application.
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
in the resource files, introducing unnecessary overhead on the translators. Translation files can quickly turn to disarray.
|
18
|
-
|
19
|
-
i18n-tasks improves this by using static analysis. It scans calls such as `I18n.t('some.key')` and uses this information to
|
20
|
-
provide reports on key usage, missing and unused keys, and can prefill missing keys, including from Google Translate,
|
21
|
-
and can also remove unused keys.
|
15
|
+
It scans calls such as `I18n.t('some.key')` and provides reports on key usage, missing, and unused keys.
|
16
|
+
It can also can pre-fill missing keys, including from Google Translate, and it can remove unused keys as well.
|
22
17
|
}
|
23
18
|
s.homepage = 'https://github.com/glebm/i18n-tasks'
|
24
19
|
if s.respond_to?(:metadata=)
|
data/lib/i18n/tasks.rb
CHANGED
@@ -13,17 +13,6 @@ require 'i18n/tasks/base_task'
|
|
13
13
|
|
14
14
|
module I18n
|
15
15
|
module Tasks
|
16
|
-
|
17
|
-
config/i18n-tasks.yml config/i18n-tasks.yml.erb
|
18
|
-
i18n-tasks.yml i18n-tasks.yml.erb
|
19
|
-
)
|
20
|
-
class << self
|
21
|
-
def config
|
22
|
-
file = CONFIG_FILES.detect { |f| File.exists?(f) }
|
23
|
-
file = YAML.load(Erubis::Eruby.new(File.read(file)).result) if file
|
24
|
-
HashWithIndifferentAccess.new.merge(file.presence || {})
|
25
|
-
end
|
26
|
-
include ::I18n::Tasks::Logging
|
27
|
-
end
|
16
|
+
|
28
17
|
end
|
29
18
|
end
|
data/lib/i18n/tasks/base_task.rb
CHANGED
@@ -1,33 +1,30 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
require 'i18n/tasks/configuration'
|
3
2
|
require 'i18n/tasks/key_pattern_matching'
|
4
|
-
require 'i18n/tasks/
|
3
|
+
require 'i18n/tasks/logging'
|
5
4
|
require 'i18n/tasks/plural_keys'
|
6
5
|
require 'i18n/tasks/used_keys'
|
7
|
-
require 'i18n/tasks/translation_data'
|
8
6
|
require 'i18n/tasks/ignore_keys'
|
9
7
|
require 'i18n/tasks/missing_keys'
|
10
8
|
require 'i18n/tasks/unused_keys'
|
11
9
|
require 'i18n/tasks/google_translation'
|
12
10
|
require 'i18n/tasks/fill_tasks'
|
13
|
-
require 'i18n/tasks/
|
11
|
+
require 'i18n/tasks/data'
|
12
|
+
require 'i18n/tasks/configuration'
|
14
13
|
|
15
14
|
module I18n
|
16
15
|
module Tasks
|
17
16
|
class BaseTask
|
18
|
-
include Configuration
|
19
17
|
include KeyPatternMatching
|
20
|
-
include IgnoreKeys
|
21
|
-
include DataTraversal
|
22
|
-
include RelativeKeys
|
23
18
|
include PluralKeys
|
24
19
|
include UsedKeys
|
20
|
+
include IgnoreKeys
|
25
21
|
include MissingKeys
|
26
22
|
include UnusedKeys
|
27
|
-
include TranslationData
|
28
23
|
include FillTasks
|
29
24
|
include GoogleTranslation
|
30
25
|
include Logging
|
26
|
+
include Configuration
|
27
|
+
include Data
|
31
28
|
|
32
29
|
def initialize(config = {})
|
33
30
|
self.config = config || {}
|
data/lib/i18n/tasks/commands.rb
CHANGED
@@ -14,7 +14,7 @@ module I18n::Tasks
|
|
14
14
|
on '-t', :types, 'Filter by type (types: missing_from_base, eq_base, missing_from_locale)', as: Array, delimiter: /[+:,]/, argument: true, optional: false
|
15
15
|
end
|
16
16
|
cmd :missing do |opt = {}|
|
17
|
-
|
17
|
+
parse_locales! opt
|
18
18
|
terminal_report.missing_keys i18n_task.missing_keys(opt)
|
19
19
|
end
|
20
20
|
|
@@ -30,7 +30,7 @@ module I18n::Tasks
|
|
30
30
|
end
|
31
31
|
cmd :translate_missing do |opt = {}|
|
32
32
|
opt[:from] = base_locale if opt[:from].blank? || opt[:from] == 'base'
|
33
|
-
|
33
|
+
parse_locales! opt
|
34
34
|
i18n_task.fill_missing_google_translate opt
|
35
35
|
end
|
36
36
|
|
@@ -40,9 +40,8 @@ module I18n::Tasks
|
|
40
40
|
on '-p', :placeholder, 'Value for empty keys (default: base value or key.humanize)', argument: true, optional: false
|
41
41
|
end
|
42
42
|
cmd :add_missing do |opt = {}|
|
43
|
-
|
44
|
-
opt[:value] ||= opt.delete(:placeholder)
|
45
|
-
opt[:value] ||= proc { |key, locale|
|
43
|
+
parse_locales! opt
|
44
|
+
opt[:value] ||= opt.delete(:placeholder) || proc { |key, locale|
|
46
45
|
# default to base value or key.humanize
|
47
46
|
locale == base_locale && t(locale, base_locale) || key.split('.').last.to_s.humanize
|
48
47
|
}
|
@@ -55,11 +54,7 @@ module I18n::Tasks
|
|
55
54
|
end
|
56
55
|
cmd :find do |opt = {}|
|
57
56
|
opt[:filter] ||= opt.delete(:pattern) || opt[:arguments].try(:first)
|
58
|
-
|
59
|
-
used_keys = i18n_task.scanner.with_key_filter(filter) {
|
60
|
-
i18n_task.used_keys true
|
61
|
-
}
|
62
|
-
terminal_report.used_keys used_keys
|
57
|
+
terminal_report.used_keys i18n_task.used_keys(key_filter: opt[:filter].presence, src_locations: true)
|
63
58
|
end
|
64
59
|
|
65
60
|
desc 'normalize translation data: sort and move to the right files'
|
@@ -67,7 +62,8 @@ module I18n::Tasks
|
|
67
62
|
on '-l', :locales=, 'Locales to normalize (default: all)', on_locale_opt
|
68
63
|
end
|
69
64
|
cmd :normalize do |opt = {}|
|
70
|
-
|
65
|
+
parse_locales! opt
|
66
|
+
i18n_task.normalize_store! opt[:locales]
|
71
67
|
end
|
72
68
|
|
73
69
|
desc 'remove unused keys'
|
@@ -75,14 +71,14 @@ module I18n::Tasks
|
|
75
71
|
on '-l', :locales=, 'Locales to remove unused keys from (default: all)', on_locale_opt
|
76
72
|
end
|
77
73
|
cmd :remove_unused do |opt = {}|
|
78
|
-
|
74
|
+
parse_locales!(opt)
|
79
75
|
unused_keys = i18n_task.unused_keys
|
80
76
|
if unused_keys.present?
|
81
77
|
terminal_report.unused_keys(unused_keys)
|
82
78
|
unless ENV['CONFIRM']
|
83
|
-
exit 1 unless agree(red "All these translations will be removed in #{bold locales * ', '}#{red '.'} " + yellow('Continue? (yes/no)') + ' ')
|
79
|
+
exit 1 unless agree(red "All these translations will be removed in #{bold opt[:locales] * ', '}#{red '.'} " + yellow('Continue? (yes/no)') + ' ')
|
84
80
|
end
|
85
|
-
i18n_task.remove_unused!(locales)
|
81
|
+
i18n_task.remove_unused!(opt[:locales])
|
86
82
|
$stderr.puts "Removed #{unused_keys.size} keys"
|
87
83
|
else
|
88
84
|
$stderr.puts bold green 'No unused keys to remove'
|
@@ -91,7 +87,10 @@ module I18n::Tasks
|
|
91
87
|
|
92
88
|
desc 'display i18n-tasks configuration'
|
93
89
|
cmd :config do
|
94
|
-
|
90
|
+
cfg = i18n_task.config_for_inspect.to_yaml
|
91
|
+
cfg.sub! /\A---\n/, ''
|
92
|
+
cfg.gsub! /^([^\s-].+?)$/, Term::ANSIColor.cyan(Term::ANSIColor.bold('\1'))
|
93
|
+
puts cfg
|
95
94
|
end
|
96
95
|
|
97
96
|
desc 'save missing and unused translations to an Excel file'
|
@@ -18,8 +18,8 @@ module I18n::Tasks
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
locales_opt(opt[:arguments].presence || opt[:locales]).tap do |locales|
|
21
|
+
def parse_locales!(opt)
|
22
|
+
opt[:locales] = locales_opt(opt[:arguments].presence || opt[:locales]).tap do |locales|
|
23
23
|
log_verbose "locales for the command are #{locales.inspect}"
|
24
24
|
end
|
25
25
|
end
|
@@ -5,8 +5,18 @@ module I18n::Tasks::Configuration
|
|
5
5
|
@config || (self.config = {})
|
6
6
|
end
|
7
7
|
|
8
|
+
CONFIG_FILES = %w(
|
9
|
+
config/i18n-tasks.yml config/i18n-tasks.yml.erb
|
10
|
+
i18n-tasks.yml i18n-tasks.yml.erb
|
11
|
+
)
|
12
|
+
def file_config
|
13
|
+
file = CONFIG_FILES.detect { |f| File.exists?(f) }
|
14
|
+
file = YAML.load(Erubis::Eruby.new(File.read(file)).result) if file
|
15
|
+
{}.with_indifferent_access.merge(file.presence || {})
|
16
|
+
end
|
17
|
+
|
8
18
|
def config=(conf)
|
9
|
-
@config =
|
19
|
+
@config = file_config.deep_merge(conf)
|
10
20
|
@config_sections = {}
|
11
21
|
@config
|
12
22
|
end
|
@@ -15,12 +25,10 @@ module I18n::Tasks::Configuration
|
|
15
25
|
# @return [{adapter: String, options: Hash}]
|
16
26
|
def data_config
|
17
27
|
@config_sections[:data] ||= begin
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
{adapter: adapter, options: conf.except(:adapter, :class)}
|
28
|
+
{
|
29
|
+
adapter: data.class.name,
|
30
|
+
config: data.config
|
31
|
+
}
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
@@ -65,6 +73,11 @@ module I18n::Tasks::Configuration
|
|
65
73
|
end
|
66
74
|
end
|
67
75
|
|
76
|
+
def non_base_locales(from = nil)
|
77
|
+
from ||= self.locales
|
78
|
+
Array(from) - [base_locale]
|
79
|
+
end
|
80
|
+
|
68
81
|
# @return [String] default i18n locale
|
69
82
|
def base_locale
|
70
83
|
@config_sections[:base_locale] ||= (config[:base_locale] || 'en').to_s
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'i18n/tasks/data/file_system'
|
2
|
+
|
3
|
+
module I18n::Tasks::Data
|
4
|
+
# I18n data provider
|
5
|
+
# @see I18n::Tasks::Data::FileSystem
|
6
|
+
def data
|
7
|
+
@data ||= begin
|
8
|
+
conf = (config[:data] || {}).with_indifferent_access
|
9
|
+
adapter = (conf[:adapter].presence || conf[:class].presence || :file_system).to_s
|
10
|
+
if adapter !~ /[A-Z]/
|
11
|
+
adapter = "I18n::Tasks::Data::#{adapter.camelize}"
|
12
|
+
end
|
13
|
+
adapter.constantize.new(conf.except(:adapter, :class))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def t(key, locale = base_locale)
|
18
|
+
data.t(key, locale)
|
19
|
+
end
|
20
|
+
|
21
|
+
def t_proc(locale = base_locale)
|
22
|
+
@t_proc ||= {}
|
23
|
+
@t_proc[locale] ||= proc { |key| t(key, locale) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# whether the value for key exists in locale (defaults: base_locale)
|
27
|
+
def key_value?(key, locale = base_locale)
|
28
|
+
t(key, locale).present?
|
29
|
+
end
|
30
|
+
|
31
|
+
# write to store, normalizing all data
|
32
|
+
def normalize_store!(from = nil)
|
33
|
+
from = self.locales unless from
|
34
|
+
Array(from).each do |target_locale|
|
35
|
+
# the store itself handles normalization
|
36
|
+
data[target_locale] = data[target_locale]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# if :locales option present, call update_locale_data for each locale
|
41
|
+
# otherwise, call update_locale_data for :locale option or base locale
|
42
|
+
# @option opts [Array] :locales
|
43
|
+
# @option opts [String] :locale
|
44
|
+
def update_data(opts = {})
|
45
|
+
if opts.key?(:locales)
|
46
|
+
locales = (Array(opts[:locales]).presence || self.locales).map(&:to_s)
|
47
|
+
# make sure base_locale always comes first if present
|
48
|
+
locales = [base_locale] + (locales - [base_locale]) if locales.include?(base_locale)
|
49
|
+
opts = opts.except(:locales)
|
50
|
+
locales.each { |locale| update_locale_data(locale, opts.merge(locale: locale)) }
|
51
|
+
else
|
52
|
+
update_locale_data(opts[:locale] || base_locale, opts)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param locale
|
57
|
+
# @option opts [Array|Proc] :keys keys to update, if proc call with locale
|
58
|
+
# @option opts [String|Proc] value, if proc call with each key
|
59
|
+
# @option opts [String|Proc] values, if proc call with all the keys
|
60
|
+
def update_locale_data(locale, opts = {})
|
61
|
+
keys = opts[:keys]
|
62
|
+
keys = keys.call(locale) if keys.respond_to?(:call)
|
63
|
+
return if keys.empty?
|
64
|
+
|
65
|
+
values = opts[:values]
|
66
|
+
values = values.call(keys, locale) if values.respond_to?(:call)
|
67
|
+
values ||= begin
|
68
|
+
value = opts[:value] or raise 'pass value or values'
|
69
|
+
if value.respond_to?(:call)
|
70
|
+
keys.map { |key| value.call(key, locale) }
|
71
|
+
else
|
72
|
+
[value] * keys.size
|
73
|
+
end
|
74
|
+
end
|
75
|
+
data[locale] += keys.map(&:to_s).zip(values)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module I18n
|
2
|
+
module Tasks
|
3
|
+
module Data
|
4
|
+
module FileFormats
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
delegate :adapter_for, to: :class
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def load_file(file)
|
14
|
+
adapter_for(file).parse(
|
15
|
+
::File.read(file)
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_tree(path, tree)
|
20
|
+
::File.open(path, 'w') { |f|
|
21
|
+
f.write(adapter_for(path).dump(tree.to_hash))
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
# @param pattern [String] File.fnmatch pattern
|
27
|
+
# @param adapter [responds to parse(string)->hash and dump(hash)->string]
|
28
|
+
def register_adapter(pattern, adapter)
|
29
|
+
(@fn_patterns ||= {})[pattern] = adapter
|
30
|
+
end
|
31
|
+
|
32
|
+
def adapter_for(path)
|
33
|
+
@fn_patterns.detect { |pattern, adapter|
|
34
|
+
::File.fnmatch(pattern, path)
|
35
|
+
}[1] or raise "Adapter not found for #{path}. Registered adapters: #{@fn_patterns.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require 'i18n/tasks/data/
|
1
|
+
require 'i18n/tasks/data/file_system_base'
|
2
2
|
require 'i18n/tasks/data/adapter/json_adapter'
|
3
3
|
require 'i18n/tasks/data/adapter/yaml_adapter'
|
4
4
|
|
5
5
|
module I18n::Tasks
|
6
6
|
module Data
|
7
|
-
class FileSystem
|
8
|
-
include Storage::FileStorage
|
7
|
+
class FileSystem < FileSystemBase
|
9
8
|
register_adapter '*.yml', Adapter::YamlAdapter
|
10
9
|
register_adapter '*.json', Adapter::JsonAdapter
|
11
10
|
end
|