Module: I18nJSON

Defined in:
lib/i18n-json.rb,
lib/i18n-json/cli.rb,
lib/i18n-json/cli/ui.rb,
lib/i18n-json/listen.rb,
lib/i18n-json/schema.rb,
lib/i18n-json/version.rb,
lib/i18n-json/cli/command.rb,
lib/i18n-json/cli/init_command.rb,
lib/i18n-json/cli/export_command.rb

Defined Under Namespace

Classes: CLI, Schema

Constant Summary collapse

MissingConfigError =
Class.new(StandardError)
VERSION =
"0.0.3"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.startedObject

Returns the value of attribute started.



9
10
11
# File 'lib/i18n-json/listen.rb', line 9

def started
  @started
end

Class Method Details

.call(config_file: nil, config: nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/i18n-json.rb', line 21

def self.call(config_file: nil, config: nil)
  if !config_file && !config
    raise MissingConfigError, "you must set either `config_file` or `config`"
  end

  config = Glob::SymbolizeKeys.call(config || YAML.load_file(config_file))
  Schema.validate!(config)

  config[:translations].each do |group|
    export_group(group)
  end
end

.compute_changes(paths, changed, added, removed) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/i18n-json/listen.rb', line 65

def self.compute_changes(paths, changed, added, removed)
  paths = paths.map {|path| relative_path(path) }

  {
    changed: included_on_watched_paths(paths, changed),
    added: included_on_watched_paths(paths, added),
    removed: included_on_watched_paths(paths, removed)
  }.select {|_k, v| v.any? }
end

.debug(message) ⇒ Object



38
39
40
# File 'lib/i18n-json/listen.rb', line 38

def self.debug(message)
  logger.tagged("i18n-json") { logger.debug(message) }
end

.export_group(group) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/i18n-json.rb', line 34

def self.export_group(group)
  filtered_translations = Glob.filter(translations, group[:patterns])
  output_file_path = File.expand_path(group[:file])

  if output_file_path.include?(":locale")
    filtered_translations.each_key do |locale|
      locale_file_path = output_file_path.gsub(/:locale/, locale.to_s)
      write_file(locale_file_path, locale => filtered_translations[locale])
    end
  else
    write_file(output_file_path, filtered_translations)
  end
end

.included_on_watched_paths(paths, changes) ⇒ Object



75
76
77
78
79
# File 'lib/i18n-json/listen.rb', line 75

def self.included_on_watched_paths(paths, changes)
  changes.map {|change| relative_path(change) }.select do |change|
    paths.any? {|path| change.start_with?(path) }
  end
end

.listen(config_file: Rails.root.join("config/i18n.yml"), locales_dir: Rails.root.join("config/locales")) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/i18n-json/listen.rb', line 12

def self.listen(
  config_file: Rails.root.join("config/i18n.yml"),
  locales_dir: Rails.root.join("config/locales")
)
  return unless Rails.env.development?
  return if started

  self.started = true

  relative_paths =
    [config_file, locales_dir].map {|path| relative_path(path) }

  debug("Watching #{relative_paths.inspect}")

  listener(config_file, locales_dir.to_s).start
  I18nJSON.call(config_file: config_file)
end

.listener(config_file, locales_dir) ⇒ Object

rubocop:disable Metrics/MethodLength



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/i18n-json/listen.rb', line 46

def self.listener(config_file, locales_dir) # rubocop:disable Metrics/MethodLength
  paths = [File.dirname(config_file), locales_dir]

  Listen.to(*paths) do |changed, added, removed|
    changes = compute_changes(
      [config_file, locales_dir],
      changed,
      added,
      removed
    )

    next unless changes.any?

    debug(changes.map {|key, value| "#{key}=#{value.inspect}" }.join(", "))

    I18nJSON.call(config_file: config_file)
  end
end

.loggerObject



42
43
44
# File 'lib/i18n-json/listen.rb', line 42

def self.logger
  @logger ||= ActiveSupport::TaggedLogging.new(Rails.logger)
end

.relative_path(path) ⇒ Object



30
31
32
# File 'lib/i18n-json/listen.rb', line 30

def self.relative_path(path)
  Pathname.new(path).relative_path_from(Rails.root).to_s
end

.relative_path_list(paths) ⇒ Object



34
35
36
# File 'lib/i18n-json/listen.rb', line 34

def self.relative_path_list(paths)
  paths.map {|path| relative_path(path) }
end

.translationsObject



56
57
58
59
60
61
62
63
# File 'lib/i18n-json.rb', line 56

def self.translations
  I18n.backend.instance_eval do
    has_been_initialized_before =
      respond_to?(:initialized?, true) && initialized?
    init_translations unless has_been_initialized_before
    translations
  end
end

.write_file(file_path, translations) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/i18n-json.rb', line 48

def self.write_file(file_path, translations)
  FileUtils.mkdir_p(File.dirname(file_path))

  File.open(file_path, "w") do |file|
    file << ::JSON.pretty_generate(translations)
  end
end