i18nliner 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.md +151 -104
  2. data/lib/i18nliner/base.rb +47 -0
  3. data/lib/i18nliner/call_helpers.rb +39 -13
  4. data/lib/i18nliner/commands/check.rb +20 -10
  5. data/lib/i18nliner/commands/dump.rb +17 -0
  6. data/lib/i18nliner/commands/generic_command.rb +10 -1
  7. data/lib/i18nliner/errors.rb +11 -1
  8. data/lib/i18nliner/erubis.rb +12 -0
  9. data/lib/i18nliner/extensions/controller.rb +25 -0
  10. data/lib/i18nliner/extensions/core.rb +61 -0
  11. data/lib/i18nliner/extensions/inferpolation.rb +28 -0
  12. data/lib/i18nliner/extensions/model.rb +29 -0
  13. data/lib/i18nliner/extensions/view.rb +28 -0
  14. data/lib/i18nliner/extractors/ruby_extractor.rb +15 -33
  15. data/lib/i18nliner/extractors/sexp_helper.rb +38 -0
  16. data/lib/i18nliner/extractors/translate_call.rb +9 -11
  17. data/lib/i18nliner/extractors/translation_hash.rb +6 -6
  18. data/lib/i18nliner/pre_processors/erb_pre_processor.rb +334 -0
  19. data/lib/i18nliner/processors/abstract_processor.rb +26 -5
  20. data/lib/i18nliner/processors/erb_processor.rb +19 -3
  21. data/lib/i18nliner/processors/ruby_processor.rb +16 -5
  22. data/lib/i18nliner/railtie.rb +27 -0
  23. data/lib/i18nliner/scope.rb +4 -0
  24. data/lib/i18nliner.rb +5 -29
  25. data/lib/tasks/i18nliner.rake +10 -4
  26. data/spec/commands/check_spec.rb +22 -0
  27. data/spec/commands/dump_spec.rb +27 -0
  28. data/spec/extensions/core_spec.rb +71 -0
  29. data/spec/extensions/inferpolation_spec.rb +41 -0
  30. data/spec/extensions/view_spec.rb +42 -0
  31. data/spec/extractors/ruby_extractor_spec.rb +4 -5
  32. data/spec/extractors/translate_call_spec.rb +29 -2
  33. data/spec/fixtures/app/models/invalid.rb +5 -0
  34. data/spec/fixtures/app/models/valid.rb +5 -0
  35. data/spec/pre_processors/erb_pre_processor_spec.rb +194 -0
  36. data/spec/processors/erb_processor_spec.rb +28 -0
  37. metadata +88 -5
data/README.md CHANGED
@@ -1,15 +1,12 @@
1
1
  # I18nliner
2
2
 
3
+ [<img src="https://secure.travis-ci.org/jenseng/i18nliner.png" />](http://travis-ci.org/jenseng/i18nliner)
4
+
3
5
  yay readme-driven development!
4
6
 
5
7
  ## TODO
6
8
 
7
- * inferred placeholders (instance vars and methods)
8
- * ERB pre-processor
9
- * wrapper inference
10
- * helper/placeholder extraction
11
9
  * rake tasks
12
- * dump
13
10
  * diff
14
11
  * import
15
12
 
@@ -19,30 +16,36 @@ I18nliner is I18n made simple.
19
16
 
20
17
  No .yml files. Inline defaults. Optional keys. Inferred interpolation values.
21
18
  Wrappers and blocks, so your templates look template-y and your translations
22
- HTML-free.
19
+ stay HTML-free.
23
20
 
24
21
  ## TL;DR
25
22
 
26
23
  I18nliner lets you do stuff like this:
27
24
 
28
- t "Ohai %{@user.name}, my default translation is right here in the code. " +
29
- "Inferred keys and placeholder values, oh my!"
25
+ ```ruby
26
+ t "Ohai %{@user.name}, my default translation is right here in the code. " \
27
+ "Inferred keys and placeholder values, oh my!"
28
+ ```
30
29
 
31
30
  and even this:
32
31
 
33
- <%= t do %>
34
- Hey <%= amigo %>!
35
- Although I am <%= link_to "linking to something", random_path %> and
36
- have some <strong>bold text</strong>, the translators will see
37
- <strong><em>absolutely no markup</em></strong> and will only have a
38
- single string to translate :o
39
- <% end %>
32
+ ```erb
33
+ <%= t do %>
34
+ Hey <%= amigo %>!
35
+ Although I am <%= link_to "linking to something", random_path %> and
36
+ have some <strong>bold text</strong>, the translators will see
37
+ <strong><em>absolutely no markup</em></strong> and will only have a
38
+ single string to translate :o
39
+ <% end %>
40
+ ```
40
41
 
41
42
  ## Installation
42
43
 
43
44
  Add the following to your Gemfile:
44
45
 
45
- gem 'i18nliner'
46
+ ```ruby
47
+ gem 'i18nliner'
48
+ ```
46
49
 
47
50
  ## Features
48
51
 
@@ -50,11 +53,15 @@ Add the following to your Gemfile:
50
53
 
51
54
  Instead of maintaining .yml files and doing stuff like this:
52
55
 
53
- I18n.t :account_page_title
56
+ ```ruby
57
+ I18n.t :account_page_title
58
+ ```
54
59
 
55
60
  Forget the .yml and just do:
56
61
 
57
- I18n.t :account_page_title, "My Account"
62
+ ```ruby
63
+ I18n.t :account_page_title, "My Account"
64
+ ```
58
65
 
59
66
  Regular I18n options follow the (optional) default translation, so you can do
60
67
  the usual stuff (placeholders, etc.).
@@ -63,7 +70,9 @@ the usual stuff (placeholders, etc.).
63
70
 
64
71
  Sure, but *you* don't need to write it. Just run:
65
72
 
66
- rake i18nliner:dump
73
+ ```bash
74
+ rake i18nliner:dump
75
+ ```
67
76
 
68
77
  This extracts all default translations from your codebase, merges them with any
69
78
  other ones (from rails or pre-existing .yml files), and outputs them to
@@ -74,7 +83,9 @@ other ones (from rails or pre-existing .yml files), and outputs them to
74
83
  Why waste time coming up with keys that are less descriptive than the default
75
84
  translation? I18nliner makes keys optional, so you can just do this:
76
85
 
77
- I18n.t "My Account"
86
+ ```ruby
87
+ I18n.t "My Account"
88
+ ```
78
89
 
79
90
  I18nliner will create a [unique key](CONFIG.md) based on the translation (e.g.
80
91
  `:my_account`), so you don't have to.
@@ -91,18 +102,22 @@ Interpolation values may be inferred by I18nliner if not provided. So long as
91
102
  it's an instance variable or method (or chain), you don't need to specify its
92
103
  value. So this:
93
104
 
94
- <p>
95
- <%= t "Hello, %{user}. This request was a %{request_method}.",
96
- :user => @user.name,
97
- :request_method => request.method
98
- %>
99
- </p>
105
+ ```erb
106
+ <p>
107
+ <%= t "Hello, %{user}. This request was a %{request_method}.",
108
+ user: @user.name,
109
+ request_method: request.method
110
+ %>
111
+ </p>
112
+ ```
100
113
 
101
114
  Can just be this:
102
115
 
103
- <p>
104
- <%= t "Hello, %{@user.name}. This request was a %{request.method}." %>
105
- </p>
116
+ ```erb
117
+ <p>
118
+ <%= t "Hello, %{@user.name}. This request was a %{request.method}." %>
119
+ </p>
120
+ ```
106
121
 
107
122
  Note that local variables cannot be inferred.
108
123
 
@@ -112,19 +127,23 @@ Note that local variables cannot be inferred.
112
127
 
113
128
  Suppose you have something like this in your ERB:
114
129
 
115
- <p>
116
- You can <%= link_to "lead", new_discussion_path %> a new discussion or
117
- <%= link_to "join", discussion_search_path %> an existing one.
118
- </p>
130
+ ```erb
131
+ <p>
132
+ You can <%= link_to "lead", new_discussion_path %> a new discussion or
133
+ <%= link_to "join", discussion_search_path %> an existing one.
134
+ </p>
135
+ ```
119
136
 
120
137
  You might try something like this:
121
138
 
122
- <p>
123
- <%= t "You can %{lead} a new discussion or %{join} an existing one.",
124
- :lead => link_to(t("lead"), new_discussion_path),
125
- :join => link_to(t("join"), discussion_search_path)
126
- %>
127
- </p>
139
+ ```erb
140
+ <p>
141
+ <%= t("You can %{lead} a new discussion or %{join} an existing one.",
142
+ lead: link_to(t("lead"), new_discussion_path),
143
+ join: link_to(t("join"), discussion_search_path)).html_safe
144
+ %>
145
+ </p>
146
+ ```
128
147
 
129
148
  This is not great, because:
130
149
 
@@ -136,14 +155,16 @@ This is not great, because:
136
155
 
137
156
  So you might try this instead:
138
157
 
139
- <p>
140
- <%= t :discussion_html,
141
- "You can <a href="%{lead_url}">lead</a> a new discussion or " +
142
- "<a href="%{join_url}">join</a> an existing one.",
143
- :lead_url => new_discussion_path,
144
- :join_url => discussion_search_path
145
- %>
146
- </p>
158
+ ```erb
159
+ <p>
160
+ <%= t :discussion_html,
161
+ "You can <a href="%{lead_url}">lead</a> a new discussion or " \
162
+ "<a href="%{join_url}">join</a> an existing one.",
163
+ lead_url: new_discussion_path,
164
+ join_url: discussion_search_path
165
+ %>
166
+ </p>
167
+ ```
147
168
 
148
169
  This isn't much better, because now you have HTML in your translations. If you
149
170
  want to add a class to the link, you have to go update all the translations.
@@ -157,14 +178,16 @@ So what do you do?
157
178
  I18nliner lets you specify wrappers, so you can keep HTML out the translations,
158
179
  while still just having a single string needing translation:
159
180
 
160
- <p>
161
- <%= t "You can *lead* a new discussion or **join** an existing one.",
162
- :wrappers => [
163
- link_to('\1', new_discussion_path),
164
- link_to('\1', discussion_search_path)
165
- ]
166
- %>
167
- </p>
181
+ ```erb
182
+ <p>
183
+ <%= t "You can *lead* a new discussion or **join** an existing one.",
184
+ wrappers: [
185
+ link_to('\1', new_discussion_path),
186
+ link_to('\1', discussion_search_path)
187
+ ]
188
+ %>
189
+ </p>
190
+ ```
168
191
 
169
192
  Default delimiters are increasing numbers of asterisks, but you can specify
170
193
  any string as a delimiter by using a hash rather than an array.
@@ -175,50 +198,60 @@ But wait, there's more!
175
198
 
176
199
  Perhaps you want your templates to look like, well, templates. Try this:
177
200
 
178
- <p>
179
- <%= t do %>
180
- Welcome to the internets, <%= user.name %>
181
- <% end %>
182
- </p>
201
+ ```erb
202
+ <p>
203
+ <%= t do %>
204
+ Welcome to the internets, <%= user.name %>
205
+ <% end %>
206
+ </p>
207
+ ```
183
208
 
184
209
  Or even this:
185
210
 
186
- <p>
187
- <%= t do %>
188
- <b>Ohai <%= user.name %>,</b>
189
- you can <%= link_to "lead", new_discussion_path %> a new discussion or
190
- <%= link_to "join", discussion_search_path %> an existing one.
191
- <% end %>
192
- </p>
211
+ ```erb
212
+ <p>
213
+ <%= t do %>
214
+ <b>Ohai <%= user.name %>,</b>
215
+ you can <%= link_to "lead", new_discussion_path %> a new discussion or
216
+ <%= link_to "join", discussion_search_path %> an existing one.
217
+ <% end %>
218
+ </p>
219
+ ```
193
220
 
194
221
  In case you're curious about the man behind the curtain, I18nliner adds an ERB
195
222
  pre-processor that turns the second example into something like this right
196
223
  before it hits ERB:
197
224
 
198
- <p>
199
- <%= t :some_unique_key,
200
- "*Ohai %{user_name}*, you can **lead** a new discussion or ***join*** an existing one.",
201
- :user_name => @user.name,
202
- :wrappers => [
203
- '<b>\1</b>',
204
- link_to('\1', new_discussion_path),
205
- link_to('\1', discussion_search_path)
206
- ]
207
- %>
208
- </p>
225
+ ```erb
226
+ <p>
227
+ <%= t :some_unique_key,
228
+ "*Ohai %{user_name}*, you can **lead** a new discussion or ***join*** an existing one.",
229
+ user_name: user.name,
230
+ wrappers: [
231
+ '<b>\1</b>',
232
+ link_to('\1', new_discussion_path),
233
+ link_to('\1', discussion_search_path)
234
+ ]
235
+ %>
236
+ </p>
237
+ ```
209
238
 
210
239
  In other words, it will infer wrappers from your (balanced) markup and
211
240
  [`link_to` calls](INFERRED_WRAPPERS.md), and will create placeholders for any
212
- other ERB expressions. ERB statements (e.g.
213
- `<% if some_condition %>...`) are *not* supported inside block translations, with
214
- the notable exception of nested translations, e.g.
215
-
216
- <%= t do %>
217
- Be sure to
218
- <a href="/account/" title="<%= t do %>Account Settings<% end %>">
219
- set up your account
220
- </a>.
221
- <% end %>
241
+ other (inline) ERB expressions. ERB statements (e.g.
242
+ `<% if some_condition %>...`) and block expressions (e.g.
243
+ `<%= form_for @person do %>...`) are *not* supported within a block
244
+ translation. The only exception to this rule is nested translation
245
+ calls, e.g. this is totally fine:
246
+
247
+ ```erb
248
+ <%= t do %>
249
+ Be sure to
250
+ <a href="/account/" title="<%= t do %>Account Settings<% end %>">
251
+ set up your account
252
+ </a>.
253
+ <% end %>
254
+ ```
222
255
 
223
256
  #### HTML Safety
224
257
 
@@ -232,28 +265,29 @@ escaped.
232
265
  Pluralization can be tricky, but [I18n gives you some flexibility](http://guides.rubyonrails.org/i18n.html#pluralization).
233
266
  I18nliner brings this inline with a default translation hash, e.g.
234
267
 
235
- t({:one => "There is one light!", :other => "There are %{count} lights!"},
236
- :count => picard.visible_lights.count)
268
+ ```ruby
269
+ t({one: "There is one light!", other: "There are %{count} lights!"},
270
+ count: picard.visible_lights.count)
271
+ ```
237
272
 
238
273
  Note that the :count interpolation value needs to be explicitly set when doing
239
- pluralization. On the ERB side, I18nliner enhances pluralize to take a block,
240
- so you can do this:
241
-
242
- <%= pluralize picard.visible_lights.count do %>
243
- <% one do %>There is one light!<% end %>
244
- <% other do %>There are <%= count %> lights!<% end %>
245
- <% end %>
274
+ pluralization.
246
275
 
247
276
  If you just want to pluralize a single word, there's a shortcut:
248
277
 
249
- t "person", :count => users.count
278
+ ```ruby
279
+ t "person", count: users.count
280
+ ```
250
281
 
251
282
  This is equivalent to:
252
283
 
253
- t({:one => "1 person", :other => "%{count} people"},
254
- :count => users.count)
284
+ ```ruby
285
+ t({one: "1 person", other: "%{count} people"},
286
+ count: users.count)
287
+ ```
255
288
 
256
- I18nliner uses the pluralize helper to determine the default one/other values,
289
+ I18nliner uses [`String#pluralize`](http://edgeguides.rubyonrails.org/active_support_core_extensions.html#pluralize)
290
+ to determine the default one/other values,
257
291
  so if your `I18n.default_locale` is something other than English, you may need
258
292
  to [add some inflections](https://gist.github.com/838188).
259
293
 
@@ -271,6 +305,16 @@ Does an i18nliner:check, and then extracts all default translations from your
271
305
  codebase, merges them with any other ones (from rails or pre-existing .yml
272
306
  files), and outputs them to `config/locales/generated/en.yml`.
273
307
 
308
+ ### Dynamic Translations
309
+
310
+ Note that check and dump commands require all translation keys and
311
+ defaults to be literals. This is because it reads your code, it doesn't
312
+ run it. If you know what you are doing and want to pass in a variable or
313
+ other expression, you can use the `t!` (or `translate!`) command. It works
314
+ the same as `t` at runtime, but signals to the extractor that it shouldn't
315
+ complain. You should only do this if you are sure that the specified
316
+ key/string is extracted elsewhere or already in your yml.
317
+
274
318
  ### i18nliner:diff
275
319
 
276
320
  Does an i18nliner:dump and creates a diff from a previous one (path or git
@@ -294,7 +338,9 @@ though it supports
294
338
  If you only want to check a particular file/directory/pattern, you can set the
295
339
  environment variable `ONLY` when you run the command, e.g.
296
340
 
297
- rake i18nliner:check ONLY=/app/**/user*
341
+ ```bash
342
+ rake i18nliner:check ONLY=/app/**/user*
343
+ ```
298
344
 
299
345
  ## Compatibility
300
346
 
@@ -307,7 +353,8 @@ I18nliner requires at least Ruby 1.9.3 and Rails 3.
307
353
 
308
354
  ## What about JavaScript/Handlebars?
309
355
 
310
- Coming soon. I18nliner was inspired by some [I18n extensions](https://github.com/instructure/canvas-lms/tree/master/lib/i18n_extraction)
356
+ [Coming](https://github.com/jenseng/i18nliner-js) [soon](https://github.com/fivetanley/i18ninliner-handlebars).
357
+ I18nliner was inspired by some [I18n extensions](https://github.com/instructure/canvas-lms/tree/master/lib/i18n_extraction)
311
358
  I did in [Canvas-LMS](https://github.com/instructure/canvas-lms). While
312
359
  it also has the JavaScript/Handlebars equivalents, they are tightly
313
360
  coupled to Canvas-LMS and are written in Ruby. So basically we're talking
@@ -317,4 +364,4 @@ that is js_extractor.
317
364
 
318
365
  ## License
319
366
 
320
- Copyright (c) 2013 Jon Jensen, released under the MIT license
367
+ Copyright (c) 2014 Jon Jensen, released under the MIT license
@@ -0,0 +1,47 @@
1
+ require 'i18n'
2
+
3
+ module I18nliner
4
+ def self.ignore
5
+ @ignore ||= begin
6
+ path = File.join(base_path, ".i18nignore")
7
+ File.exist?(path) ?
8
+ File.read(path).split(/\r?\n|\r/) :
9
+ []
10
+ end
11
+ end
12
+
13
+ def self.translations
14
+ end
15
+
16
+ def self.manual_translations
17
+ # TODO: support additional backends
18
+ I18n.backend.send(:translations)
19
+ end
20
+
21
+ def self.look_up(key)
22
+ I18n.exists?(I18n.locale, key)
23
+ end
24
+
25
+ def self.setting(key, value)
26
+ instance_eval <<-CODE
27
+ def #{key}(value = nil)
28
+ if value && block_given?
29
+ begin
30
+ value_was = @#{key}
31
+ @#{key} = value
32
+ yield
33
+ ensure
34
+ @#{key} = value_was
35
+ end
36
+ else
37
+ @#{key} = #{value.inspect} if @#{key}.nil?
38
+ @#{key}
39
+ end
40
+ end
41
+ CODE
42
+ end
43
+
44
+ setting :inferred_key_format, :underscored_crc32
45
+ setting :infer_interpolation_values, true
46
+ setting :base_path, "./"
47
+ end
@@ -1,14 +1,14 @@
1
- require 'iconv'
2
1
  require 'zlib'
2
+ require 'i18n'
3
+ require 'i18nliner/base'
3
4
 
4
5
  module I18nliner
5
6
  module CallHelpers
6
7
  ALLOWED_PLURALIZATION_KEYS = [:zero, :one, :few, :many, :other]
7
8
  REQUIRED_PLURALIZATION_KEYS = [:one, :other]
8
9
 
9
- def normalize_key(key, scope, receiver)
10
- key = key.to_s
11
- scope.normalize_key(key)
10
+ def normalize_key(key, scope = Scope.root)
11
+ scope.normalize_key(key.to_s)
12
12
  end
13
13
 
14
14
  def normalize_default(default, translate_options = {})
@@ -25,21 +25,22 @@ module I18nliner
25
25
  end
26
26
 
27
27
  def infer_key(default, translate_options = {})
28
+ return unless default && (default.is_a?(String) || default.is_a?(Hash))
28
29
  default = default[:other].to_s if default.is_a?(Hash)
29
30
  keyify(normalize_default(default, translate_options))
30
31
  end
31
32
 
32
33
  def keyify_underscored(string)
33
- Iconv.iconv('ascii//translit//ignore', 'utf-8', string).
34
- to_s.
35
- downcase.
36
- gsub(/[^a-z0-9_\.]+/, '_').
37
- gsub(/\A_|_\z/, '')[0..50]
34
+ key = I18n.transliterate(string, :locale => I18n.default_locale).to_s
35
+ key.downcase!
36
+ key.gsub!(/[^a-z0-9_]+/, '_')
37
+ key.gsub!(/\A_|_\z/, '')
38
+ key[0..50]
38
39
  end
39
40
 
40
41
  def keyify_underscored_crc32(string)
41
- checksum = Zlib.crc32(string.size.to_s + ":" + string).to_s(16)
42
- keyify_underscored(string) + "_#{checksum}"
42
+ checksum = Zlib.crc32("#{string.size.to_s}:#{string}").to_s(16)
43
+ "#{keyify_underscored(string)}_#{checksum}"
43
44
  end
44
45
 
45
46
  def keyify(string)
@@ -57,13 +58,38 @@ module I18nliner
57
58
  # key, default_hash, options
58
59
  # default_string [, options]
59
60
  # default_hash, options
60
- def key_provided?(scope, receiver, key_or_default = nil, default_or_options = nil, maybe_options = nil, *others)
61
+ def key_provided?(key_or_default = nil, default_or_options = nil, maybe_options = nil, *others)
61
62
  return false if key_or_default.is_a?(Hash)
62
63
  return true if key_or_default.is_a?(Symbol)
63
64
  return true if default_or_options.is_a?(String)
64
65
  return true if maybe_options
65
- return true if I18nliner.look_up(normalize_key(key_or_default, scope, receiver))
66
+ return true if key_or_default =~ /\A\.?(\w+\.)+\w+\z/
66
67
  false
67
68
  end
69
+
70
+ def pluralization_hash?(hash)
71
+ hash.is_a?(Hash) &&
72
+ hash.size > 0 &&
73
+ (hash.keys - ALLOWED_PLURALIZATION_KEYS).size == 0
74
+ end
75
+
76
+ def infer_arguments(args)
77
+ if args.size == 2 && args[1].is_a?(Hash) && args[1][:default]
78
+ return args
79
+ end
80
+
81
+ has_key = key_provided?(*args)
82
+ args.unshift infer_key(args[0]) unless has_key
83
+
84
+ default_or_options = args[1]
85
+ if args[2] || default_or_options.is_a?(String) || pluralization_hash?(default_or_options)
86
+ options = args[2] ||= {}
87
+ options[:default] = args.delete_at(1) if options.is_a?(Hash)
88
+ end
89
+ args << {} if args.size == 1
90
+ args
91
+ end
92
+
93
+ extend self
68
94
  end
69
95
  end
@@ -1,17 +1,25 @@
1
+ require 'i18nliner/commands/generic_command'
2
+ require 'i18nliner/extractors/translation_hash'
3
+ require 'active_support/core_ext/enumerable'
4
+ Dir[File.join(File.dirname(__FILE__), "../processors/*.rb")].each do |file|
5
+ require "i18nliner/processors/#{File.basename(file)}"
6
+ end
7
+
1
8
  module I18nliner
2
9
  module Commands
3
10
  class Check < GenericCommand
4
- attr_reader :translations
11
+ attr_reader :translations, :errors
5
12
 
6
13
  def initialize(options)
7
14
  super
8
15
  @errors = []
9
- @translations = TranslationHash.new(I18nliner.manual_translations)
16
+ @translations = I18nliner::Extractors::TranslationHash.new(I18nliner.manual_translations)
10
17
  end
11
18
 
12
19
  def processors
13
20
  @processors ||= I18nliner::Processors.all.map do |klass|
14
- klass.new :only => @options[:only],
21
+ klass.new @translations,
22
+ :only => @options[:only],
15
23
  :translations => @translations,
16
24
  :checker => method(:check_file)
17
25
  end
@@ -22,14 +30,16 @@ module I18nliner
22
30
  end
23
31
 
24
32
  def check_file(file)
25
- print green(".") if yield file
33
+ if yield file
34
+ print green(".") unless @options[:silent]
35
+ end
26
36
  rescue SyntaxError, StandardError, ExtractionError
27
37
  @errors << "#{$!}\n#{file}"
28
- print red("F")
38
+ print red("F") unless @options[:silent]
29
39
  end
30
40
 
31
- def failure
32
- @errors.size > 0
41
+ def success?
42
+ @errors.empty?
33
43
  end
34
44
 
35
45
  def print_summary
@@ -46,13 +56,13 @@ module I18nliner
46
56
 
47
57
  print "Finished in #{Time.now - @start} seconds\n\n"
48
58
  summary = "#{file_count} files, #{translation_count} strings, #{@errors.size} failures"
49
- puts failure ? red(summary) : green(summary)
59
+ puts success? ? green(summary) : red(summary)
50
60
  end
51
61
 
52
62
  def run
53
63
  check_files
54
- print_summary
55
- raise "check command encountered errors" if failure
64
+ print_summary unless @options[:silent]
65
+ success?
56
66
  end
57
67
  end
58
68
  end
@@ -1,7 +1,24 @@
1
+ require 'ya2yaml'
2
+ require 'fileutils'
3
+
1
4
  module I18nliner
2
5
  module Commands
3
6
  class Dump < GenericCommand
7
+ attr_reader :yml_file
8
+
9
+ def initialize(options)
10
+ super
11
+ @translations = @options[:translations]
12
+ @yml_file = @options[:file] ||
13
+ File.join(I18nliner.base_path, "config", "locales", "generated", "#{I18n.default_locale}.yml")
14
+ end
15
+
4
16
  def run
17
+ FileUtils.mkdir_p File.dirname(yml_file)
18
+ File.open(yml_file, "w") do |file|
19
+ file.write({I18n.default_locale.to_s => @translations}.ya2yaml(:syck_compatible => true))
20
+ end
21
+ puts "Wrote default translations to #{yml_file}" unless @options[:silent]
5
22
  end
6
23
  end
7
24
  end
@@ -1,3 +1,6 @@
1
+ require 'i18nliner/commands/basic_formatter'
2
+ require 'i18nliner/commands/color_formatter'
3
+
1
4
  module I18nliner
2
5
  module Commands
3
6
  class GenericCommand
@@ -9,8 +12,14 @@ module I18nliner
9
12
  extend ColorFormatter if $stdout.tty?
10
13
  end
11
14
 
15
+ def success?
16
+ true
17
+ end
18
+
12
19
  def self.run(options)
13
- new(options).run
20
+ command = new(options)
21
+ command.run
22
+ command
14
23
  end
15
24
  end
16
25
  end