i18n-tasks 0.3.3 → 0.3.4
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 +4 -4
- data/CHANGES.md +4 -0
- data/README.md +18 -10
- data/bin/i18n-tasks +10 -4
- data/i18n-tasks.gemspec +8 -3
- data/lib/i18n/tasks/commands.rb +11 -10
- data/lib/i18n/tasks/commands_base.rb +8 -0
- data/lib/i18n/tasks/configuration.rb +6 -3
- data/lib/i18n/tasks/missing_keys.rb +7 -3
- data/lib/i18n/tasks/version.rb +1 -1
- data/spec/i18n_tasks_spec.rb +11 -6
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68c94e2f16413ec396e24e366c2d22107423e5e4
|
4
|
+
data.tar.gz: 16680455229c39bbfd63b57e6ebeac977041ff98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5410cf4b6b5c92058a751fbde9302b8a0fb5c65e3d640e296b6148364ceba9e93eb4299ea07c84c911d7c616129115d3220c042c6e7d56af2bf20cc9d21e06e
|
7
|
+
data.tar.gz: fff053a40cc87b6c183930cda9b3db27849b94969cfaf32bec104bdf89015e3764d8eb6ca6997fba2c76d51ad994dae2d38302f57a353c281b6281e414bf61af
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
# i18n-tasks [![Build Status]
|
2
|
-
|
3
|
-
The default model of i18n key management in frameworks such as Rails is broken.
|
1
|
+
# i18n-tasks [![Build Status][badge-travis]][travis] [![Coverage Status][badge-coveralls]][coveralls] [![Code Climate][badge-code-climate]][code-climate] [![Flattr this][badge-flattr]][flattr]
|
4
2
|
|
3
|
+
The basic approach to i18n key management in frameworks such as Rails is far from perfect.
|
5
4
|
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
6
|
-
in the resource files, introducing unnecessary overhead on the translators.
|
7
|
-
Translation files can quickly turn to disarray.
|
5
|
+
in the resource files, introducing unnecessary overhead on the translators. Translation files can quickly turn to disarray.
|
8
6
|
|
9
|
-
i18n-tasks improves this by using static analysis.
|
7
|
+
i18n-tasks improves this by using static analysis. It provides tasks to find and manage missing and unused translations.
|
8
|
+
This information is inferred based on the keys the gem detects used with calls such as `I18n.t` when scanning the code.
|
10
9
|
|
11
10
|
<img width="534" height="288" src="https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png">
|
12
11
|
|
@@ -23,7 +22,7 @@ i18n-tasks improves this by using static analysis.
|
|
23
22
|
```yaml
|
24
23
|
# config/i18n-tasks.yml
|
25
24
|
base_locale: en
|
26
|
-
locales: [es, fr]
|
25
|
+
locales: [es, fr] # This includes base_locale by default
|
27
26
|
```
|
28
27
|
|
29
28
|
## Usage
|
@@ -84,7 +83,7 @@ i18n-tasks find 'auth.*'
|
|
84
83
|
i18n-tasks find '{number,currency}.format.*'
|
85
84
|
```
|
86
85
|
|
87
|
-
![i18n-screenshot]
|
86
|
+
![i18n-screenshot][screenshot-find]
|
88
87
|
|
89
88
|
Relative keys (`t '.title'`) and plural keys (key.one/many/other/etc) are fully supported.
|
90
89
|
|
@@ -120,7 +119,7 @@ so it is recommended to set locale settings explicitly:
|
|
120
119
|
```yaml
|
121
120
|
# config/i18n-tasks.yml
|
122
121
|
base_locale: en
|
123
|
-
locales: [es, fr]
|
122
|
+
locales: [es, fr] # This includes base_locale by default
|
124
123
|
```
|
125
124
|
|
126
125
|
### Storage
|
@@ -287,4 +286,13 @@ While i18n-tasks does not provide an HTML version of the report, you can add [on
|
|
287
286
|
|
288
287
|
This was originally developed for [Zuigo](http://zuigo.com/), a platform to organize and discover events.
|
289
288
|
|
290
|
-
[MIT license]
|
289
|
+
[MIT license]: /LICENSE.txt
|
290
|
+
[travis]: https://travis-ci.org/glebm/i18n-tasks
|
291
|
+
[badge-travis]: https://travis-ci.org/glebm/i18n-tasks.png?branch=master
|
292
|
+
[coveralls]: https://coveralls.io/r/glebm/i18n-tasks?branch=master
|
293
|
+
[badge-coveralls]: https://coveralls.io/repos/glebm/i18n-tasks/badge.png?branch=master
|
294
|
+
[code-climate]: https://codeclimate.com/github/glebm/i18n-tasks
|
295
|
+
[badge-code-climate]: https://codeclimate.com/github/glebm/i18n-tasks.png
|
296
|
+
[badge-flattr]: https://api.flattr.com/button/flattr-badge-large.png
|
297
|
+
[flattr]: https://flattr.com/submit/auto?user_id=glebm&url=https%3A%2F%2Fgithub.com%2Fglebm%2Fi18n-tasks
|
298
|
+
[screenshot-find]: https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-usages.png "i18n-tasks find output screenshot"
|
data/bin/i18n-tasks
CHANGED
@@ -24,14 +24,20 @@ end
|
|
24
24
|
if command
|
25
25
|
cmd = ::I18n::Tasks::Commands.new
|
26
26
|
meth = command[0]
|
27
|
-
|
27
|
+
opts = command[1].to_hash.reject{ |k, v| v.nil? }
|
28
|
+
args = command[2]
|
29
|
+
|
30
|
+
if opts.empty? && args.empty?
|
31
|
+
if ENV['VERBOSE']
|
32
|
+
STDERR.puts Term::ANSIColor.green "i18n-tasks: run #{meth.tr('_', '-')} without arguments"
|
33
|
+
end
|
28
34
|
cmd.send meth
|
29
35
|
else
|
30
|
-
|
36
|
+
opts = opts.merge(arguments: args) unless args.empty?
|
31
37
|
if ENV['VERBOSE']
|
32
|
-
STDERR.puts Term::ANSIColor.green "i18n-tasks: #{meth.tr('_', '-')} #{
|
38
|
+
STDERR.puts Term::ANSIColor.green "i18n-tasks: run #{meth.tr('_', '-')} with #{opts.map { |k, v| "#{k}=#{v}" } * ' '}"
|
33
39
|
end
|
34
|
-
cmd.send meth,
|
40
|
+
cmd.send meth, opts
|
35
41
|
end
|
36
42
|
else
|
37
43
|
STDERR.puts Term::ANSIColor.red "Command unknown: #{ARGV[0]}" if ARGV[0]
|
data/i18n-tasks.gemspec
CHANGED
@@ -8,10 +8,15 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.version = I18n::Tasks::VERSION
|
9
9
|
s.authors = ['glebm']
|
10
10
|
s.email = ['glex.spb@gmail.com']
|
11
|
-
s.summary = %q{
|
11
|
+
s.summary = %q{Manage translations in ruby applications with the awesome power of static analysis — Edit}
|
12
12
|
s.description = %q{
|
13
|
-
|
14
|
-
|
13
|
+
The basic approach to i18n key management in frameworks such as Rails has many flaws.
|
14
|
+
|
15
|
+
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
16
|
+
in the resource files, introducing unnecessary overhead on the translators.
|
17
|
+
Translation files can quickly turn to disarray.
|
18
|
+
|
19
|
+
i18n-tasks solves this problem with static analysis.
|
15
20
|
}
|
16
21
|
s.homepage = 'https://github.com/glebm/i18n-tasks'
|
17
22
|
if s.respond_to?(:metadata=)
|
data/lib/i18n/tasks/commands.rb
CHANGED
@@ -7,13 +7,14 @@ module I18n::Tasks
|
|
7
7
|
include Term::ANSIColor
|
8
8
|
require 'highline/import'
|
9
9
|
|
10
|
+
on_locale_opt = { as: Array, delimiter: /[+:,]/, default: 'all', argument: true, optional: false }
|
10
11
|
desc 'show missing translations'
|
11
12
|
opts do
|
12
|
-
on '-l', :locales=, 'Filter by locale
|
13
|
+
on '-l', :locales=, 'Filter by locale (default: all)', on_locale_opt
|
13
14
|
on '-t', :types, 'Filter by type (types: missing_from_base, eq_base, missing_from_locale)', as: Array, delimiter: /[+:,]/, argument: true, optional: false
|
14
15
|
end
|
15
16
|
cmd :missing do |opt = {}|
|
16
|
-
opt[:locales] =
|
17
|
+
opt[:locales] = locales_opt_or_args(opt)
|
17
18
|
terminal_report.missing_keys i18n_task.missing_keys(opt)
|
18
19
|
end
|
19
20
|
|
@@ -24,22 +25,22 @@ module I18n::Tasks
|
|
24
25
|
|
25
26
|
desc 'translate missing keys with Google Translate'
|
26
27
|
opts do
|
27
|
-
on '-l', :locales, '
|
28
|
+
on '-l', :locales, 'Locales to translate (default: all)', on_locale_opt
|
28
29
|
on '-f', :from, 'Locale to translate from (default: base)', default: 'base', argument: true, optional: false
|
29
30
|
end
|
30
31
|
cmd :translate_missing do |opt = {}|
|
31
32
|
opt[:from] = base_locale if opt[:from].blank? || opt[:from] == 'base'
|
32
|
-
opt[:locales] =
|
33
|
+
opt[:locales] = locales_opt_or_args(opt)
|
33
34
|
i18n_task.fill_missing_google_translate opt
|
34
35
|
end
|
35
36
|
|
36
37
|
desc 'add missing keys to the locales'
|
37
38
|
opts do
|
38
|
-
on '-l', :locales, '
|
39
|
+
on '-l', :locales, 'Locales to add keys into (default: all)', on_locale_opt
|
39
40
|
on '-p', :placeholder, 'Value for empty keys (default: base value or key.humanize)', argument: true, optional: false
|
40
41
|
end
|
41
42
|
cmd :add_missing do |opt = {}|
|
42
|
-
opt[:locales] =
|
43
|
+
opt[:locales] = locales_opt_or_args(opt)
|
43
44
|
opt[:value] ||= opt.delete(:placeholder)
|
44
45
|
opt[:value] ||= proc { |key, locale|
|
45
46
|
# default to base value or key.humanize
|
@@ -63,18 +64,18 @@ module I18n::Tasks
|
|
63
64
|
|
64
65
|
desc 'normalize translation data: sort and move to the right files'
|
65
66
|
opts do
|
66
|
-
on '-l', :locales=, '
|
67
|
+
on '-l', :locales=, 'Locales to normalize (default: all)', on_locale_opt
|
67
68
|
end
|
68
69
|
cmd :normalize do |opt = {}|
|
69
|
-
i18n_task.normalize_store!
|
70
|
+
i18n_task.normalize_store! locales_opt_or_args(opt)
|
70
71
|
end
|
71
72
|
|
72
73
|
desc 'remove unused keys'
|
73
74
|
opts do
|
74
|
-
on '-l', :locales=, '
|
75
|
+
on '-l', :locales=, 'Locales to remove unused keys from (default: all)', on_locale_opt
|
75
76
|
end
|
76
77
|
cmd :remove_unused do |opt = {}|
|
77
|
-
locales =
|
78
|
+
locales = locales_opt_or_args(opt)
|
78
79
|
unused_keys = i18n_task.unused_keys
|
79
80
|
if unused_keys.present?
|
80
81
|
terminal_report.unused_keys(unused_keys)
|
@@ -12,6 +12,14 @@ module I18n::Tasks
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
def locales_opt_or_args(opt)
|
16
|
+
locales_opt(opt[:arguments].presence || opt[:locales]).tap do |locales|
|
17
|
+
if ENV['VERBOSE']
|
18
|
+
STDERR.puts Term::ANSIColor.green "i18n-tasks: locales are #{locales.inspect}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
class << self
|
16
24
|
def cmds
|
17
25
|
@cmds ||= {}.with_indifferent_access
|
@@ -45,12 +45,15 @@ module I18n::Tasks::Configuration
|
|
45
45
|
}
|
46
46
|
end
|
47
47
|
|
48
|
-
# @return [Array<String>] all available locales
|
48
|
+
# @return [Array<String>] all available locales, base_locale is always first
|
49
49
|
def locales
|
50
50
|
@config_sections[:locales] ||= begin
|
51
51
|
locales = (config[:locales] || I18n.available_locales).map(&:to_s)
|
52
|
-
|
53
|
-
|
52
|
+
if locales.include?(base_locale)
|
53
|
+
[base_locale] + (locales - [base_locale])
|
54
|
+
else
|
55
|
+
[base_locale] + locales
|
56
|
+
end
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
@@ -3,18 +3,22 @@ module I18n::Tasks
|
|
3
3
|
# @param [:missing_from_base, :missing_from_locale, :eq_base] type (default nil)
|
4
4
|
# @return [KeyGroup]
|
5
5
|
def missing_keys(opts = {})
|
6
|
-
locales =
|
6
|
+
locales = Array(opts[:locales]).presence || self.locales
|
7
7
|
type = opts[:type]
|
8
8
|
unless type
|
9
9
|
types = opts[:types].presence || missing_keys_types
|
10
10
|
opts = opts.except(:types).merge(locales: locales)
|
11
11
|
return types.map { |t| missing_keys(opts.merge(type: t)) }.reduce(:+)
|
12
12
|
end
|
13
|
+
|
13
14
|
if type.to_s == 'missing_from_base'
|
14
|
-
keys_missing_from_base
|
15
|
+
keys = keys_missing_from_base if locales.include?(base_locale)
|
15
16
|
else
|
16
|
-
locales.map { |locale|
|
17
|
+
keys = non_base_locales(locales).map { |locale|
|
18
|
+
send("keys_#{type}", locale)
|
19
|
+
}.reduce(:+)
|
17
20
|
end
|
21
|
+
keys || KeyGroup.new([])
|
18
22
|
end
|
19
23
|
|
20
24
|
def missing_keys_types
|
data/lib/i18n/tasks/version.rb
CHANGED
data/spec/i18n_tasks_spec.rb
CHANGED
@@ -11,14 +11,19 @@ describe 'i18n-tasks' do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe 'missing' do
|
14
|
-
|
15
|
-
|
16
|
-
expect(run_cmd :missing).to be_i18n_keys %w(
|
17
|
-
en.used_but_missing.a en.relative.index.missing
|
14
|
+
let (:expected_missing_keys) {
|
15
|
+
%w( en.used_but_missing.a en.relative.index.missing
|
18
16
|
es.missing_in_es.a es.blank_in_es.a es.same_in_es.a
|
19
17
|
en.hash.pattern_missing.a en.hash.pattern_missing.b
|
20
|
-
en.missing_symbol_key en.missing_symbol.key_two en.missing_symbol.key_three
|
21
|
-
|
18
|
+
en.missing_symbol_key en.missing_symbol.key_two en.missing_symbol.key_three )
|
19
|
+
}
|
20
|
+
it 'detects missing or identical' do
|
21
|
+
capture_stderr do
|
22
|
+
expect(run_cmd :missing).to be_i18n_keys expected_missing_keys
|
23
|
+
es_keys = expected_missing_keys.grep(/^es\./)
|
24
|
+
# locale argument
|
25
|
+
expect(run_cmd :missing, locales: %w(es)).to be_i18n_keys es_keys
|
26
|
+
expect(run_cmd :missing, arguments: %w(es)).to be_i18n_keys es_keys
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erubis
|
@@ -180,8 +180,13 @@ dependencies:
|
|
180
180
|
version: '0'
|
181
181
|
description: |2
|
182
182
|
|
183
|
-
|
184
|
-
|
183
|
+
The basic approach to i18n key management in frameworks such as Rails has many flaws.
|
184
|
+
|
185
|
+
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
186
|
+
in the resource files, introducing unnecessary overhead on the translators.
|
187
|
+
Translation files can quickly turn to disarray.
|
188
|
+
|
189
|
+
i18n-tasks solves this problem with static analysis.
|
185
190
|
email:
|
186
191
|
- glex.spb@gmail.com
|
187
192
|
executables:
|
@@ -277,8 +282,8 @@ rubyforge_project:
|
|
277
282
|
rubygems_version: 2.0.14
|
278
283
|
signing_key:
|
279
284
|
specification_version: 4
|
280
|
-
summary:
|
281
|
-
|
285
|
+
summary: Manage translations in ruby applications with the awesome power of static
|
286
|
+
analysis — Edit
|
282
287
|
test_files:
|
283
288
|
- spec/file_system_data_spec.rb
|
284
289
|
- spec/fixtures/app/assets/javascripts/application.js
|