class I18n::Tasks::Scanners::PatternScanner

Scan for I18n.t usages using a simple regular expression.

Constants

IGNORE_LINES
TRANSLATE_CALL_RE
VALID_KEY_RE_DYNAMIC

Attributes

translate_call_re[R]

This method only exists for backwards compatibility with monkey-patches and plugins

Public Class Methods

new(**args) click to toggle source
Calls superclass method I18n::Tasks::Scanners::FileScanner::new
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 26
def initialize(**args)
  super
  @translate_call_re = config[:translate_call].present? ? Regexp.new(config[:translate_call]) : TRANSLATE_CALL_RE
  @pattern = config[:pattern].present? ? Regexp.new(config[:pattern]) : default_pattern
  @ignore_lines_res = (config[:ignore_lines] || IGNORE_LINES).each_with_object({}) do |(ext, re), h|
    h[ext.to_s] = Regexp.new(re)
  end
end

Protected Instance Methods

closest_method(occurrence) click to toggle source
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 87
def closest_method(occurrence)
  method = File.readlines(occurrence.path, encoding: 'UTF-8')
               .first(occurrence.line_num - 1).reverse_each.find { |x| x =~ /\bdef\b/ }
  method && method.strip.sub(/^def\s*/, '').sub(/[(\s;].*$/, '')
end
default_pattern() click to toggle source
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 96
def default_pattern
  # capture only the first argument
  /
  #{translate_call_re} [( ] \s* (?# fn call begin )
  (#{first_argument_re})         (?# capture the first argument)
  /x
end
exclude_line?(line, path) click to toggle source
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 68
def exclude_line?(line, path)
  re = @ignore_lines_res[File.extname(path)[1..]]
  re && re =~ line
end
first_argument_re() click to toggle source
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 104
def first_argument_re
  literal_re
end
key_relative_to_method?(path) click to toggle source
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 83
def key_relative_to_method?(path)
  /controllers|mailers/ =~ path
end
match_to_key(match, path, location) click to toggle source

@param [MatchData] match @param [String] path @return [String] full absolute key name

# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 63
def match_to_key(match, path, location)
  absolute_key(strip_literal(match[0]), path,
               calling_method: -> { closest_method(location) if key_relative_to_method?(path) })
end
scan_file(path) click to toggle source

Extract i18n keys from file based on the pattern which must capture the key literal. @return [Array<[key, Results::Occurrence]>] each occurrence found in the file

# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 39
def scan_file(path)
  keys = []
  text = read_file(path)
  text.scan(@pattern) do |match|
    src_pos = Regexp.last_match.offset(0).first
    location = occurrence_from_position(path, text, src_pos, raw_key: strip_literal(match[0]))
    next if exclude_line?(location.line, path)

    key = match_to_key(match, path, location)
    next unless key

    key += ':' if key.end_with?('.')
    next unless valid_key?(key)

    keys << [key, location]
  end
  keys
rescue Exception => e # rubocop:disable Lint/RescueException
  raise ::I18n::Tasks::CommandError.new(e, "Error scanning #{path}: #{e.message}")
end
valid_key?(key) click to toggle source
# File lib/i18n/tasks/scanners/pattern_scanner.rb, line 75
def valid_key?(key)
  if @config[:strict]
    super(key)
  else
    key =~ VALID_KEY_RE_DYNAMIC
  end
end