translations 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ # Ignore project files
2
+ .idea
3
+ *.iml
4
+
5
+ # Ignore build artifacts
6
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-1.9.3-p385@translations
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in translations.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ translations (0.0.1)
5
+ thor (~> 0.17.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.3)
11
+ predicated (0.2.6)
12
+ rspec (2.12.0)
13
+ rspec-core (~> 2.12.0)
14
+ rspec-expectations (~> 2.12.0)
15
+ rspec-mocks (~> 2.12.0)
16
+ rspec-core (2.12.2)
17
+ rspec-expectations (2.12.1)
18
+ diff-lcs (~> 1.1.3)
19
+ rspec-mocks (2.12.2)
20
+ ruby2ruby (2.0.3)
21
+ ruby_parser (~> 3.1)
22
+ sexp_processor (~> 4.0)
23
+ ruby_parser (3.1.1)
24
+ sexp_processor (~> 4.1)
25
+ sexp_processor (4.1.4)
26
+ thor (0.17.0)
27
+ wrong (0.7.0)
28
+ diff-lcs (~> 1.1.2)
29
+ predicated (~> 0.2.6)
30
+ ruby2ruby (>= 2.0.1)
31
+ ruby_parser (>= 3.0.1)
32
+ sexp_processor (>= 4.0)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ rspec (~> 2.12.0)
39
+ translations!
40
+ wrong (~> 0.7.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Marten Lienen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ Translations
2
+ ============
3
+
4
+ Edit your translation files in a synchronized way.
5
+
6
+
7
+ Naming
8
+ ------
9
+
10
+ 1. One translation is your `master`. This file is always complete and serves as a reference for the `slaves`.
11
+ 2. All translations that are not `master` are `slave`s. This means that they may not be up-to-date and can be synchronized
12
+ with the master using `translate`.
13
+
14
+ The default master is `en`, but you may alter it using the `-m <locale>` switch.
15
+
16
+
17
+ Usage
18
+ -----
19
+
20
+ Currently there are 6 commands to alter your translation files:
21
+
22
+ - `add`: Add a new key to all your files
23
+ - `update`: Update a key in a single file
24
+ - `change`: Change the meaning of a key in a way that requires a re-translation for all locales
25
+ - `move`: Move a key around
26
+ - `remove`: Remove a key from all files
27
+ - `translate`: Translate all keys that are missing from a given file
28
+
29
+ For more info just run `translations help <command>`.
30
+
31
+
32
+ Requirements
33
+ ------------
34
+
35
+ - All your translations are stored in YAML format and one file per locale called `<locale>.yml`
36
+ - Optimally you work in a rails project, e.g. your translations are stored in `config/locales`, but you may alter this location with `-d <directory>`
37
+ - Optimally you have a master
38
+
39
+
40
+ Missing/Coming Features
41
+ ----------------
42
+
43
+ The following features (or whatever comes to your mind) will probably be implemented in the next time:
44
+
45
+ - Support for Pluralizations
46
+ - Support for [Cascading](http://svenfuchs.com/2011/2/11/organizing-translations-with-i18n-cascade-and-i18n-missingtranslations)
47
+
48
+
49
+ Installation
50
+ ------------
51
+
52
+ Add this line to your application's Gemfile:
53
+
54
+ gem 'translations'
55
+
56
+ And then execute:
57
+
58
+ $ bundle
59
+
60
+ Or install it yourself as:
61
+
62
+ $ gem install translations
63
+
64
+
65
+ Contributing
66
+ ------------
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/translations ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "bundler/setup"
4
+ require "translations/cli"
5
+
6
+ Translations::CLI.start
@@ -0,0 +1,5 @@
1
+ require "translations/version"
2
+
3
+ module Translations
4
+
5
+ end
@@ -0,0 +1,147 @@
1
+ require "thor"
2
+
3
+ require "translations/serializer"
4
+
5
+ module Translations
6
+ class CLI < Thor
7
+ class_option :directory, aliases: ["-d"], default: "config/locales", type: :string, desc: "Directory containing the translations"
8
+ class_option :master, aliases: ["-m"], default: "en", type: :string, desc: "The master locale"
9
+
10
+ desc "translate LOCALE [KEYS]", "Translate the KEYS into the given LOCALE"
11
+ long_desc <<-DESC
12
+ Translate KEYS from the master to LOCALE. If you omit KEYS it will instead ask you to translate all keys that exist
13
+ in master but not in LOCALE.
14
+ DESC
15
+ def translate locale, *keys
16
+ translations = serializer.translations
17
+
18
+ translation = translations.for_locale(locale)
19
+
20
+ if keys.length == 0
21
+ keys = translation.missing_keys_from_translation(translations.master)
22
+ end
23
+
24
+ master = translations.master
25
+
26
+ keys.each do |key|
27
+ say key
28
+ say "#{master.locale}: #{master[key]}"
29
+
30
+ translations.slaves.each do |translation|
31
+ answer = ask "#{translation.locale}?"
32
+
33
+ if answer.length > 0
34
+ translation[key] = answer
35
+ end
36
+
37
+ puts
38
+
39
+ serializer.save translations
40
+ end
41
+ end
42
+ end
43
+
44
+ desc "remove KEYS", "Remove KEYS from all locales"
45
+ def remove *keys
46
+ translations = serializer.translations
47
+
48
+ keys.each do |key|
49
+ translations.remove key
50
+ end
51
+
52
+ serializer.save translations
53
+ end
54
+
55
+ desc "move FROM TO", "Move a translation from FROM to TO"
56
+ def move from, to
57
+ translations = serializer.translations
58
+
59
+ translations.move from, to
60
+
61
+ serializer.save translations
62
+ end
63
+
64
+ desc "add KEY", "Add a new KEY to all translations"
65
+ long_desc <<-DESC
66
+ Add a key and provide translations for as many locales as you can.
67
+ DESC
68
+ def add key
69
+ translations = serializer.translations
70
+
71
+ answer = ask "#{translations.master.locale}?"
72
+
73
+ if answer.length > 0
74
+ translations.master[key] = answer
75
+ else
76
+ say "You have to provide a translation for master"
77
+
78
+ return
79
+ end
80
+
81
+ translations.slaves.each do |translation|
82
+ answer = ask "#{translation.locale}?"
83
+
84
+ if answer.length > 0
85
+ translation[key] = answer
86
+ end
87
+ end
88
+
89
+ serializer.save translations
90
+ end
91
+
92
+ desc "change KEY", "Change the meaning of KEY"
93
+ long_desc <<-DESC
94
+ Changes the meaning of KEY in a way that requires re-translation to all locales. Therefore the key will be removed
95
+ from all locales for which you cannot provide a translation, so that it can be fixed using the translate command.
96
+ DESC
97
+ def change key
98
+ translations = serializer.translations
99
+
100
+ say "#{translations.master.locale}: #{translations.master[key]}"
101
+ answer = ask "#{translations.master.locale}?"
102
+
103
+ if answer.length > 0
104
+ translations.master[key] = answer
105
+ else
106
+ say "You have to provide a translation for master"
107
+
108
+ return
109
+ end
110
+
111
+ translations.slaves.each do |translation|
112
+ say "#{translation.locale}: #{translation[key]}"
113
+ answer = ask "#{translation.locale}?"
114
+
115
+ if answer.length > 0
116
+ translation[key] = answer
117
+ else
118
+ translation.remove key
119
+ end
120
+ end
121
+
122
+ serializer.save translations
123
+ end
124
+
125
+ desc "update LOCALE KEY", "Update KEY in a specific LOCALE without changing it's meaning"
126
+ long_desc <<-DESC
127
+ Just update KEY in LOCALE without altering any other locales.
128
+ DESC
129
+ def update locale, key
130
+ translations = serializer.translations
131
+ translation = translations.for_locale(locale)
132
+
133
+ say "#{locale}: #{translation[key]}"
134
+ answer = ask "#{locale}?"
135
+
136
+ translation[key] = answer
137
+
138
+ serializer.save translations
139
+ end
140
+
141
+ no_tasks do
142
+ def serializer
143
+ @serializer ||= Serializer.new options.directory, options.master
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,22 @@
1
+ require "translations/translation_collection"
2
+
3
+ module Translations
4
+ class Serializer
5
+ def initialize directory, master
6
+ @directory = directory
7
+ @master = master
8
+ end
9
+
10
+ def translations
11
+ TranslationCollection.new Dir["#{@directory}/*"].map { |file| Translation.new YAML.load_file(file) }, @master
12
+ end
13
+
14
+ def save translations
15
+ translations.each do |translation|
16
+ File.open File.join(@directory, "#{translation.locale}.yml"), "w" do |file|
17
+ file.write translation.to_hash.to_yaml
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,94 @@
1
+ module Translations
2
+ class Translation
3
+ class InvalidKeyException < ArgumentError
4
+
5
+ end
6
+
7
+ attr_reader :locale
8
+
9
+ def initialize translations
10
+ @locale = translations.keys.first
11
+ @translations = translations[@locale]
12
+ end
13
+
14
+ def keys
15
+ keys_of_nested_hash @translations
16
+ end
17
+
18
+ def missing_keys_from_translation translation
19
+ translation.keys - keys
20
+ end
21
+
22
+ def has_key? key
23
+ translation = key.split(".").inject(@translations) do |translation, key|
24
+ if translation.nil?
25
+ nil
26
+ else
27
+ translation[key]
28
+ end
29
+ end
30
+
31
+ translation != nil
32
+ end
33
+
34
+ def [] key
35
+ key.split(".").inject(@translations) do |translation, key|
36
+ if translation.nil?
37
+ raise InvalidKeyException
38
+ else
39
+ translation[key]
40
+ end
41
+ end
42
+ end
43
+
44
+ def []= key, value
45
+ parts = key.split(".")
46
+
47
+ hash = parts.slice(0, parts.length - 1).inject(@translations) do |translation, key|
48
+ if !translation.has_key? key
49
+ translation[key] = { }
50
+ end
51
+
52
+ if !translation[key].is_a? Hash
53
+ translation[key] = { }
54
+ end
55
+
56
+ translation[key]
57
+ end
58
+
59
+ hash[parts.last] = value
60
+ end
61
+
62
+ def remove key
63
+ parts = key.split(".")
64
+ last_part = parts.pop
65
+
66
+ parent = parts.inject(@translations) do |translation, key|
67
+ translation[key]
68
+ end
69
+
70
+ parent.delete last_part
71
+ end
72
+
73
+ def move from, to
74
+ self[to] = self[from]
75
+
76
+ remove from
77
+ end
78
+
79
+ def to_hash
80
+ { @locale => @translations }
81
+ end
82
+
83
+ private
84
+ def keys_of_nested_hash hash
85
+ hash.map do |key, value|
86
+ if value.is_a? Hash
87
+ keys_of_nested_hash(value).map { |nested_key| "#{key}.#{nested_key}" }
88
+ else
89
+ key
90
+ end
91
+ end.flatten 1
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,34 @@
1
+ require "translations/translation"
2
+
3
+ module Translations
4
+ class TranslationCollection
5
+ include Enumerable
6
+
7
+ attr_reader :master
8
+
9
+ def initialize translations, master
10
+ @translations = translations
11
+ @master = @translations.select { |translation| translation.locale == master }.first
12
+ end
13
+
14
+ def each
15
+ @translations.each { |translation| yield translation }
16
+ end
17
+
18
+ def for_locale locale
19
+ @translations.select { |translation| translation.locale == locale }.first
20
+ end
21
+
22
+ def slaves
23
+ @translations.reject { |translation| translation == master }
24
+ end
25
+
26
+ def remove key
27
+ @translations.each { |translation| translation.remove key }
28
+ end
29
+
30
+ def move from, to
31
+ @translations.each { |translation| translation.move from, to }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Translations
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,2 @@
1
+ de:
2
+ save: 'Speichern'
@@ -0,0 +1,6 @@
1
+ en:
2
+ save: 'Save'
3
+ buttons:
4
+ add: 'Add'
5
+ save: 'Save'
6
+ delete: 'Delete'
@@ -0,0 +1,2 @@
1
+ de:
2
+ save: 'Speichern'
@@ -0,0 +1,2 @@
1
+ en:
2
+ save: 'Save'
@@ -0,0 +1 @@
1
+ require "wrong/adapters/rspec"
@@ -0,0 +1,76 @@
1
+ require "translations/serializer"
2
+
3
+ describe Translations::Serializer do
4
+ describe "#translations" do
5
+ let(:serializer) { Translations::Serializer.new("spec/fixtures/working", "en") }
6
+
7
+ it "should parse YAML files into a TranslationCollection" do
8
+ assert { serializer.translations.is_a? Translations::TranslationCollection }
9
+ end
10
+
11
+ it "should create a translation for every found locale" do
12
+ locales = serializer.translations.map(&:locale)
13
+
14
+ assert { locales.== ["en", "de"] }
15
+ end
16
+
17
+ it "should set the master correctly" do
18
+ assert { serializer.translations.master.locale == "en" }
19
+ end
20
+ end
21
+
22
+ describe "#save" do
23
+ before :each do
24
+ if File.exists? "/tmp/de.yml"
25
+ File.delete "/tmp/de.yml"
26
+ end
27
+ end
28
+
29
+ it "should write the YAML serialization of the translations into the files" do
30
+ translation = Translations::Translation.new({
31
+ "de" => {
32
+ "save" => "Speichern"
33
+ }
34
+ })
35
+
36
+ translations = Translations::TranslationCollection.new [translation], "de"
37
+
38
+ serializer = Translations::Serializer.new "/tmp/", "de"
39
+
40
+ serializer.save translations
41
+
42
+ assert { File.exists?("/tmp/de.yml") }
43
+ end
44
+
45
+ it "should output the keys in alphabetical order" do
46
+ translations_hash = {
47
+ "en" => {
48
+ "animals" => {
49
+ "mammals" => {
50
+ "elephant" => "Elephant",
51
+ "human" => "Human"
52
+ },
53
+ "fish" => {
54
+ "trout" => "Trout",
55
+ "bass" => "Bass",
56
+ "mackerel" => "Mackerel"
57
+ }
58
+ },
59
+ "actions" => {
60
+ "save" => "Save",
61
+ "add" => "Add",
62
+ "delete" => "Delete"
63
+ }
64
+ }
65
+ }
66
+
67
+ translation = Translations::Translation.new(translations_hash)
68
+ translations = Translations::TranslationCollection.new [translation], "en"
69
+ serializer = Translations::Serializer.new "/tmp/", "en"
70
+
71
+ serializer.save translations
72
+
73
+ assert { YAML.load_file("/tmp/en.yml") == translations_hash }
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,47 @@
1
+ require "translations/translation_collection"
2
+
3
+ describe Translations::TranslationCollection do
4
+ let(:translation_de) { Translations::Translation.new({ "de" => { "save" => "Speichern" } }) }
5
+ let(:translation_en) { Translations::Translation.new({ "en" => { "save" => "Save" } }) }
6
+ let(:translations) { Translations::TranslationCollection.new [translation_de, translation_en], "en" }
7
+
8
+ it "should be Enumerable" do
9
+ enumerated_translations = []
10
+
11
+ translations.each { |translation| enumerated_translations << translation }
12
+
13
+ assert { enumerated_translations == [translation_de, translation_en] }
14
+ end
15
+
16
+ it "should have a master locale" do
17
+ assert { translations.master == translation_en }
18
+ end
19
+
20
+ it "should expose all translations that are not master as slaves" do
21
+ assert { translations.slaves == [translation_de] }
22
+ end
23
+
24
+ describe "#for_locale" do
25
+ it "should return the Translation for a locale" do
26
+ assert { translations.for_locale("de") == translation_de }
27
+ end
28
+ end
29
+
30
+ describe "#remove" do
31
+ it "should remove the given key from all translations" do
32
+ translations.remove "save"
33
+
34
+ assert { translation_de.has_key?("save") == false }
35
+ assert { translation_en.has_key?("save") == false }
36
+ end
37
+ end
38
+
39
+ describe "#move" do
40
+ it "should move the key in all translations" do
41
+ translations.move "save", "x_save"
42
+
43
+ assert { translation_de["x_save"] == "Speichern" }
44
+ assert { translation_en["x_save"] == "Save" }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,119 @@
1
+ require "translations/translation"
2
+
3
+ describe Translations::Translation do
4
+ let(:translation) {
5
+ Translations::Translation.new({
6
+ "en" => {
7
+ "save" => "Save",
8
+ "buttons" => {
9
+ "delete" => "Delete",
10
+ "save" => "Save"
11
+ }
12
+ }
13
+ })
14
+ }
15
+
16
+ it "should have a locale" do
17
+ assert { translation.locale == "en" }
18
+ end
19
+
20
+ it "should be able to enumerate it's keys" do
21
+ assert { translation.keys == ["save", "buttons.delete", "buttons.save"] }
22
+ end
23
+
24
+ it "should be able to compute the missing keys when compared to another translation" do
25
+ translation_de = Translations::Translation.new({
26
+ "de" => {
27
+ "buttons" => {
28
+ "save" => "Speichern"
29
+ }
30
+ }
31
+ })
32
+
33
+ translation_de.missing_keys_from_translation(translation).should == ["save", "buttons.delete"]
34
+ end
35
+
36
+ describe "#has_key?" do
37
+ it "should return true if the key exists" do
38
+ assert { translation.has_key?("buttons.delete") == true }
39
+ end
40
+
41
+ it "should return false if the key does not exist" do
42
+ assert { translation.has_key?("key.does.not.exist") == false }
43
+ end
44
+
45
+ it "should return false if the key does not exist" do
46
+ assert { translation.has_key?("buttons.xxx") == false }
47
+ end
48
+ end
49
+
50
+ describe "#[]" do
51
+ it "should expose translations through their keys" do
52
+ assert { translation["buttons.delete"] == "Delete" }
53
+ end
54
+
55
+ it "should raise an exception if the key is not found" do
56
+ assert { rescuing { translation["key.does.not.exist"] }.is_a? Translations::Translation::InvalidKeyException }
57
+ end
58
+ end
59
+
60
+ describe "#[]=" do
61
+ it "should let you mutate translations through their keys" do
62
+ translation["buttons.delete"] = "Remove"
63
+
64
+ assert { translation["buttons.delete"] == "Remove" }
65
+ end
66
+
67
+ it "should let you create new translations using keys" do
68
+ translation = Translations::Translation.new({
69
+ "en" => { }
70
+ })
71
+
72
+ translation["buttons.delete"] = "Delete"
73
+
74
+ assert { translation["buttons.delete"] == "Delete" }
75
+ end
76
+
77
+ it "should expand a node when you set a key that goes 'through' another translation" do
78
+ translation["save.success"] = "Success"
79
+
80
+ assert { translation["save.success"] == "Success" }
81
+ end
82
+ end
83
+
84
+ describe "#remove" do
85
+ it "should remove the key" do
86
+ translation.remove "buttons.delete"
87
+
88
+ assert { translation.has_key?("buttons.delete") == false }
89
+ end
90
+ end
91
+
92
+ describe "#move" do
93
+ it "should move the key" do
94
+ translation.move "buttons.delete", "actions.crud.delete"
95
+
96
+ assert { translation["actions.crud.delete"] == "Delete" }
97
+ end
98
+
99
+ it "should remove the old key" do
100
+ translation.move "buttons.delete", "actions.crud.delete"
101
+
102
+ assert { translation.has_key?("buttons.delete") == false }
103
+ end
104
+ end
105
+
106
+ it "should have a Hash representation" do
107
+ expected = {
108
+ "en" => {
109
+ "save" => "Save",
110
+ "buttons" => {
111
+ "delete" => "Delete",
112
+ "save" => "Save"
113
+ }
114
+ }
115
+ }
116
+
117
+ assert { translation.to_hash == expected }
118
+ end
119
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'translations/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "translations"
8
+ gem.version = Translations::VERSION
9
+ gem.authors = ["Marten Lienen"]
10
+ gem.email = ["marten.lienen@gmail.com"]
11
+ gem.description = %q{Manage YAML translations}
12
+ gem.summary = %q{}
13
+ gem.homepage = "https://github.com/CQQL/translations"
14
+
15
+ gem.add_dependency "thor", "~> 0.17.0"
16
+
17
+ gem.add_development_dependency "rspec", "~> 2.12.0"
18
+ gem.add_development_dependency "wrong", "~> 0.7.0"
19
+
20
+ gem.files = `git ls-files`.split($/)
21
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
+ gem.require_paths = ["lib"]
24
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: translations
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marten Lienen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.17.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.17.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.12.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.12.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: wrong
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.7.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.0
62
+ description: Manage YAML translations
63
+ email:
64
+ - marten.lienen@gmail.com
65
+ executables:
66
+ - translations
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - .ruby-version
73
+ - Gemfile
74
+ - Gemfile.lock
75
+ - LICENSE.txt
76
+ - README.md
77
+ - Rakefile
78
+ - bin/translations
79
+ - lib/translations.rb
80
+ - lib/translations/cli.rb
81
+ - lib/translations/serializer.rb
82
+ - lib/translations/translation.rb
83
+ - lib/translations/translation_collection.rb
84
+ - lib/translations/version.rb
85
+ - spec/fixtures/missing_keys/de.yml
86
+ - spec/fixtures/missing_keys/en.yml
87
+ - spec/fixtures/working/de.yml
88
+ - spec/fixtures/working/en.yml
89
+ - spec/spec_helper.rb
90
+ - spec/translations/serializer_spec.rb
91
+ - spec/translations/translation_collection_spec.rb
92
+ - spec/translations/translation_spec.rb
93
+ - translations.gemspec
94
+ homepage: https://github.com/CQQL/translations
95
+ licenses: []
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.25
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: ''
118
+ test_files:
119
+ - spec/fixtures/missing_keys/de.yml
120
+ - spec/fixtures/missing_keys/en.yml
121
+ - spec/fixtures/working/de.yml
122
+ - spec/fixtures/working/en.yml
123
+ - spec/spec_helper.rb
124
+ - spec/translations/serializer_spec.rb
125
+ - spec/translations/translation_collection_spec.rb
126
+ - spec/translations/translation_spec.rb