i18n-tasks 0.8.7 → 0.9.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -5
  3. data/CHANGES.md +3 -3
  4. data/Gemfile +1 -1
  5. data/README.md +4 -4
  6. data/bin/i18n-tasks +0 -1
  7. data/config/locales/en.yml +103 -102
  8. data/config/locales/ru.yml +1 -1
  9. data/i18n-tasks.gemspec +1 -2
  10. data/lib/i18n/tasks.rb +0 -1
  11. data/lib/i18n/tasks/base_task.rb +0 -1
  12. data/lib/i18n/tasks/cli.rb +1 -1
  13. data/lib/i18n/tasks/command/commander.rb +0 -1
  14. data/lib/i18n/tasks/command/commands/missing.rb +3 -15
  15. data/lib/i18n/tasks/command/commands/usages.rb +5 -6
  16. data/lib/i18n/tasks/command/option_parsers/locale.rb +1 -8
  17. data/lib/i18n/tasks/command_error.rb +5 -1
  18. data/lib/i18n/tasks/commands.rb +0 -1
  19. data/lib/i18n/tasks/configuration.rb +1 -9
  20. data/lib/i18n/tasks/console_context.rb +2 -2
  21. data/lib/i18n/tasks/data.rb +0 -1
  22. data/lib/i18n/tasks/data/adapter/json_adapter.rb +0 -1
  23. data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +0 -1
  24. data/lib/i18n/tasks/data/file_formats.rb +0 -1
  25. data/lib/i18n/tasks/data/file_system.rb +0 -1
  26. data/lib/i18n/tasks/data/file_system_base.rb +0 -1
  27. data/lib/i18n/tasks/data/router/conservative_router.rb +0 -1
  28. data/lib/i18n/tasks/data/router/pattern_router.rb +0 -1
  29. data/lib/i18n/tasks/data/tree/node.rb +6 -7
  30. data/lib/i18n/tasks/data/tree/nodes.rb +0 -1
  31. data/lib/i18n/tasks/data/tree/siblings.rb +29 -10
  32. data/lib/i18n/tasks/data/tree/traversal.rb +0 -3
  33. data/lib/i18n/tasks/google_translation.rb +0 -1
  34. data/lib/i18n/tasks/ignore_keys.rb +0 -1
  35. data/lib/i18n/tasks/key_pattern_matching.rb +0 -1
  36. data/lib/i18n/tasks/logging.rb +0 -1
  37. data/lib/i18n/tasks/missing_keys.rb +0 -1
  38. data/lib/i18n/tasks/plural_keys.rb +0 -1
  39. data/lib/i18n/tasks/reports/base.rb +1 -2
  40. data/lib/i18n/tasks/reports/spreadsheet.rb +0 -1
  41. data/lib/i18n/tasks/reports/terminal.rb +41 -17
  42. data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +32 -0
  43. data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +24 -0
  44. data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +27 -0
  45. data/lib/i18n/tasks/scanners/files/file_finder.rb +61 -0
  46. data/lib/i18n/tasks/scanners/files/file_reader.rb +18 -0
  47. data/lib/i18n/tasks/scanners/key_occurrences.rb +35 -0
  48. data/lib/i18n/tasks/scanners/occurence.rb +50 -0
  49. data/lib/i18n/tasks/scanners/pattern_scanner.rb +97 -38
  50. data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +2 -3
  51. data/lib/i18n/tasks/scanners/relative_keys.rb +3 -4
  52. data/lib/i18n/tasks/scanners/scanner.rb +15 -0
  53. data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +43 -0
  54. data/lib/i18n/tasks/unused_keys.rb +4 -5
  55. data/lib/i18n/tasks/used_keys.rb +76 -23
  56. data/lib/i18n/tasks/version.rb +1 -2
  57. data/spec/conservative_router_spec.rb +0 -1
  58. data/spec/file_system_data_spec.rb +0 -1
  59. data/spec/fixtures/app/controllers/events_controller.rb +1 -2
  60. data/spec/google_translate_spec.rb +0 -1
  61. data/spec/i18n_tasks_spec.rb +4 -15
  62. data/spec/key_pattern_matching_spec.rb +0 -1
  63. data/spec/locale_tree/siblings_spec.rb +0 -1
  64. data/spec/pattern_scanner_spec.rb +34 -36
  65. data/spec/plural_keys_spec.rb +0 -1
  66. data/spec/readme_spec.rb +0 -1
  67. data/spec/relative_keys_spec.rb +15 -10
  68. data/spec/scanners/files/caching_file_finder_provider_spec.rb +18 -0
  69. data/spec/scanners/files/caching_file_finder_spec.rb +39 -0
  70. data/spec/scanners/files/caching_file_reader_spec.rb +18 -0
  71. data/spec/scanners/files/file_finder_spec.rb +52 -0
  72. data/spec/scanners/files/file_reader_spec.rb +15 -0
  73. data/spec/scanners/scanner_multiplexer_spec.rb +26 -0
  74. data/spec/spec_helper.rb +1 -1
  75. data/spec/support/capture_std.rb +0 -1
  76. data/spec/support/fixtures.rb +0 -1
  77. data/spec/support/i18n_tasks_output_matcher.rb +0 -1
  78. data/spec/support/key_pattern_matcher.rb +0 -1
  79. data/spec/support/keys_and_occurrences.rb +27 -0
  80. data/spec/support/test_codebase.rb +0 -1
  81. data/spec/support/trees.rb +1 -7
  82. data/spec/used_keys_spec.rb +15 -16
  83. data/templates/config/i18n-tasks.yml +9 -2
  84. metadata +29 -9
  85. data/lib/i18n/tasks/scanners/base_scanner.rb +0 -149
  86. data/spec/commands/missing_commands_spec.rb +0 -23
@@ -1,149 +0,0 @@
1
- # coding: utf-8
2
- require 'i18n/tasks/key_pattern_matching'
3
- require 'i18n/tasks/scanners/relative_keys'
4
-
5
- module I18n::Tasks::Scanners
6
- class BaseScanner
7
- include RelativeKeys
8
- include ::I18n::Tasks::KeyPatternMatching
9
- include ::I18n::Tasks::Logging
10
-
11
- attr_reader :config, :key_filter, :ignore_lines_res
12
-
13
- ALWAYS_EXCLUDE = %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf
14
- *.css *.sass *.scss *.less *.yml *.json)
15
-
16
- def initialize(config = {})
17
- @config = config.dup.with_indifferent_access.tap do |conf|
18
- if conf[:relative_roots].blank?
19
- conf[:relative_roots] = %w(app/controllers app/helpers app/mailers app/presenters app/views)
20
- end
21
- conf[:paths] = %w(app/) if conf[:paths].blank?
22
- conf[:include] = Array(conf[:include]) if conf[:include].present?
23
- conf[:exclude] = Array(conf[:exclude]) + ALWAYS_EXCLUDE
24
- # Regexps for lines to ignore per extension
25
- if conf[:ignore_lines] && !conf[:ignore_lines].is_a?(Hash)
26
- warn_deprecated "search.ignore_lines must be a Hash, found #{conf[:ignore_lines].class.name}"
27
- conf[:ignore_lines] = nil
28
- end
29
- conf[:ignore_lines] ||= {
30
- 'rb' => %q(^\s*#(?!\si18n-tasks-use)),
31
- 'opal' => %q(^\s*#(?!\si18n-tasks-use)),
32
- 'haml' => %q(^\s*-\s*#(?!\si18n-tasks-use)),
33
- 'slim' => %q(^\s*(?:-#|/)(?!\si18n-tasks-use)),
34
- 'coffee' => %q(^\s*#(?!\si18n-tasks-use)),
35
- 'erb' => %q(^\s*<%\s*#(?!\si18n-tasks-use)),
36
- }
37
- @ignore_lines_res = conf[:ignore_lines].inject({}) { |h, (ext, re)| h.update(ext => Regexp.new(re)) }
38
- @key_filter = nil
39
- end
40
- end
41
-
42
- def exclude_line?(line, path)
43
- re = ignore_lines_res[File.extname(path)[1..-1]]
44
- re && re =~ line
45
- end
46
-
47
- def key_filter=(value)
48
- @key_filter = value
49
- @key_filter_pattern = compile_key_pattern(value) if @key_filter
50
- end
51
-
52
- # @return [Array<{key,data:{source_occurrences:[]}}]
53
- def keys(opts = {})
54
- keys = traverse_files { |path|
55
- scan_file(path, opts)
56
- }.reduce(:+) || []
57
- keys.group_by(&:first).map { |key, key_loc|
58
- [key, data: {source_occurrences: key_loc.map { |(_k, attr)| attr[:data] }}]
59
- }
60
- end
61
-
62
- def read_file(path)
63
- result = nil
64
- File.open(path, 'rb', encoding: 'UTF-8') { |f| result = f.read }
65
- result
66
- end
67
-
68
- # @return [Array<Key>] keys found in file
69
- def scan_file(path, opts = {})
70
- raise 'Unimplemented'
71
- end
72
-
73
- # Run given block for every relevant file, according to config
74
- # @return [Array] Results of block calls
75
- def traverse_files
76
- result = []
77
- paths = config[:paths].select { |p| File.exist?(p) }
78
- if paths.empty?
79
- log_warn "search.paths #{config[:paths].inspect} do not exist"
80
- return result
81
- end
82
- Find.find(*paths) do |path|
83
- is_dir = File.directory?(path)
84
- hidden = File.basename(path).start_with?('.')
85
- not_incl = config[:include] && !path_fnmatch_any?(path, config[:include])
86
- excl = path_fnmatch_any?(path, config[:exclude])
87
- if is_dir || hidden || not_incl || excl
88
- Find.prune if is_dir && (hidden || excl)
89
- else
90
- result << yield(path)
91
- end
92
- end
93
- result
94
- end
95
-
96
- def with_key_filter(key_filter = nil)
97
- filter_was = @key_filter
98
- self.key_filter = key_filter
99
- yield
100
- ensure
101
- self.key_filter = filter_was
102
- end
103
-
104
- protected
105
-
106
- def path_fnmatch_any?(path, globs)
107
- globs.any? { |glob| File.fnmatch(glob, path) }
108
- end
109
-
110
- def src_location(path, text, src_pos, position = true)
111
- data = {src_path: path}
112
- if position
113
- line_begin = text.rindex(/^/, src_pos - 1)
114
- line_end = text.index(/.(?=\r?\n|$)/, src_pos)
115
- data.merge! pos: src_pos,
116
- line_num: text[0..src_pos].count("\n") + 1,
117
- line_pos: src_pos - line_begin + 1,
118
- line: text[line_begin..line_end]
119
- end
120
- data
121
- end
122
-
123
- # remove the leading colon and unwrap quotes from the key match
124
- def strip_literal(literal)
125
- key = literal
126
- key = key[1..-1] if ':' == key[0]
127
- key = key[1..-2] if %w(' ").include?(key[0])
128
- key
129
- end
130
-
131
- VALID_KEY_CHARS = /(?:[[:word:]]|[-.?!;À-ž])/
132
- VALID_KEY_RE_STRICT = /^#{VALID_KEY_CHARS}+$/
133
- VALID_KEY_RE = /^(#{VALID_KEY_CHARS}|[:\#{@}\[\]])+$/
134
-
135
- def valid_key?(key, strict = false)
136
- return false if @key_filter && @key_filter_pattern !~ key
137
- if strict
138
- key =~ VALID_KEY_RE_STRICT && !key.end_with?('.')
139
- else
140
- key =~ VALID_KEY_RE
141
- end
142
- end
143
-
144
- def relative_roots
145
- config[:relative_roots]
146
- end
147
-
148
- end
149
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe 'Data commands' do
4
- delegate :run_cmd, to: :TestCodebase
5
-
6
- describe '#add_missing' do
7
- describe 'adds the missing keys to base locale first, then to other locales' do
8
- around do |ex|
9
- TestCodebase.setup(
10
- 'config/i18n-tasks.yml' => {base_locale: 'en', locales: %w(es fr)}.to_yaml,
11
- 'config/locales/es.yml' => {'es' => {'a' => 'A'}}.to_yaml)
12
- TestCodebase.in_test_app_dir { ex.call }
13
- TestCodebase.teardown
14
- end
15
-
16
- it 'with -v argument' do
17
- run_cmd 'add-missing', '-vTRME'
18
- expect(YAML.load_file('config/locales/en.yml')).to eq('en' => {'a' => 'TRME'})
19
- expect(YAML.load_file('config/locales/fr.yml')).to eq('fr' => {'a' => 'TRME'})
20
- end
21
- end
22
- end
23
- end