i18n-tasks 0.1.7 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fba31809b28d7db5c2f2febad005236e8e4b7e1b
4
- data.tar.gz: 0b3f032893745205af5368c017fe092fea521b26
3
+ metadata.gz: c8589f7427df05f3f7b0800308e70ae540e37de5
4
+ data.tar.gz: 188dde3f2e967792815f620e501c7a4e1fb21762
5
5
  SHA512:
6
- metadata.gz: ca884fd7cd3f02830003fb4fe8e13586fa162c22b328a17c39f0655e08005e03073ac193b6d57c50e3edb619b93bfc316eef873a761fb4bbdaac2d16d05c6375
7
- data.tar.gz: 3ebcfa3023b2b5c6cb83181382a51253ffca5ce2ed476d9167495da31d19358ed8db3b8bd2401b522295f64312bdad9f51f5884a1de17145474eb3a45458d538
6
+ metadata.gz: 052729b13dda5b45fe78dbbab9ea4bfb46c98d057927d8ca9b772b4c254ea9f4342940ddf60a37e10e8fb8ea62345cc73b891cc654cf28cc8cb25128d58ccec3
7
+ data.tar.gz: 63b64036166715e0b07644a022028f4a77c2b7932fa0722f1e39503b790d1a3174e21d7a1dfab1ebe8e62d5e2c3eaa0d8dc674e671fb87ac8ca0eda05f7e9d3f
data/.travis.yml CHANGED
@@ -3,12 +3,4 @@ rvm:
3
3
  - 2.0.0
4
4
  - 1.9.3
5
5
  - jruby
6
- - jruby-head
7
6
  - rbx-19mode
8
-
9
- matrix:
10
- allow_failures:
11
- - rvm: jruby
12
- - rvm: jruby-head
13
- - rvm: rbx-19mode
14
-
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## v0.1.8
2
+
3
+ * improved search: no longer uses grep, more robust detection (@natano)
4
+
1
5
  ## v0.1.7
2
6
 
3
7
  * ability to route prefill output via data.write config (@glebm)
data/README.md CHANGED
@@ -3,7 +3,9 @@
3
3
 
4
4
  Rails I18n tasks to find missing / unused translations and more. Works with slim / coffee / haml etc.
5
5
 
6
- ![i18n-missing-screenshot](https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png "rake i18n:missing output screenshot")
6
+ ![i18n-screenshot](https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png "i18n-tasks output screenshot")
7
+
8
+ ## Usage
7
9
 
8
10
  Use `rake -T i18n` to get the list of tasks with descriptions. There are 3 tasks available at the moment:
9
11
 
@@ -29,15 +31,12 @@ For more examples see [the tests](/spec/i18n_tasks_spec.rb).
29
31
  Simply add to Gemfile:
30
32
 
31
33
  ```ruby
32
- gem 'i18n-tasks', '~> 0.1.0'
34
+ gem 'i18n-tasks', '~> 0.1.7'
33
35
  ```
34
36
 
35
- `grep` is required. You likely have it already on Linux / Mac / BSD, Windows users will need to [install](http://gnuwin32.sourceforge.net/packages/grep.htm) and make sure it's available in `PATH`.
36
-
37
-
38
37
  ## Configuration
39
38
 
40
- Configuration is read from `i18n-tasks/config.yml`.
39
+ Configuration is read from `config/i18n-tasks.yml`.
41
40
 
42
41
  ### Storage
43
42
 
@@ -75,8 +74,10 @@ search:
75
74
  - '*.html.*'
76
75
  - '*.text.*'
77
76
  # explicitly exclude files (default: blank = exclude no files)
78
- exclude: '*.js'
79
- # search uses grep under the hood
77
+ exclude:
78
+ - '*.js'
79
+ # you can override the default grep pattern:
80
+ pattern: '\bt[( ]\s*(.)((?<=").+?(?=")|(?<=').+?(?=')|(?<=:)\w+\b)'
80
81
  ```
81
82
 
82
83
  ### Fine-tuning
data/i18n-tasks.gemspec CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'rails'
22
21
  spec.add_dependency 'rake'
22
+ spec.add_dependency 'activesupport'
23
23
  spec.add_dependency 'term-ansicolor'
24
24
  spec.add_development_dependency 'bundler', '~> 1.3'
25
25
  spec.add_development_dependency 'rake'
@@ -27,11 +27,7 @@ module I18n::Tasks::DataTraversal
27
27
  list.each do |key, value|
28
28
  key_segments = key.to_s.split('.')
29
29
  node = key_segments[0..-2].inject(tree) do |r, segment|
30
- if r.key?(segment)
31
- r[segment]
32
- else
33
- r[segment] = {}
34
- end
30
+ r[segment] ||= {}
35
31
  end
36
32
  node[key_segments.last] = value
37
33
  end
@@ -8,7 +8,7 @@ module I18n
8
8
  def missing(missing)
9
9
  print_title "Missing keys and translations (#{missing.length})"
10
10
  if missing.present?
11
- $stderr.puts "#{bold 'Legend:'} #{on_red '✗'} key missing, #{yellow bold '∅'} translation blank, #{blue bold '='} value equal to base locale, #{cyan 'value in base locale'}"
11
+ $stderr.puts "#{bold 'Legend:'} #{red '✗'} key missing, #{yellow bold '∅'} translation blank, #{blue bold '='} value equal to base locale, #{cyan 'value in base locale'}"
12
12
  key_col_width = missing.map { |x| x[:key] }.max_by(&:length).length + 2
13
13
  missing.each { |m| print_missing_translation m, key_col_width: key_col_width }
14
14
  else
@@ -47,14 +47,11 @@ module I18n
47
47
  def print_missing_translation(m, opts)
48
48
  locale, key, base_value, status_text = m[:locale], m[:key], m[:base_value].to_s.try(:strip), " #{STATUS_TEXTS[m[:type]]}"
49
49
 
50
- long = base_value.length > 50
51
-
52
- key = magenta "#{key}#{':' if long}".ljust(opts[:key_col_width])
53
- base_value = "\n#{indent(base_value, 13)}\n" if long
50
+ key = magenta "#{key}".ljust(opts[:key_col_width])
54
51
  s = if m[:type] == :none
55
52
  "#{red bold locale.ljust(4)} #{status_text} #{key}"
56
53
  else
57
- "#{bold locale.ljust(4)} #{status_text} #{key} #{cyan base_value}"
54
+ "#{bold locale.ljust(4)} #{status_text} #{key} #{cyan base_value.strip.gsub("\n", ' ')}"
58
55
  end
59
56
  puts s
60
57
  end
@@ -2,10 +2,9 @@ require 'i18n/tasks/base_task'
2
2
 
3
3
  module I18n
4
4
  module Tasks
5
+ # Prefill values from base locale data
5
6
  class Prefill < BaseTask
6
- # todo refactor to allow configuring output targets
7
7
  def perform
8
- # Will also rewrite en, good for ordering
9
8
  I18n.available_locales.map(&:to_s).each do |target_locale|
10
9
  data[target_locale] = data[base_locale].deep_merge(data[target_locale])
11
10
  end
@@ -1,22 +1,12 @@
1
- require 'open3'
1
+ require 'find'
2
+
2
3
  module I18n::Tasks::SourceKeys
3
4
  # find all keys in the source (relative keys are returned in absolutized)
4
5
  # @return [Array<String>]
5
6
  def find_source_keys
6
- @source_keys ||= begin
7
- if (grep_out = run_grep)
8
- grep_out.split("\n").map { |r|
9
- key = r.match(/['"](.*?)['"]/)[1]
10
- if key.start_with? '.'
11
- absolutize_key key, r.split(':')[0]
12
- else
13
- key
14
- end
15
- }.uniq.reject { |k| k !~ /^[\w.\#{}]+$/ }
16
- else
17
- []
18
- end
19
- end
7
+ @source_keys ||= traverse_files do |path|
8
+ extract_keys(path)
9
+ end.flatten.uniq
20
10
  end
21
11
 
22
12
  # whether the key is used in the source
@@ -41,8 +31,8 @@ module I18n::Tasks::SourceKeys
41
31
 
42
32
  # grep config, also from config/i18n-tasks.yml
43
33
  # @return [Hash{String => String,Hash,Array}]
44
- def grep_config
45
- @grep_config ||= begin
34
+ def search_config
35
+ @search_config ||= begin
46
36
  if config.key?(:grep)
47
37
  config[:search] ||= config.delete(:grep)
48
38
  warn_deprecated 'please rename "grep" key to "search" in config/i18n-tasks.yml'
@@ -50,30 +40,42 @@ module I18n::Tasks::SourceKeys
50
40
  search_config = (config[:search] || {}).with_indifferent_access
51
41
  search_config.tap do |conf|
52
42
  conf[:paths] = %w(app/) if conf[:paths].blank?
43
+ conf[:include] = Array(conf[:include]) if conf[:include].present?
44
+ conf[:exclude] = Array(conf[:exclude])
45
+ conf[:pattern] ||= conf[:pattern].present? ? Regexp.new(conf[:pattern]) : /\bt[( ]\s*(.)((?<=").+?(?=")|(?<=').+?(?=')|(?<=:)\w+\b)/
53
46
  end
54
47
  end
55
48
  end
56
49
 
57
- # Run grep searching for source keys and return grep output
58
- # @return [String] output of the grep command
59
- def run_grep
60
- args = ['grep', '-HoRI']
61
- [:include, :exclude].each do |opt|
62
- next unless (val = grep_config[opt]).present?
63
- args += Array(val).map { |v| "--#{opt}=#{v}" }
50
+ # Run given block for every relevant file, according to search_config
51
+ # @return [Array] Results of block calls
52
+ def traverse_files
53
+ result = []
54
+ Find.find(*search_config[:paths]) do |path|
55
+ next if File.directory?(path)
56
+ next if search_config[:include] and !search_config[:include].any? { |glob| File.fnmatch(glob, path) }
57
+ next if search_config[:exclude].any? { |glob| File.fnmatch(glob, path) }
58
+ result << yield(path)
64
59
  end
65
- args += [%q{\\bt(\\?\\s*['"]\\([^'"]*\\)['"]}, *grep_config[:paths]]
66
- args.compact!
67
- run_command *args
60
+ result
68
61
  end
69
62
 
70
-
71
- # Run command and get only stdout output
72
- # @return [String] output
73
- # @raise [RuntimeError] if grep returns with exit code other than 0
74
- def run_command(*args)
75
- o, e, s = Open3.capture3(*args)
76
- raise "#{args[0]} failed with status #{s.exitstatus} (stderr: #{e})" unless s.success?
77
- o
63
+ # Extract i18n keys from file
64
+ # @return [String] list of unique, absolut keys
65
+ def extract_keys(path)
66
+ keys = []
67
+ File.open(path, 'rb') do |f|
68
+ while (line = f.gets)
69
+ line.scan(search_config[:pattern]) do |t, key|
70
+ if key.start_with? '.'
71
+ key = absolutize_key(key, path)
72
+ elsif t == ':'
73
+ key = absolutize_key(".#{key}", path)
74
+ end
75
+ keys << key
76
+ end
77
+ end
78
+ end
79
+ keys.select { |k| k =~ /^[\w.\#{}]+$/ }
78
80
  end
79
- end
81
+ end
@@ -1,5 +1,5 @@
1
1
  module I18n
2
2
  module Tasks
3
- VERSION = '0.1.7'
3
+ VERSION = '0.1.8'
4
4
  end
5
5
  end
@@ -10,3 +10,4 @@ p = t 'ignore_eq_base_es.a'
10
10
  p = t 'numeric.a'
11
11
  p = t 'plural.a', count: 2
12
12
  p = t 'devise.a'
13
+ p = t :missing_symbol_key
@@ -5,8 +5,8 @@ describe 'rake i18n' do
5
5
  describe 'missing' do
6
6
  it 'detects missing or identical' do
7
7
  TestCodebase.capture_stderr do
8
- TestCodebase.rake_result('i18n:missing').should be_i18n_keys %w(en.used_but_missing.a es.missing_in_es.a es.blank_in_es.a es.same_in_es.a)
9
- end.should =~ /Missing keys and translations \(4\)/
8
+ TestCodebase.rake_result('i18n:missing').should be_i18n_keys %w(en.used_but_missing.a en.index.missing_symbol_key es.missing_in_es.a es.blank_in_es.a es.same_in_es.a)
9
+ end.should =~ /Missing keys and translations \(5\)/
10
10
  end
11
11
  end
12
12
 
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-20 00:00:00.000000000 Z
11
+ date: 2013-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '>='
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '>='
@@ -122,7 +122,6 @@ files:
122
122
  - LICENSE.txt
123
123
  - README.md
124
124
  - Rakefile
125
- - doc/img/i18n-missing.png
126
125
  - doc/img/i18n-tasks.png
127
126
  - i18n-tasks.gemspec
128
127
  - lib/i18n/tasks.rb
Binary file