twine 1.0.4 → 1.0.5
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 +5 -5
- data/README.md +44 -5
- data/lib/twine/formatters/abstract.rb +8 -1
- data/lib/twine/formatters/android.rb +2 -2
- data/lib/twine/formatters/apple.rb +1 -1
- data/lib/twine/formatters/django.rb +0 -11
- data/lib/twine/formatters/flash.rb +0 -5
- data/lib/twine/formatters/gettext.rb +4 -14
- data/lib/twine/formatters/jquery.rb +5 -10
- data/lib/twine/plugin.rb +1 -1
- data/lib/twine/runner.rb +6 -11
- data/lib/twine/version.rb +1 -1
- data/test/fixtures/formatter_gettext.po +2 -2
- data/test/fixtures/formatter_gettext_quotes.po +10 -0
- data/test/test_cli.rb +1 -1
- data/test/test_formatters.rb +85 -4
- data/test/test_generate_all_localization_files.rb +4 -8
- data/test/test_generate_localization_archive.rb +1 -1
- data/test/twine_test.rb +2 -2
- metadata +55 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 44fd7c832c7ecf4c70ebd07f2a7471b7ec7d7dd4989cc336becd4f404a2cf7dd
|
4
|
+
data.tar.gz: b947aeaac122ab7abd0d02704210ea13d52974a5e3a95e74414bec019700b184
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d726639293d96d2c053bd13d7222e1971ceb542db66956b8415301a9f075a3b429677f1f5b34ded00d9e60814c9e7b472ead5106b05dc3d08c51b25841a957c8
|
7
|
+
data.tar.gz: b50fd40a63c1b804e19a4c7e4ae791ace13898080a0459e998efde4810801919fc4e24d20a689d7774814271e0925d0992a3cc5ddfdac2b9dc36f82ec5022967
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Twine
|
2
2
|
|
3
|
-
[](https://circleci.com/gh/scelis/twine)
|
4
4
|
|
5
5
|
Twine is a command line tool for managing your strings and their translations. These are all stored in a master text file and then Twine uses this file to import and export localization files in a variety of types, including iOS and Mac OS X `.strings` files, Android `.xml` files, gettext `.po` files, and [jquery-localize][jquerylocalize] `.json` files. This allows individuals and companies to easily share translations across multiple projects, as well as export localization files in any format the user wants.
|
6
6
|
|
@@ -150,7 +150,7 @@ This command validates that the Twine data file can be parsed, contains no dupli
|
|
150
150
|
The easiest way to create your first Twine data file is to run the [`consume-all-localization-files`](#consume-all-localization-files) command. The one caveat is to first create a blank file to use as your starting point. Then, just point the `consume-all-localization-files` command at a directory in your project containing all of your localization files.
|
151
151
|
|
152
152
|
$ touch twine.txt
|
153
|
-
$ twine consume-all-localization-files twine.txt Resources/Locales --developer-language en --consume-all --consume-comments
|
153
|
+
$ twine consume-all-localization-files twine.txt Resources/Locales --developer-language en --consume-all --consume-comments --format apple/android/gettext/jquery/django/tizen/flash
|
154
154
|
|
155
155
|
## Twine and Your Build Process
|
156
156
|
|
@@ -174,7 +174,10 @@ Now, whenever you build your application, Xcode will automatically invoke Twine
|
|
174
174
|
|
175
175
|
### Android Studio/Gradle
|
176
176
|
|
177
|
-
|
177
|
+
#### Standard
|
178
|
+
|
179
|
+
Add the following code to `app/build.gradle`:
|
180
|
+
|
178
181
|
```
|
179
182
|
task generateLocalizations {
|
180
183
|
String script = 'if hash twine 2>/dev/null; then twine generate-localization-file twine.txt ./src/main/res/values/generated_strings.xml; fi'
|
@@ -183,10 +186,46 @@ task generateLocalizations {
|
|
183
186
|
args '-c', script
|
184
187
|
}
|
185
188
|
}
|
189
|
+
|
190
|
+
preBuild {
|
191
|
+
dependsOn generateLocalizations
|
192
|
+
}
|
186
193
|
```
|
187
194
|
|
188
|
-
|
195
|
+
#### Using [jruby](http://jruby.org)
|
189
196
|
|
197
|
+
With this approach, developers do not need to manually install ruby, gem, or twine.
|
198
|
+
|
199
|
+
Add the following code to `app/build.gradle`:
|
200
|
+
|
201
|
+
```
|
202
|
+
buildscript {
|
203
|
+
repositories { jcenter() }
|
204
|
+
|
205
|
+
dependencies {
|
206
|
+
/* NOTE: Set your prefered version of jruby here. */
|
207
|
+
classpath "com.github.jruby-gradle:jruby-gradle-plugin:1.5.0"
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
apply plugin: 'com.github.jruby-gradle.base'
|
212
|
+
|
213
|
+
dependencies {
|
214
|
+
/* NOTE: Set your prefered version of twine here. */
|
215
|
+
jrubyExec 'rubygems:twine:1.0.3'
|
216
|
+
}
|
217
|
+
|
218
|
+
task generateLocalizations (type: JRubyExec) {
|
219
|
+
dependsOn jrubyPrepare
|
220
|
+
jrubyArgs '-S'
|
221
|
+
script "twine"
|
222
|
+
scriptArgs 'generate-localization-file', 'twine.txt', './src/main/res/values/generated_strings.xml'
|
223
|
+
}
|
224
|
+
|
225
|
+
preBuild {
|
226
|
+
dependsOn generateLocalizations
|
227
|
+
}
|
228
|
+
```
|
190
229
|
|
191
230
|
## User Interface
|
192
231
|
|
@@ -224,4 +263,4 @@ Many thanks to all of the contributors to the Twine project, including:
|
|
224
263
|
[djangopo]: https://docs.djangoproject.com/en/dev/topics/i18n/translation/
|
225
264
|
[tizen]: https://developer.tizen.org/documentation/articles/localization
|
226
265
|
[flash]: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#getString()
|
227
|
-
[printf]: https://en.wikipedia.org/wiki/Printf_format_string
|
266
|
+
[printf]: https://en.wikipedia.org/wiki/Printf_format_string
|
@@ -3,6 +3,8 @@ require 'fileutils'
|
|
3
3
|
module Twine
|
4
4
|
module Formatters
|
5
5
|
class Abstract
|
6
|
+
LANGUAGE_CODE_WITH_OPTIONAL_REGION_CODE = "[a-z]{2}(?:-[A-Za-z]{2})?"
|
7
|
+
|
6
8
|
attr_accessor :twine_file
|
7
9
|
attr_accessor :options
|
8
10
|
|
@@ -76,7 +78,12 @@ module Twine
|
|
76
78
|
end
|
77
79
|
|
78
80
|
def determine_language_given_path(path)
|
79
|
-
|
81
|
+
only_language_and_region = /^#{LANGUAGE_CODE_WITH_OPTIONAL_REGION_CODE}$/i
|
82
|
+
basename = File.basename(path, File.extname(path))
|
83
|
+
return basename if basename =~ only_language_and_region
|
84
|
+
return basename if @twine_file.language_codes.include? basename
|
85
|
+
|
86
|
+
path.split(File::SEPARATOR).reverse.find { |segment| segment =~ only_language_and_region }
|
80
87
|
end
|
81
88
|
|
82
89
|
def output_path_for_language(lang)
|
@@ -37,7 +37,7 @@ module Twine
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
return
|
40
|
+
return super
|
41
41
|
end
|
42
42
|
|
43
43
|
def output_path_for_language(lang)
|
@@ -56,7 +56,7 @@ module Twine
|
|
56
56
|
|
57
57
|
def read(io, lang)
|
58
58
|
document = REXML::Document.new io, :compress_whitespace => %w{ string }
|
59
|
-
|
59
|
+
document.context[:attribute_quote] = :quote
|
60
60
|
comment = nil
|
61
61
|
document.root.children.each do |child|
|
62
62
|
if child.is_a? REXML::Comment
|
@@ -13,22 +13,11 @@ module Twine
|
|
13
13
|
'strings.po'
|
14
14
|
end
|
15
15
|
|
16
|
-
def determine_language_given_path(path)
|
17
|
-
path_arr = path.split(File::SEPARATOR)
|
18
|
-
path_arr.each do |segment|
|
19
|
-
match = /([a-z]{2}(-[A-Za-z]{2})?)\.po$/.match(segment)
|
20
|
-
return match[1] if match
|
21
|
-
end
|
22
|
-
|
23
|
-
return
|
24
|
-
end
|
25
|
-
|
26
16
|
def read(io, lang)
|
27
17
|
comment_regex = /#\. *"?(.*)"?$/
|
28
18
|
key_regex = /msgid *"(.*)"$/
|
29
19
|
value_regex = /msgstr *"(.*)"$/m
|
30
20
|
|
31
|
-
last_comment = nil
|
32
21
|
while line = io.gets
|
33
22
|
comment_match = comment_regex.match(line)
|
34
23
|
if comment_match
|
@@ -15,11 +15,6 @@ module Twine
|
|
15
15
|
'resources.properties'
|
16
16
|
end
|
17
17
|
|
18
|
-
def determine_language_given_path(path)
|
19
|
-
# match two-letter language code, optionally followed by a two letter region code
|
20
|
-
path.split(File::SEPARATOR).reverse.find { |segment| segment =~ /^([a-z]{2}(-[a-z]{2})?)$/i }
|
21
|
-
end
|
22
|
-
|
23
18
|
def set_translation_for_key(key, lang, value)
|
24
19
|
value = convert_placeholders_from_flash_to_twine(value)
|
25
20
|
super(key, lang, value)
|
@@ -15,16 +15,6 @@ module Twine
|
|
15
15
|
'strings.po'
|
16
16
|
end
|
17
17
|
|
18
|
-
def determine_language_given_path(path)
|
19
|
-
path_arr = path.split(File::SEPARATOR)
|
20
|
-
path_arr.each do |segment|
|
21
|
-
match = /([a-z]{2}(-[A-Za-z]{2})?)\.po$/.match(segment)
|
22
|
-
return match[1] if match
|
23
|
-
end
|
24
|
-
|
25
|
-
return
|
26
|
-
end
|
27
|
-
|
28
18
|
def read(io, lang)
|
29
19
|
comment_regex = /#.? *"(.*)"$/
|
30
20
|
key_regex = /msgctxt *"(.*)"$/
|
@@ -65,7 +55,7 @@ module Twine
|
|
65
55
|
end
|
66
56
|
|
67
57
|
def format_header(lang)
|
68
|
-
"msgid \"\"\nmsgstr \"\"\n\"Language: #{lang}
|
58
|
+
"msgid \"\"\nmsgstr \"\"\n\"Language: #{lang}\"\n\"X-Generator: Twine #{Twine::VERSION}\"\n"
|
69
59
|
end
|
70
60
|
|
71
61
|
def format_section_header(section)
|
@@ -86,15 +76,15 @@ module Twine
|
|
86
76
|
end
|
87
77
|
|
88
78
|
def format_key(key)
|
89
|
-
"msgctxt \"#{key}\"\n"
|
79
|
+
"msgctxt \"#{escape_quotes(key)}\"\n"
|
90
80
|
end
|
91
81
|
|
92
82
|
def format_base_translation(definition)
|
93
|
-
"msgid \"#{definition.translations[@default_lang]}\"\n"
|
83
|
+
"msgid \"#{escape_quotes(definition.translations[@default_lang])}\"\n"
|
94
84
|
end
|
95
85
|
|
96
86
|
def format_value(value)
|
97
|
-
"msgstr \"#{value}\"\n"
|
87
|
+
"msgstr \"#{escape_quotes(value)}\"\n"
|
98
88
|
end
|
99
89
|
end
|
100
90
|
end
|
@@ -14,22 +14,17 @@ module Twine
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def determine_language_given_path(path)
|
17
|
-
|
18
|
-
|
19
|
-
match = /^((.+)-)?([^-]+)\.json$/.match(segment)
|
20
|
-
if match
|
21
|
-
return match[3]
|
22
|
-
end
|
23
|
-
end
|
17
|
+
match = /^.+-([^-]{2})\.json$/.match File.basename(path)
|
18
|
+
return match[1] if match
|
24
19
|
|
25
|
-
return
|
20
|
+
return super
|
26
21
|
end
|
27
22
|
|
28
23
|
def read(io, lang)
|
29
24
|
begin
|
30
25
|
require "json"
|
31
26
|
rescue LoadError
|
32
|
-
raise Twine::Error.new "You must run
|
27
|
+
raise Twine::Error.new "You must run `gem install json` in order to read or write jquery-localize files."
|
33
28
|
end
|
34
29
|
|
35
30
|
json = JSON.load(io)
|
@@ -46,7 +41,7 @@ module Twine
|
|
46
41
|
|
47
42
|
def format_sections(twine_file, lang)
|
48
43
|
sections = twine_file.sections.map { |section| format_section(section, lang) }
|
49
|
-
sections.delete_if
|
44
|
+
sections.delete_if(&:empty?)
|
50
45
|
sections.join(",\n\n")
|
51
46
|
end
|
52
47
|
|
data/lib/twine/plugin.rb
CHANGED
data/lib/twine/runner.rb
CHANGED
@@ -87,7 +87,7 @@ module Twine
|
|
87
87
|
end
|
88
88
|
|
89
89
|
unless formatter
|
90
|
-
raise Twine::Error.new "Could not determine format given the contents of #{@options[:output_path]}"
|
90
|
+
raise Twine::Error.new "Could not determine format given the contents of #{@options[:output_path]}. Try using `--format`."
|
91
91
|
end
|
92
92
|
|
93
93
|
file_name = @options[:file_name] || formatter.default_file_name
|
@@ -294,21 +294,16 @@ module Twine
|
|
294
294
|
end
|
295
295
|
end
|
296
296
|
|
297
|
-
def determine_language_given_path(path)
|
298
|
-
code = File.basename(path, File.extname(path))
|
299
|
-
return code if @twine_file.language_codes.include? code
|
300
|
-
end
|
301
|
-
|
302
297
|
def formatter_for_format(format)
|
303
298
|
find_formatter { |f| f.format_name == format }
|
304
299
|
end
|
305
300
|
|
306
301
|
def find_formatter(&block)
|
307
|
-
formatters = Formatters.formatters.select
|
302
|
+
formatters = Formatters.formatters.select(&block)
|
308
303
|
if formatters.empty?
|
309
304
|
return nil
|
310
305
|
elsif formatters.size > 1
|
311
|
-
raise Twine::Error.new("Unable to determine format. Candidates are: #{formatters.map(&:format_name).join(', ')}. Please specify the format you want using
|
306
|
+
raise Twine::Error.new("Unable to determine format. Candidates are: #{formatters.map(&:format_name).join(', ')}. Please specify the format you want using `--format`")
|
312
307
|
end
|
313
308
|
formatter = formatters.first
|
314
309
|
formatter.twine_file = @twine_file
|
@@ -339,12 +334,12 @@ module Twine
|
|
339
334
|
end
|
340
335
|
|
341
336
|
unless formatter
|
342
|
-
raise Twine::Error.new "Unable to determine format of #{path}"
|
337
|
+
raise Twine::Error.new "Unable to determine format of #{path}. Try using `--format`."
|
343
338
|
end
|
344
339
|
|
345
|
-
lang = lang ||
|
340
|
+
lang = lang || formatter.determine_language_given_path(path)
|
346
341
|
unless lang
|
347
|
-
raise Twine::Error.new "Unable to determine language for #{path}"
|
342
|
+
raise Twine::Error.new "Unable to determine language for #{path}. Try using `--lang`."
|
348
343
|
end
|
349
344
|
|
350
345
|
@twine_file.language_codes << lang unless @twine_file.language_codes.include? lang
|
data/lib/twine/version.rb
CHANGED
data/test/test_cli.rb
CHANGED
data/test/test_formatters.rb
CHANGED
@@ -116,6 +116,21 @@ class TestAndroidFormatter < FormatterTest
|
|
116
116
|
assert_equal 'Hello, <b>BOLD</b>', @empty_twine_file.definitions_by_key["foo"].translations['en']
|
117
117
|
end
|
118
118
|
|
119
|
+
def test_double_quotes_are_not_modified
|
120
|
+
content = <<-EOCONTENT
|
121
|
+
<?xml version="1.0" encoding="utf-8"?>
|
122
|
+
<resources>
|
123
|
+
<string name="foo">Hello, <a href="http://www.foo.com">BOLD</a></string>
|
124
|
+
</resources>
|
125
|
+
EOCONTENT
|
126
|
+
|
127
|
+
io = StringIO.new(content)
|
128
|
+
|
129
|
+
@formatter.read io, 'en'
|
130
|
+
|
131
|
+
assert_equal 'Hello, <a href="http://www.foo.com">BOLD</a>', @empty_twine_file.definitions_by_key["foo"].translations['en']
|
132
|
+
end
|
133
|
+
|
119
134
|
def test_set_translation_converts_leading_spaces
|
120
135
|
@formatter.set_translation_for_key 'key1', 'en', "\u0020value"
|
121
136
|
assert_equal ' value', @empty_twine_file.definitions_by_key['key1'].translations['en']
|
@@ -180,8 +195,24 @@ class TestAndroidFormatter < FormatterTest
|
|
180
195
|
assert_equal identifier, @formatter.format_value(identifier)
|
181
196
|
end
|
182
197
|
|
198
|
+
def test_deducts_language_from_filename
|
199
|
+
language = KNOWN_LANGUAGES.sample
|
200
|
+
assert_equal language, @formatter.determine_language_given_path("#{language}.xml")
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_recognize_every_twine_language_from_filename
|
204
|
+
twine_file = build_twine_file "not-a-lang-code" do
|
205
|
+
add_section "Section" do
|
206
|
+
add_definition key: "value"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
@formatter.twine_file = twine_file
|
211
|
+
assert_equal "not-a-lang-code", @formatter.determine_language_given_path("not-a-lang-code.xml")
|
212
|
+
end
|
213
|
+
|
183
214
|
def test_deducts_language_from_resource_folder
|
184
|
-
language =
|
215
|
+
language = KNOWN_LANGUAGES.sample
|
185
216
|
assert_equal language, @formatter.determine_language_given_path("res/values-#{language}")
|
186
217
|
end
|
187
218
|
|
@@ -213,6 +244,22 @@ class TestAppleFormatter < FormatterTest
|
|
213
244
|
assert_file_contents_read_correctly
|
214
245
|
end
|
215
246
|
|
247
|
+
def test_deducts_language_from_filename
|
248
|
+
language = KNOWN_LANGUAGES.sample
|
249
|
+
assert_equal language, @formatter.determine_language_given_path("#{language}.strings")
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_recognize_every_twine_language_from_filename
|
253
|
+
twine_file = build_twine_file "not-a-lang-code" do
|
254
|
+
add_section "Section" do
|
255
|
+
add_definition key: "value"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
@formatter.twine_file = twine_file
|
260
|
+
assert_equal "not-a-lang-code", @formatter.determine_language_given_path("not-a-lang-code.strings")
|
261
|
+
end
|
262
|
+
|
216
263
|
def test_deducts_language_from_resource_folder
|
217
264
|
language = %w(en de fr).sample
|
218
265
|
assert_equal language, @formatter.determine_language_given_path("#{language}.lproj/Localizable.strings")
|
@@ -317,6 +364,21 @@ class TestJQueryFormatter < FormatterTest
|
|
317
364
|
def test_format_value_with_newline
|
318
365
|
assert_equal "value\nwith\nline\nbreaks", @formatter.format_value("value\nwith\nline\nbreaks")
|
319
366
|
end
|
367
|
+
|
368
|
+
def test_deducts_language_from_filename
|
369
|
+
language = KNOWN_LANGUAGES.sample
|
370
|
+
assert_equal language, @formatter.determine_language_given_path("#{language}.json")
|
371
|
+
end
|
372
|
+
|
373
|
+
def test_deducts_language_from_extended_filename
|
374
|
+
language = KNOWN_LANGUAGES.sample
|
375
|
+
assert_equal language, @formatter.determine_language_given_path("something-#{language}.json")
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_deducts_language_from_path
|
379
|
+
language = %w(en-GB de fr).sample
|
380
|
+
assert_equal language, @formatter.determine_language_given_path("/output/#{language}/#{@formatter.default_file_name}")
|
381
|
+
end
|
320
382
|
end
|
321
383
|
|
322
384
|
class TestGettextFormatter < FormatterTest
|
@@ -346,6 +408,21 @@ class TestGettextFormatter < FormatterTest
|
|
346
408
|
language = "en-GB"
|
347
409
|
assert_equal language, @formatter.determine_language_given_path("#{language}.po")
|
348
410
|
end
|
411
|
+
|
412
|
+
def test_deducts_language_from_path
|
413
|
+
language = %w(en-GB de fr).sample
|
414
|
+
assert_equal language, @formatter.determine_language_given_path("/output/#{language}/#{@formatter.default_file_name}")
|
415
|
+
end
|
416
|
+
|
417
|
+
def test_quoted_strings
|
418
|
+
formatter = Twine::Formatters::Gettext.new
|
419
|
+
formatter.twine_file = build_twine_file "not-a-lang-code" do
|
420
|
+
add_section "Section" do
|
421
|
+
add_definition key: "foo \"bar\" baz"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
assert_equal content('formatter_gettext_quotes.po'), formatter.format_file('en')
|
425
|
+
end
|
349
426
|
end
|
350
427
|
|
351
428
|
class TestTizenFormatter < FormatterTest
|
@@ -366,7 +443,6 @@ class TestTizenFormatter < FormatterTest
|
|
366
443
|
formatter.twine_file = @twine_file
|
367
444
|
assert_equal content('formatter_tizen.xml'), formatter.format_file('en')
|
368
445
|
end
|
369
|
-
|
370
446
|
end
|
371
447
|
|
372
448
|
class TestDjangoFormatter < FormatterTest
|
@@ -390,6 +466,11 @@ class TestDjangoFormatter < FormatterTest
|
|
390
466
|
language = "en-GB"
|
391
467
|
assert_equal language, @formatter.determine_language_given_path("#{language}.po")
|
392
468
|
end
|
469
|
+
|
470
|
+
def test_deducts_language_from_path
|
471
|
+
language = %w(en-GB de fr).sample
|
472
|
+
assert_equal language, @formatter.determine_language_given_path("/output/#{language}/#{@formatter.default_file_name}")
|
473
|
+
end
|
393
474
|
end
|
394
475
|
|
395
476
|
class TestFlashFormatter < FormatterTest
|
@@ -420,10 +501,10 @@ class TestFlashFormatter < FormatterTest
|
|
420
501
|
|
421
502
|
def test_deducts_language_from_resource_folder
|
422
503
|
language = %w(en de fr).sample
|
423
|
-
assert_equal language, @formatter.determine_language_given_path("locale/#{language}")
|
504
|
+
assert_equal language, @formatter.determine_language_given_path("locale/#{language}/#{@formatter.default_file_name}")
|
424
505
|
end
|
425
506
|
|
426
507
|
def test_deducts_language_and_region_from_resource_folder
|
427
|
-
assert_equal 'de-AT', @formatter.determine_language_given_path("locale/de-AT")
|
508
|
+
assert_equal 'de-AT', @formatter.determine_language_given_path("locale/de-AT/#{@formatter.default_file_name}")
|
428
509
|
end
|
429
510
|
end
|
@@ -24,10 +24,6 @@ class TestGenerateAllLocalizationFiles < CommandTest
|
|
24
24
|
def setup
|
25
25
|
super
|
26
26
|
Dir.mkdir File.join @output_dir, 'values-en'
|
27
|
-
|
28
|
-
# both Android and Tizen can handle folders containing `values-en`
|
29
|
-
android_formatter = prepare_mock_formatter(Twine::Formatters::Android)
|
30
|
-
tizen_formatter = prepare_mock_formatter(Twine::Formatters::Tizen, false)
|
31
27
|
end
|
32
28
|
|
33
29
|
def new_runner(options = {})
|
@@ -60,7 +56,7 @@ class TestGenerateAllLocalizationFiles < CommandTest
|
|
60
56
|
def test_does_not_create_language_folders
|
61
57
|
Dir.mkdir File.join @output_dir, 'en.lproj'
|
62
58
|
new_runner.generate_all_localization_files
|
63
|
-
refute File.
|
59
|
+
refute File.exist?(File.join(@output_dir, 'es.lproj')), "language folder should not be created"
|
64
60
|
end
|
65
61
|
|
66
62
|
def test_prints_empty_file_warnings
|
@@ -86,13 +82,13 @@ class TestGenerateAllLocalizationFiles < CommandTest
|
|
86
82
|
def test_creates_output_folder
|
87
83
|
FileUtils.remove_entry_secure @output_dir
|
88
84
|
new_runner.generate_all_localization_files
|
89
|
-
assert File.
|
85
|
+
assert File.exist? @output_dir
|
90
86
|
end
|
91
87
|
|
92
88
|
def test_creates_language_folders
|
93
89
|
new_runner.generate_all_localization_files
|
94
|
-
assert File.
|
95
|
-
assert File.
|
90
|
+
assert File.exist?(File.join(@output_dir, 'en.lproj')), "language folder 'en.lproj' should be created"
|
91
|
+
assert File.exist?(File.join(@output_dir, 'es.lproj')), "language folder 'es.lproj' should be created"
|
96
92
|
end
|
97
93
|
|
98
94
|
def test_prints_empty_file_warnings
|
@@ -19,7 +19,7 @@ class TestGenerateLocalizationArchive < CommandTest
|
|
19
19
|
def test_generates_zip_file
|
20
20
|
new_runner.generate_localization_archive
|
21
21
|
|
22
|
-
assert File.
|
22
|
+
assert File.exist?(@output_path), "zip file should exist"
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_zip_file_structure
|
data/test/twine_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'minitest/autorun'
|
3
|
-
require "mocha/
|
3
|
+
require "mocha/minitest"
|
4
4
|
require 'securerandom'
|
5
5
|
require 'stringio'
|
6
6
|
require 'twine'
|
@@ -23,7 +23,7 @@ class TwineTest < Minitest::Test
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def teardown
|
26
|
-
FileUtils.remove_entry_secure @output_dir if File.
|
26
|
+
FileUtils.remove_entry_secure @output_dir if File.exist? @output_dir
|
27
27
|
Twine::Formatters.formatters.clear
|
28
28
|
Twine::Formatters.formatters.concat @formatters
|
29
29
|
super
|
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Celis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: safe_yaml
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '10.4'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.4'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '5.5'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '5.5'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest-ci
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '3.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: mocha
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '1.1'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.1'
|
97
97
|
description: |2
|
@@ -105,58 +105,59 @@ extensions: []
|
|
105
105
|
extra_rdoc_files: []
|
106
106
|
files:
|
107
107
|
- Gemfile
|
108
|
-
- README.md
|
109
108
|
- LICENSE
|
109
|
+
- README.md
|
110
|
+
- bin/twine
|
110
111
|
- lib/twine.rb
|
111
|
-
- lib/twine/
|
112
|
-
- lib/twine/
|
112
|
+
- lib/twine/cli.rb
|
113
|
+
- lib/twine/encoding.rb
|
114
|
+
- lib/twine/formatters.rb
|
115
|
+
- lib/twine/formatters/abstract.rb
|
116
|
+
- lib/twine/formatters/android.rb
|
113
117
|
- lib/twine/formatters/apple.rb
|
114
|
-
- lib/twine/formatters/
|
118
|
+
- lib/twine/formatters/django.rb
|
115
119
|
- lib/twine/formatters/flash.rb
|
116
|
-
- lib/twine/formatters/android.rb
|
117
|
-
- lib/twine/formatters/tizen.rb
|
118
120
|
- lib/twine/formatters/gettext.rb
|
119
|
-
- lib/twine/formatters/
|
120
|
-
- lib/twine/formatters/
|
121
|
-
- lib/twine/cli.rb
|
122
|
-
- lib/twine/twine_file.rb
|
123
|
-
- lib/twine/encoding.rb
|
121
|
+
- lib/twine/formatters/jquery.rb
|
122
|
+
- lib/twine/formatters/tizen.rb
|
124
123
|
- lib/twine/output_processor.rb
|
125
|
-
- lib/twine/
|
126
|
-
- lib/twine/
|
124
|
+
- lib/twine/placeholders.rb
|
125
|
+
- lib/twine/plugin.rb
|
127
126
|
- lib/twine/runner.rb
|
128
|
-
-
|
129
|
-
-
|
130
|
-
- test/test_output_processor.rb
|
131
|
-
- test/test_consume_localization_file.rb
|
132
|
-
- test/test_consume_localization_archive.rb
|
133
|
-
- test/test_abstract_formatter.rb
|
134
|
-
- test/test_cli.rb
|
135
|
-
- test/test_twine_file.rb
|
136
|
-
- test/test_generate_localization_file.rb
|
137
|
-
- test/test_generate_all_localization_files.rb
|
138
|
-
- test/twine_test.rb
|
139
|
-
- test/test_generate_localization_archive.rb
|
127
|
+
- lib/twine/twine_file.rb
|
128
|
+
- lib/twine/version.rb
|
140
129
|
- test/command_test.rb
|
141
|
-
- test/
|
142
|
-
- test/
|
143
|
-
- test/fixtures/formatter_apple.strings
|
130
|
+
- test/fixtures/consume_localization_archive.zip
|
131
|
+
- test/fixtures/enc_utf16be.dummy
|
144
132
|
- test/fixtures/enc_utf16be_bom.dummy
|
145
|
-
- test/fixtures/
|
133
|
+
- test/fixtures/enc_utf16le.dummy
|
134
|
+
- test/fixtures/enc_utf16le_bom.dummy
|
146
135
|
- test/fixtures/enc_utf8.dummy
|
147
136
|
- test/fixtures/formatter_android.xml
|
148
|
-
- test/fixtures/
|
149
|
-
- test/fixtures/twine_accent_values.txt
|
150
|
-
- test/fixtures/enc_utf16be.dummy
|
137
|
+
- test/fixtures/formatter_apple.strings
|
151
138
|
- test/fixtures/formatter_django.po
|
152
|
-
- test/fixtures/enc_utf16le.dummy
|
153
|
-
- test/fixtures/formatter_tizen.xml
|
154
|
-
- test/fixtures/formatter_jquery.json
|
155
|
-
- test/fixtures/formatter_gettext.po
|
156
139
|
- test/fixtures/formatter_flash.properties
|
157
|
-
- test/fixtures/
|
140
|
+
- test/fixtures/formatter_gettext.po
|
141
|
+
- test/fixtures/formatter_gettext_quotes.po
|
142
|
+
- test/fixtures/formatter_jquery.json
|
143
|
+
- test/fixtures/formatter_tizen.xml
|
144
|
+
- test/fixtures/gettext_multiline.po
|
145
|
+
- test/fixtures/twine_accent_values.txt
|
146
|
+
- test/test_abstract_formatter.rb
|
147
|
+
- test/test_cli.rb
|
148
|
+
- test/test_consume_localization_archive.rb
|
149
|
+
- test/test_consume_localization_file.rb
|
150
|
+
- test/test_formatters.rb
|
151
|
+
- test/test_generate_all_localization_files.rb
|
152
|
+
- test/test_generate_localization_archive.rb
|
153
|
+
- test/test_generate_localization_file.rb
|
154
|
+
- test/test_output_processor.rb
|
158
155
|
- test/test_placeholders.rb
|
156
|
+
- test/test_twine_definition.rb
|
157
|
+
- test/test_twine_file.rb
|
159
158
|
- test/test_validate_twine_file.rb
|
159
|
+
- test/twine_file_dsl.rb
|
160
|
+
- test/twine_test.rb
|
160
161
|
homepage: https://github.com/mobiata/twine
|
161
162
|
licenses:
|
162
163
|
- BSD-3-Clause
|
@@ -167,17 +168,16 @@ require_paths:
|
|
167
168
|
- lib
|
168
169
|
required_ruby_version: !ruby/object:Gem::Requirement
|
169
170
|
requirements:
|
170
|
-
- -
|
171
|
+
- - ">="
|
171
172
|
- !ruby/object:Gem::Version
|
172
173
|
version: '2.0'
|
173
174
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
175
|
requirements:
|
175
|
-
- -
|
176
|
+
- - ">="
|
176
177
|
- !ruby/object:Gem::Version
|
177
178
|
version: '0'
|
178
179
|
requirements: []
|
179
|
-
|
180
|
-
rubygems_version: 2.0.14.1
|
180
|
+
rubygems_version: 3.0.1
|
181
181
|
signing_key:
|
182
182
|
specification_version: 4
|
183
183
|
summary: Manage strings and their translations for your iOS, Android and other projects.
|