i18n_checker 0.5.0 → 0.6.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +6 -1
  3. data/README.md +48 -1
  4. data/Rakefile +11 -1
  5. data/examples/unused/example.haml +1 -0
  6. data/examples/unused/example.rb +11 -0
  7. data/examples/unused/locales/en.yml +7 -0
  8. data/examples/unused/locales/ja.yml +7 -0
  9. data/i18n-checker.gemspec +3 -0
  10. data/lib/i18n_checker/command/check.rb +22 -0
  11. data/lib/i18n_checker/command/clean.rb +21 -0
  12. data/lib/i18n_checker/locale/file.rb +69 -7
  13. data/lib/i18n_checker/locale/files.rb +9 -0
  14. data/lib/i18n_checker/locale/text.rb +12 -0
  15. data/lib/i18n_checker/locale/texts.rb +16 -1
  16. data/lib/i18n_checker/locale.rb +8 -1
  17. data/lib/i18n_checker/{detector/locale_text_not_found.rb → not_found/detector.rb} +4 -4
  18. data/lib/i18n_checker/not_found/reporter/base.rb +17 -0
  19. data/lib/i18n_checker/not_found/reporter/default.rb +30 -0
  20. data/lib/i18n_checker/not_found/reporter.rb +2 -0
  21. data/lib/i18n_checker/{detector/detected_result.rb → not_found/result.rb} +2 -2
  22. data/lib/i18n_checker/{detector/text_result.rb → not_found/text.rb} +2 -2
  23. data/lib/i18n_checker/rake_task/{locale_check.rb → check.rb} +7 -6
  24. data/lib/i18n_checker/rake_task/clean.rb +50 -0
  25. data/lib/i18n_checker/rake_task.rb +2 -1
  26. data/lib/i18n_checker/unused/detector.rb +38 -0
  27. data/lib/i18n_checker/unused/reporter/base.rb +15 -0
  28. data/lib/i18n_checker/unused/reporter/default.rb +37 -0
  29. data/lib/i18n_checker/unused/reporter.rb +2 -0
  30. data/lib/i18n_checker/unused/result.rb +44 -0
  31. data/lib/i18n_checker/unused/text.rb +18 -0
  32. data/lib/i18n_checker/version.rb +1 -1
  33. data/lib/i18n_checker.rb +4 -6
  34. metadata +52 -11
  35. data/lib/i18n_checker/locale_text_not_found_checker.rb +0 -20
  36. data/lib/i18n_checker/reporter/default_reporter.rb +0 -28
  37. data/lib/i18n_checker/reporter/detect_result_reporter.rb +0 -15
  38. data/lib/i18n_checker/reporter.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e19d1fb49c3cf080cc470ee645bdf19bac8ca955
4
- data.tar.gz: f96f63a7b74fe6fa6a002b7520c737610ad4a2c4
3
+ metadata.gz: 5f5558d107c756fa782ad6a425a9c13189e96fc5
4
+ data.tar.gz: 321f55bfa86d773d871532ce7c4aab9105e0eb31
5
5
  SHA512:
6
- metadata.gz: a1d0b632d0049108127d9e34cfb86984edf5475ca6bab05ca623fc5689116edcb4bf69cd0b73b5fd2830cbb58dcb181520fc975f83efe9f1f2ae99b432739d18
7
- data.tar.gz: 06c158aad02010d206904d62cacfc729f0d3500ec9f33ab13a5d412be6b1ac79e745635b0de7e215a54bf30f315c5fa954d2f02dd7ec65d8ab163bb3c8b49edb
6
+ metadata.gz: f83fcce7f6caba897b78d27557090394e69802fd3034ecde81d2dbacafd992b4cbfb464a326535ac16615e9739152085de28b81003b834e685a74de5bd047d1f
7
+ data.tar.gz: df76434f18429622f5da5680e6b55a9db20d138f61d525d83b2bf6bb361b8415878095ebfde46fd55fd6dca76ccfa24305d065c46d07f209ccec6916a249800d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- i18n_checker (0.5.0)
4
+ i18n_checker (0.6.0)
5
5
  colorator (~> 1.1.0)
6
6
  haml_parser (~> 0.4)
7
7
  parser
@@ -44,6 +44,8 @@ GEM
44
44
  diff-lcs (>= 1.2.0, < 2.0)
45
45
  rspec-support (~> 3.6.0)
46
46
  rspec-support (3.6.0)
47
+ rspec-temp_dir (1.0.0)
48
+ rspec (>= 3.0)
47
49
  rubocop (0.47.1)
48
50
  parser (>= 2.3.3.1, < 3.0)
49
51
  powerpack (~> 0.1)
@@ -67,6 +69,7 @@ GEM
67
69
  thor (0.19.4)
68
70
  tins (1.13.2)
69
71
  unicode-display_width (1.1.3)
72
+ yard (0.9.9)
70
73
 
71
74
  PLATFORMS
72
75
  ruby
@@ -78,8 +81,10 @@ DEPENDENCIES
78
81
  onkcop
79
82
  rake (~> 10.0)
80
83
  rspec
84
+ rspec-temp_dir
81
85
  simplecov
82
86
  simplecov-console
87
+ yard
83
88
 
84
89
  BUNDLED WITH
85
90
  1.14.6
data/README.md CHANGED
@@ -14,12 +14,18 @@ Current version supports Ruby source code, Haml template file.
14
14
 
15
15
  ## Basic usage
16
16
 
17
+ Detected out of reference text, Delete unused translation text at once.
17
18
  Add the following tasks to your **Rakefile**.
18
19
 
19
20
  ```ruby
20
21
  require 'i18n_checker/rake_task'
21
22
 
22
- I18nChecker::RakeTask::LocaleCheck.new do |task|
23
+ I18nChecker::RakeTask::Check.new do |task|
24
+ task.source_paths = FileList['app/models/*', 'app/views/*'] # haml templates, ruby sources
25
+ task.locale_file_paths = FileList['config/locales/*'] # locale file paths
26
+ end
27
+
28
+ I18nChecker::RakeTask::Clean do |task|
23
29
  task.source_paths = FileList['app/models/*', 'app/views/*'] # haml templates, ruby sources
24
30
  task.locale_file_paths = FileList['config/locales/*'] # locale file paths
25
31
  end
@@ -29,6 +35,47 @@ After that we just execute the task.
29
35
 
30
36
  ```shell
31
37
  bundle exec rake locale_check
38
+ bundle exec rake locale_clean
39
+ ```
40
+
41
+ ## Check translation of translated text
42
+
43
+ Detect translated text references that are broken.
44
+ It is useful for detecting text that is not in the translation file of a particular language.
45
+
46
+ ```ruby
47
+ require 'i18n_checker/rake_task'
48
+
49
+ I18nChecker::RakeTask::Check.new do |task|
50
+ task.source_paths = FileList['app/models/*', 'app/views/*'] # haml templates, ruby sources
51
+ task.locale_file_paths = FileList['config/locales/*'] # locale file paths
52
+ end
53
+ ```
54
+
55
+ After that we just execute the task.
56
+
57
+ ```shell
58
+ bundle exec rake locale_check
59
+ ```
60
+
61
+ ## Delete unused translated text
62
+
63
+ Using the **locale_clean** task you can delete unused translated text from the file.
64
+ Since you can delete translated text that you do not use safely, you can reduce the maintenance cost by running it periodically.
65
+
66
+ ```ruby
67
+ require 'i18n_checker/rake_task'
68
+
69
+ I18nChecker::RakeTask::Clean do |task|
70
+ task.source_paths = FileList['app/models/*', 'app/views/*'] # haml templates, ruby sources
71
+ task.locale_file_paths = FileList['config/locales/*'] # locale file paths
72
+ end
73
+ ```
74
+
75
+ After that we just execute the task.
76
+
77
+ ```shell
78
+ bundle exec rake locale_clean
32
79
  ```
33
80
 
34
81
  ## Run the test
data/Rakefile CHANGED
@@ -1,12 +1,22 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
+ require 'yard'
3
4
  require 'i18n_checker/rake_task'
4
5
 
5
6
  RSpec::Core::RakeTask.new(:spec)
6
7
 
7
- I18nChecker::RakeTask::LocaleCheck.new do |task|
8
+ I18nChecker::RakeTask::Check.new do |task|
8
9
  task.source_paths = FileList['spec/fixtures/haml/*', 'spec/fixtures/ruby/*']
9
10
  task.locale_file_paths = FileList['spec/fixtures/locales/**']
10
11
  end
11
12
 
13
+ I18nChecker::RakeTask::Clean.new do |task|
14
+ task.source_paths = FileList['examples/unused/**']
15
+ task.locale_file_paths = FileList['examples/unused/locales/**']
16
+ end
17
+
18
+ YARD::Rake::YardocTask.new do |t|
19
+ t.files = ['lib/**/*.rb']
20
+ end
21
+
12
22
  task :default => :spec
@@ -0,0 +1 @@
1
+ %p= t('nested.foo')
@@ -0,0 +1,11 @@
1
+ module Example
2
+ class Example
3
+ def foo
4
+ t('nested.foo')
5
+ end
6
+
7
+ def bar
8
+ I18n.t('nested.bar')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ en:
2
+ nested:
3
+ foo: foo
4
+ bar: bar
5
+ nested2:
6
+ foo: foo
7
+ bar: bar
@@ -0,0 +1,7 @@
1
+ ja:
2
+ nested:
3
+ foo: foo
4
+ bar: bar
5
+ nested2:
6
+ foo: foo
7
+ bar: bar
data/i18n-checker.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
21
  spec.require_paths = ['lib']
22
+ spec.metadata['yard.run'] = 'yri'
22
23
  spec.add_dependency 'haml_parser', '~> 0.4'
23
24
  spec.add_dependency 'colorator', '~> 1.1.0'
24
25
  spec.add_dependency 'parser'
@@ -29,4 +30,6 @@ Gem::Specification.new do |spec|
29
30
  spec.add_development_dependency 'simplecov-console'
30
31
  spec.add_development_dependency 'coveralls'
31
32
  spec.add_development_dependency 'onkcop'
33
+ spec.add_development_dependency 'rspec-temp_dir'
34
+ spec.add_development_dependency 'yard'
32
35
  end
@@ -0,0 +1,22 @@
1
+ require 'i18n_checker/not_found/detector'
2
+ require 'i18n_checker/not_found/text'
3
+ require 'i18n_checker/not_found/result'
4
+
5
+ module I18nChecker
6
+ module Command
7
+ class Check
8
+ def initialize(locale_file_paths: [], source_paths: [], reporter:)
9
+ @reporter = reporter
10
+ @locale_texts = I18nChecker::Locale.texts_of(source_paths)
11
+ @locale_files = I18nChecker::Locale.load_of(locale_file_paths)
12
+ end
13
+
14
+ def check
15
+ not_found_detector = I18nChecker::NotFound::Detector.new(@locale_files)
16
+ not_found_result = @locale_texts.detect(not_found_detector)
17
+ @reporter.report not_found_result
18
+ yield not_found_result if block_given?
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require 'i18n_checker/unused/detector'
2
+
3
+ module I18nChecker
4
+ module Command
5
+ class Clean
6
+ def initialize(locale_file_paths: [], source_paths: [], reporter:)
7
+ @reporter = reporter
8
+ @locale_texts = I18nChecker::Locale.texts_of(source_paths)
9
+ @locale_files = I18nChecker::Locale.load_of(locale_file_paths)
10
+ @unused_detector = I18nChecker::Unused::Detector.new(@locale_files)
11
+ end
12
+
13
+ def run
14
+ unused_result = @locale_texts.detect(@unused_detector)
15
+ @reporter.report unused_result
16
+ unused_result.apply(@locale_files)
17
+ yield unused_result if block_given?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,29 +2,71 @@ require 'yaml'
2
2
 
3
3
  module I18nChecker
4
4
  module Locale
5
+ # Translation file for each language
6
+ #
7
+ # @attr_reader [String] file_name Translation file path
8
+ # @attr_reader [String] lang language
9
+ # @attr_reader [Hash<String,String>] locale_texts translation texts
5
10
  class File
6
- attr_reader :lang, :locale_texts
11
+ attr_reader :file_name, :lang, :locale_texts
7
12
 
8
13
  class << self
9
- def load_yaml(s)
10
- new(YAML.load(s))
11
- end
12
-
14
+ # Read translation file
15
+ #
16
+ # @param yaml_file [String] Translation file path
17
+ # @return [I18nChecker::Locale::File] Translation file
13
18
  def load_yaml_file(yaml_file)
14
- load_yaml(::File.open(yaml_file, &:read))
19
+ new(yaml_file, YAML.load(::File.open(yaml_file, &:read)))
15
20
  end
16
21
  end
17
22
 
18
- def initialize(locale_texts = {})
23
+ # Create a translation file
24
+ #
25
+ # @param yaml_file [String] Translation file path
26
+ # @param locale_texts [Hash<String,String>] translation text
27
+ def initialize(yaml_file, locale_texts = {})
19
28
  lang = locale_texts.keys.first
20
29
  @lang = lang.to_sym
21
30
  @locale_texts = compact_of(locale_texts[lang] || {})
31
+ @file_name = yaml_file
22
32
  end
23
33
 
34
+ # Check for translated text
35
+ #
36
+ # @param locale_text [Stirng] Translation text key
37
+ # @return [Boolean] Returns true if there is translated text
24
38
  def include?(locale_text)
25
39
  @locale_texts.key?(locale_text.text)
26
40
  end
27
41
 
42
+ # Deletes the specified translation text
43
+ #
44
+ # @param locale_text [Array<Stirng>] Translation text key
45
+ # @return [I18nChecker::Locale::File] New translation file
46
+ def remove_texts(locale_texts)
47
+ registry = locale_texts.map { |locale_text| [locale_text, true] }.to_h
48
+
49
+ current_locale_texts = @locale_texts.dup
50
+ current_locale_texts.delete_if { |locale_text| registry.key?(locale_text) }
51
+
52
+ remain_texts = {}
53
+ remain_texts[@lang] = current_locale_texts
54
+
55
+ self.class.new(file_name, remain_texts)
56
+ end
57
+
58
+ # Save the translation file
59
+ #
60
+ # @return [I18nChecker::Locale::File] translation file
61
+ def save
62
+ locale = {}
63
+ locale[@lang.to_s] = tree_of(locale_texts)
64
+ yaml_file = ::File.open(file_name, 'w')
65
+ yaml_file.write(YAML.dump(locale))
66
+ yaml_file.close
67
+ self
68
+ end
69
+
28
70
  private
29
71
 
30
72
  def compact_of(values = {}, path = KeyPath.new)
@@ -40,6 +82,26 @@ module I18nChecker
40
82
  end
41
83
  result
42
84
  end
85
+
86
+ def tree_of(values = [])
87
+ result = {}
88
+ values.each do |path, value|
89
+ dest = nil
90
+ paths = path.split('.')
91
+ last_key = paths.last
92
+ paths.pop
93
+ paths.each do |p|
94
+ if result.key?(p)
95
+ dest = result[p]
96
+ else
97
+ result[p] = {}
98
+ dest = result[p]
99
+ end
100
+ end
101
+ dest[last_key] = value
102
+ end
103
+ result
104
+ end
43
105
  end
44
106
  end
45
107
  end
@@ -9,10 +9,19 @@ module I18nChecker
9
9
 
10
10
  def_delegators :locale_files, :size, :each
11
11
 
12
+ # Translation files for each language
13
+ #
14
+ # @param locale_files [Array<I18nChecker::Locale::File>]
12
15
  def initialize(locale_files = [])
13
16
  @locale_files = locale_files
14
17
  end
15
18
 
19
+ # Execute the specified block and delete the translation file
20
+ #
21
+ # @yield [file] Block to be evaluated
22
+ # @yieldparam [I18nChecker::Locale::File]
23
+ # @yieldreturn [Boolean]
24
+ # @return [I18nChecker::Locale::Files]
16
25
  def delete_if(&block)
17
26
  locale_files.delete_if(&block)
18
27
  self
@@ -1,8 +1,20 @@
1
1
  module I18nChecker
2
2
  module Locale
3
+ # Translation text referenced from the file
4
+ #
5
+ # @attr_reader [String] file File referring to translated text
6
+ # @attr_reader [String] text Translation text key
7
+ # @attr_reader [Fixnum] line Line number of file
8
+ # @attr_reader [Fixnum] column Column number of file
3
9
  class Text
4
10
  attr_reader :file, :text, :line, :column
5
11
 
12
+ # Create translated text
13
+ #
14
+ # @param file [String] File referring to translated text
15
+ # @param text [String] Translation text key
16
+ # @param line [Fixnum] Line number of file
17
+ # @param column [Fixnum] Column number of file
6
18
  def initialize(file:, text:, line:, column:)
7
19
  @file = file
8
20
  @text = text
@@ -3,27 +3,42 @@ require 'i18n_checker/locale/text'
3
3
 
4
4
  module I18nChecker
5
5
  module Locale
6
+ # List of translated text
7
+ #
6
8
  class Texts
7
9
  extend Forwardable
8
10
 
9
11
  include Enumerable
10
12
 
11
- def_delegators :texts, :size, :each
13
+ def_delegators :texts, :size, :each, :select
12
14
 
15
+ # Create list of translated text
16
+ #
17
+ # @param texts [Array<I18nChecker::Locale::Text>] List of translated text
13
18
  def initialize(texts = [])
14
19
  @texts = texts
15
20
  end
16
21
 
22
+ # Combine lists of translated texts
23
+ #
24
+ # @param texts [Enumerable<I18nChecker::Locale::Text>] List of translated text
25
+ # @return [I18nChecker::Locale::Texts<I18nChecker::Locale::Text>] Returns the combined receiver itself
17
26
  def concat(texts)
18
27
  @texts.concat(texts.to_a)
19
28
  self
20
29
  end
21
30
 
31
+ # Delete translated text duplicates
32
+ #
33
+ # @return [I18nChecker::Locale::Texts<I18nChecker::Locale::Text>] Returns the combined receiver itself
22
34
  def uniq!
23
35
  @texts.uniq!
24
36
  self
25
37
  end
26
38
 
39
+ # Compare lists of translated texts
40
+ #
41
+ # @return [Boolean]
27
42
  def ==(other)
28
43
  @texts == other.to_a
29
44
  end
@@ -6,11 +6,18 @@ require 'i18n_checker/locale/collector'
6
6
  module I18nChecker
7
7
  module Locale
8
8
  module Methods
9
+ # Read specified translation file
10
+ #
11
+ # @return [I18nChecker::Locale::Files]
9
12
  def load_of(locale_files)
10
- loaded_locale_files = locale_files.map { |locale_file| I18nChecker::Locale::File.load_yaml_file(locale_file) }
13
+ files = locale_files.delete_if { |resource| ::File.directory?(resource) }.to_a
14
+ loaded_locale_files = files.map { |locale_file| I18nChecker::Locale::File.load_yaml_file(locale_file) }
11
15
  Files.new(loaded_locale_files)
12
16
  end
13
17
 
18
+ # Collect translation text from specified file list
19
+ #
20
+ # @return [I18nChecker::Locale::Texts]
14
21
  def texts_of(resources)
15
22
  caches = I18nChecker::Cache::Files.new
16
23
 
@@ -1,13 +1,13 @@
1
1
  module I18nChecker
2
- module Detector
3
- class LocaleTextNotFound
2
+ module NotFound
3
+ class Detector
4
4
  def initialize(locale_files)
5
5
  @locale_files = locale_files
6
6
  end
7
7
 
8
8
  def detect(locale_texts)
9
9
  results = locale_texts.map { |local_text| detect_not_found(local_text) }
10
- DetectedResult.new(results.compact.flatten)
10
+ Result.new(results.compact.flatten)
11
11
  end
12
12
 
13
13
  private
@@ -16,7 +16,7 @@ module I18nChecker
16
16
  locale_files = @locale_files.dup
17
17
  locale_files.delete_if { |locale_file| locale_file.include?(locale_text) }
18
18
  locale_files.map do |locale_file|
19
- TextResult.new(
19
+ Text.new(
20
20
  locale_text: locale_text,
21
21
  locale_file: locale_file
22
22
  )
@@ -0,0 +1,17 @@
1
+ require 'logger'
2
+
3
+ module I18nChecker
4
+ module NotFound
5
+ module Reporter
6
+ class Base
7
+ def initialize(logger: Logger.new(STDOUT))
8
+ @logger = logger
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :logger
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ require 'colorator'
2
+
3
+ module I18nChecker
4
+ module NotFound
5
+ module Reporter
6
+ class Default < Base
7
+ CHECK_COMPLETED = 'Translation text checking is complete.'.freeze
8
+
9
+ def report(result)
10
+ return passed if result.empty?
11
+ failed(result)
12
+ end
13
+
14
+ def passed
15
+ logger.info CHECK_COMPLETED.green
16
+ logger.info 'There was no translated text that can not be referenced'.green
17
+ end
18
+
19
+ def failed(result)
20
+ logger.info CHECK_COMPLETED.red
21
+ logger.info "There are settings where translated text can not be found\n".red
22
+ result.locale_texts.each do |locale_text|
23
+ logger.info locale_text.file.cyan.to_s
24
+ logger.info " line:#{locale_text.line}, column:#{locale_text.column} - #{locale_text.lang}.#{locale_text.text}"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,2 @@
1
+ require 'i18n_checker/not_found/reporter/base'
2
+ require 'i18n_checker/not_found/reporter/default'
@@ -1,6 +1,6 @@
1
1
  module I18nChecker
2
- module Detector
3
- class DetectedResult
2
+ module NotFound
3
+ class Result
4
4
  attr_reader :locale_texts
5
5
 
6
6
  def initialize(locale_texts = [])
@@ -1,8 +1,8 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module I18nChecker
4
- module Detector
5
- class TextResult
4
+ module NotFound
5
+ class Text
6
6
  extend Forwardable
7
7
 
8
8
  def_delegators :locale_file, :lang
@@ -2,12 +2,13 @@ require 'rake'
2
2
  require 'rake/tasklib'
3
3
  require 'i18n_checker/cache'
4
4
  require 'i18n_checker/locale'
5
- require 'i18n_checker/reporter'
6
- require 'i18n_checker/locale_text_not_found_checker'
5
+ require 'i18n_checker/not_found/reporter/base'
6
+ require 'i18n_checker/not_found/reporter/default'
7
+ require 'i18n_checker/command/check'
7
8
 
8
9
  module I18nChecker
9
10
  module RakeTask
10
- class LocaleCheck < ::Rake::TaskLib
11
+ class Check < ::Rake::TaskLib
11
12
  attr_accessor :name
12
13
  attr_accessor :reporter
13
14
  attr_accessor :source_paths
@@ -22,7 +23,7 @@ module I18nChecker
22
23
  @logger.formatter = proc { |_severity, _datetime, _progname, message|
23
24
  "#{message}\n"
24
25
  }
25
- @reporter = I18nChecker::Reporter::DefaultReporter.new(logger: logger)
26
+ @reporter = I18nChecker::NotFound::Reporter::Default.new(logger: logger)
26
27
  yield self if block_given?
27
28
  define
28
29
  end
@@ -35,12 +36,12 @@ module I18nChecker
35
36
  end
36
37
 
37
38
  def run_task
38
- checker = I18nChecker::LocaleTextNotFoundChecker.new(
39
+ commmand = I18nChecker::Command::Check.new(
39
40
  reporter: reporter,
40
41
  source_paths: source_paths,
41
42
  locale_file_paths: locale_file_paths
42
43
  )
43
- checker.check do |result|
44
+ commmand.check do |result|
44
45
  exit 1 unless result.empty?
45
46
  end
46
47
  end
@@ -0,0 +1,50 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+ require 'i18n_checker/cache'
4
+ require 'i18n_checker/locale'
5
+ require 'i18n_checker/unused/detector'
6
+ require 'i18n_checker/unused/reporter/default'
7
+ require 'i18n_checker/command/clean'
8
+
9
+ module I18nChecker
10
+ module RakeTask
11
+ class Clean < ::Rake::TaskLib
12
+ attr_accessor :name
13
+ attr_accessor :reporter
14
+ attr_accessor :source_paths
15
+ attr_accessor :locale_file_paths
16
+ attr_accessor :logger
17
+
18
+ def initialize(name = :locale_clean)
19
+ @name = name
20
+ @source_paths = FileList['app/views/*', 'app/controllers/*', 'app/jobs/*', 'app/models/*', 'app/helpers/*']
21
+ @locale_file_paths = FileList['config/locales/*']
22
+ @logger = Logger.new(STDOUT)
23
+ @logger.formatter = proc { |_severity, _datetime, _progname, message|
24
+ "#{message}\n"
25
+ }
26
+ @reporter = I18nChecker::Unused::Reporter::Default.new(logger: logger)
27
+ yield self if block_given?
28
+ define
29
+ end
30
+
31
+ private
32
+
33
+ def define
34
+ desc 'Delete unused translation text.'
35
+ task(name) { run_task }
36
+ end
37
+
38
+ def run_task
39
+ command = I18nChecker::Command::Clean.new(
40
+ reporter: reporter,
41
+ source_paths: source_paths,
42
+ locale_file_paths: locale_file_paths
43
+ )
44
+ command.run do |result|
45
+ exit 1 unless result.empty?
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1 +1,2 @@
1
- require 'i18n_checker/rake_task/locale_check'
1
+ require 'i18n_checker/rake_task/check'
2
+ require 'i18n_checker/rake_task/clean'
@@ -0,0 +1,38 @@
1
+ require 'i18n_checker/unused/text'
2
+ require 'i18n_checker/unused/result'
3
+
4
+ module I18nChecker
5
+ module Unused
6
+ class Detector
7
+ def initialize(locale_files)
8
+ @locale_files = locale_files
9
+ end
10
+
11
+ def detect(locale_texts)
12
+ unused_texts = cleaned_locale_files(locale_texts).map do |locale_file|
13
+ locale_file.locale_texts.map do |key, _v|
14
+ I18nChecker::Unused::Text.new(
15
+ text: key,
16
+ file: locale_file
17
+ )
18
+ end
19
+ end
20
+ I18nChecker::Unused::Result.new(unused_texts.compact.flatten)
21
+ end
22
+
23
+ private
24
+
25
+ def cleaned_locale_files(locale_texts)
26
+ remove_locale_texts = used_locale_texts(locale_texts)
27
+ @locale_files.map { |locale_file| locale_file.remove_texts(remove_locale_texts) }
28
+ end
29
+
30
+ def used_locale_texts(locale_texts)
31
+ used_locale_texts = locale_texts.dup.select do |locale_text|
32
+ @locale_files.any? { |locale_file| locale_file.include?(locale_text) }
33
+ end
34
+ used_locale_texts.map(&:text)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ module I18nChecker
2
+ module Unused
3
+ module Reporter
4
+ class Base
5
+ def initialize(logger: Logger.new(STDOUT))
6
+ @logger = logger
7
+ end
8
+
9
+ private
10
+
11
+ attr_reader :logger
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ require 'i18n_checker/unused/result'
2
+ require 'i18n_checker/unused/result'
3
+ require 'i18n_checker/unused/detector'
4
+ require 'i18n_checker/unused/reporter/base'
5
+
6
+ module I18nChecker
7
+ module Unused
8
+ module Reporter
9
+ class Default < Base
10
+ CHECK_COMPLETED = 'Checking of unused translated text is finished.'.freeze
11
+
12
+ #
13
+ # @param unused_result [I18nChecker::Unused::Result]
14
+ def report(unused_result)
15
+ return passed if unused_result.empty?
16
+ failed(unused_result)
17
+ end
18
+
19
+ private
20
+
21
+ def passed
22
+ logger.info CHECK_COMPLETED.green
23
+ logger.info 'Unused translation text was not found'.green
24
+ end
25
+
26
+ def failed(unused_result)
27
+ logger.info CHECK_COMPLETED.red
28
+ logger.info "An unused translation text was found.\n".red
29
+ unused_result.locale_files.each do |file_name, unused_texts|
30
+ logger.info file_name.cyan.to_s
31
+ unused_texts.map { |text| logger.info " #{text.text}" }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,2 @@
1
+ require 'i18n_checker/unused/reporter/base'
2
+ require 'i18n_checker/unused/reporter/default'
@@ -0,0 +1,44 @@
1
+ module I18nChecker
2
+ module Unused
3
+ # Detection result of unused translated text
4
+ #
5
+ # @attr_reader [Array<I18nChecker::Unused::Text>] unused_texts
6
+ # @attr_reader [Hash<String, Array<I18nChecker::Unused::File>>] locale_files
7
+ class Result
8
+ attr_reader :unused_texts, :locale_files
9
+
10
+ #
11
+ #
12
+ # @param unused_texts [Array<I18nChecker::Unused::Text>]
13
+ def initialize(unused_texts = [])
14
+ @unused_texts = unused_texts
15
+ @locale_files = unused_texts.group_by(&:file_name)
16
+ end
17
+
18
+ #
19
+ #
20
+ # @return [Boolean]
21
+ def empty?
22
+ unused_texts.empty?
23
+ end
24
+
25
+ # Apply the detected unused translated text to the current translation file.
26
+ # Unused text has been deleted from the translation file.
27
+ #
28
+ # @param target_locale_files [Array<I18nChecker::Locale::File>]
29
+ # @return [Array<I18nChecker::Locale::File>]
30
+ def apply(target_locale_files)
31
+ locale_files = target_locale_files.
32
+ group_by(&:file_name).
33
+ map { |k, v| [k, v.first] }
34
+
35
+ cleanup_locale_files = locale_files.map do |file_name, locale_file|
36
+ return locale_file unless @locale_files.key?(file_name)
37
+ unused_texts = @locale_files[file_name]
38
+ locale_file.remove_texts(unused_texts.map(&:text))
39
+ end
40
+ cleanup_locale_files.each(&:save)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ require 'forwardable'
2
+
3
+ module I18nChecker
4
+ module Unused
5
+ class Text
6
+ extend Forwardable
7
+
8
+ attr_reader :file, :text
9
+
10
+ def_delegators :file, :lang, :file_name
11
+
12
+ def initialize(file:, text:)
13
+ @file = file
14
+ @text = text
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module I18nChecker
2
- VERSION = '0.5.0'.freeze
2
+ VERSION = '0.6.0'.freeze
3
3
  end
data/lib/i18n_checker.rb CHANGED
@@ -11,12 +11,10 @@ require 'i18n_checker/locale/texts'
11
11
  require 'i18n_checker/locale/key_path'
12
12
  require 'i18n_checker/locale/file'
13
13
  require 'i18n_checker/locale/files'
14
- require 'i18n_checker/detector/locale_text_not_found'
15
- require 'i18n_checker/detector/text_result'
16
- require 'i18n_checker/detector/detected_result'
17
- require 'i18n_checker/reporter/detect_result_reporter'
18
- require 'i18n_checker/reporter/default_reporter'
19
- require 'i18n_checker/locale_text_not_found_checker'
14
+ require 'i18n_checker/unused/detector'
15
+ require 'i18n_checker/unused/reporter'
16
+ require 'i18n_checker/not_found/detector'
17
+ require 'i18n_checker/not_found/reporter'
20
18
 
21
19
  module I18nChecker
22
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n_checker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - holyshared
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-30 00:00:00.000000000 Z
11
+ date: 2017-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: haml_parser
@@ -150,6 +150,34 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec-temp_dir
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: yard
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
153
181
  description: Verification of translation of Ruby source and Haml template
154
182
  email:
155
183
  - holy.shared.design@gmail.com
@@ -168,13 +196,16 @@ files:
168
196
  - LICENSE
169
197
  - README.md
170
198
  - Rakefile
199
+ - examples/unused/example.haml
200
+ - examples/unused/example.rb
201
+ - examples/unused/locales/en.yml
202
+ - examples/unused/locales/ja.yml
171
203
  - i18n-checker.gemspec
172
204
  - lib/i18n_checker.rb
173
205
  - lib/i18n_checker/cache.rb
174
206
  - lib/i18n_checker/collectible.rb
175
- - lib/i18n_checker/detector/detected_result.rb
176
- - lib/i18n_checker/detector/locale_text_not_found.rb
177
- - lib/i18n_checker/detector/text_result.rb
207
+ - lib/i18n_checker/command/check.rb
208
+ - lib/i18n_checker/command/clean.rb
178
209
  - lib/i18n_checker/locale.rb
179
210
  - lib/i18n_checker/locale/collector.rb
180
211
  - lib/i18n_checker/locale/collector/haml.rb
@@ -185,18 +216,28 @@ files:
185
216
  - lib/i18n_checker/locale/text.rb
186
217
  - lib/i18n_checker/locale/text_processor.rb
187
218
  - lib/i18n_checker/locale/texts.rb
188
- - lib/i18n_checker/locale_text_not_found_checker.rb
219
+ - lib/i18n_checker/not_found/detector.rb
220
+ - lib/i18n_checker/not_found/reporter.rb
221
+ - lib/i18n_checker/not_found/reporter/base.rb
222
+ - lib/i18n_checker/not_found/reporter/default.rb
223
+ - lib/i18n_checker/not_found/result.rb
224
+ - lib/i18n_checker/not_found/text.rb
189
225
  - lib/i18n_checker/rake_task.rb
190
- - lib/i18n_checker/rake_task/locale_check.rb
191
- - lib/i18n_checker/reporter.rb
192
- - lib/i18n_checker/reporter/default_reporter.rb
193
- - lib/i18n_checker/reporter/detect_result_reporter.rb
226
+ - lib/i18n_checker/rake_task/check.rb
227
+ - lib/i18n_checker/rake_task/clean.rb
228
+ - lib/i18n_checker/unused/detector.rb
229
+ - lib/i18n_checker/unused/reporter.rb
230
+ - lib/i18n_checker/unused/reporter/base.rb
231
+ - lib/i18n_checker/unused/reporter/default.rb
232
+ - lib/i18n_checker/unused/result.rb
233
+ - lib/i18n_checker/unused/text.rb
194
234
  - lib/i18n_checker/version.rb
195
235
  - screenshot.png
196
236
  homepage: https://github.com/holyshared/i18n-checker
197
237
  licenses:
198
238
  - MIT
199
- metadata: {}
239
+ metadata:
240
+ yard.run: yri
200
241
  post_install_message:
201
242
  rdoc_options: []
202
243
  require_paths:
@@ -1,20 +0,0 @@
1
- require 'i18n_checker/detector/locale_text_not_found'
2
- require 'i18n_checker/detector/text_result'
3
- require 'i18n_checker/detector/detected_result'
4
-
5
- module I18nChecker
6
- class LocaleTextNotFoundChecker
7
- def initialize(locale_file_paths: [], source_paths: [], reporter:)
8
- @reporter = reporter
9
- @locale_texts = I18nChecker::Locale.texts_of(source_paths)
10
- @locale_files = I18nChecker::Locale.load_of(locale_file_paths)
11
- end
12
-
13
- def check
14
- not_found_detector = I18nChecker::Detector::LocaleTextNotFound.new(@locale_files)
15
- not_found_result = @locale_texts.detect(not_found_detector)
16
- @reporter.report not_found_result
17
- yield not_found_result if block_given?
18
- end
19
- end
20
- end
@@ -1,28 +0,0 @@
1
- require 'colorator'
2
-
3
- module I18nChecker
4
- module Reporter
5
- class DefaultReporter < DetectResultReporter
6
- CHECK_COMPLETED = 'Translation text checking is complete.'.freeze
7
-
8
- def report(result)
9
- return passed if result.empty?
10
- failed(result)
11
- end
12
-
13
- def passed
14
- logger.info CHECK_COMPLETED.green
15
- logger.info 'There was no translated text that can not be referenced'.green
16
- end
17
-
18
- def failed(result)
19
- logger.info CHECK_COMPLETED.red
20
- logger.info "There are settings where translated text can not be found\n".red
21
- result.locale_texts.each do |locale_text|
22
- logger.info locale_text.file.cyan.to_s
23
- logger.info " line:#{locale_text.line}, column:#{locale_text.column} - #{locale_text.lang}.#{locale_text.text}"
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,15 +0,0 @@
1
- require 'logger'
2
-
3
- module I18nChecker
4
- module Reporter
5
- class DetectResultReporter
6
- def initialize(logger: Logger.new(STDOUT))
7
- @logger = logger
8
- end
9
-
10
- private
11
-
12
- attr_reader :logger
13
- end
14
- end
15
- end
@@ -1,7 +0,0 @@
1
- require 'i18n_checker/reporter/detect_result_reporter'
2
- require 'i18n_checker/reporter/default_reporter'
3
-
4
- module I18nChecker
5
- module Reporter
6
- end
7
- end