translatomatic 0.1.0 → 0.1.1

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.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +1 -0
  3. data/.gitignore +15 -12
  4. data/.rspec +3 -3
  5. data/.travis.yml +32 -50
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/Gemfile +29 -5
  8. data/Guardfile +48 -0
  9. data/LICENSE.txt +21 -21
  10. data/README.de.md +92 -0
  11. data/README.es.md +92 -0
  12. data/README.fr.md +92 -0
  13. data/README.it.md +92 -0
  14. data/README.ja.md +92 -0
  15. data/README.md +96 -74
  16. data/Rakefile +6 -6
  17. data/bin/setup +8 -8
  18. data/bin/translatomatic +6 -6
  19. data/bin/travis +26 -0
  20. data/db/database.yml +9 -9
  21. data/db/migrate/201712170000_initial.rb +24 -23
  22. data/lib/translatomatic/cli.rb +204 -80
  23. data/lib/translatomatic/config.rb +12 -26
  24. data/lib/translatomatic/converter.rb +206 -142
  25. data/lib/translatomatic/converter_stats.rb +27 -27
  26. data/lib/translatomatic/database.rb +139 -99
  27. data/lib/translatomatic/escaped_unicode.rb +90 -90
  28. data/lib/translatomatic/extractor/base.rb +14 -0
  29. data/lib/translatomatic/extractor/ruby.rb +5 -0
  30. data/lib/translatomatic/extractor.rb +4 -0
  31. data/lib/translatomatic/http_request.rb +133 -0
  32. data/lib/translatomatic/locale.rb +52 -0
  33. data/lib/translatomatic/logger.rb +28 -0
  34. data/lib/translatomatic/model/locale.rb +21 -22
  35. data/lib/translatomatic/model/text.rb +17 -13
  36. data/lib/translatomatic/model.rb +4 -4
  37. data/lib/translatomatic/option.rb +24 -24
  38. data/lib/translatomatic/progress_updater.rb +15 -0
  39. data/lib/translatomatic/resource_file/base.rb +169 -137
  40. data/lib/translatomatic/resource_file/html.rb +46 -28
  41. data/lib/translatomatic/resource_file/markdown.rb +54 -0
  42. data/lib/translatomatic/resource_file/plist.rb +30 -29
  43. data/lib/translatomatic/resource_file/properties.rb +72 -60
  44. data/lib/translatomatic/resource_file/resw.rb +30 -0
  45. data/lib/translatomatic/resource_file/text.rb +29 -28
  46. data/lib/translatomatic/resource_file/xcode_strings.rb +71 -65
  47. data/lib/translatomatic/resource_file/xml.rb +79 -59
  48. data/lib/translatomatic/resource_file/yaml.rb +82 -80
  49. data/lib/translatomatic/resource_file.rb +76 -74
  50. data/lib/translatomatic/string.rb +160 -0
  51. data/lib/translatomatic/tmx/document.rb +100 -0
  52. data/lib/translatomatic/tmx/translation_unit.rb +19 -0
  53. data/lib/translatomatic/tmx.rb +4 -0
  54. data/lib/translatomatic/translation_result.rb +75 -57
  55. data/lib/translatomatic/translator/base.rb +83 -47
  56. data/lib/translatomatic/translator/frengly.rb +57 -64
  57. data/lib/translatomatic/translator/google.rb +31 -30
  58. data/lib/translatomatic/translator/microsoft.rb +33 -32
  59. data/lib/translatomatic/translator/my_memory.rb +64 -55
  60. data/lib/translatomatic/translator/yandex.rb +39 -37
  61. data/lib/translatomatic/translator.rb +63 -63
  62. data/lib/translatomatic/util.rb +15 -24
  63. data/lib/translatomatic/version.rb +4 -3
  64. data/lib/translatomatic.rb +32 -27
  65. data/translatomatic.gemspec +43 -45
  66. metadata +52 -18
  67. data/Gemfile.lock +0 -137
@@ -1,157 +1,221 @@
1
- class Translatomatic::Converter
2
- include Translatomatic::Util
3
-
4
- class << self
5
- attr_reader :options
6
- private
7
- include Translatomatic::DefineOptions
8
- end
9
-
10
- define_options(
11
- { name: :translator, type: :string, aliases: "-t",
12
- desc: "The translator implementation",
13
- enum: Translatomatic::Translator.names },
14
- { name: :dry_run, type: :boolean, aliases: "-n", desc:
15
- "Print actions without performing translations or writing files" }
16
- )
17
-
18
- # @return [Translatomatic::ConverterStats] translation statistics
1
+ class Translatomatic::Converter
2
+
3
+ class << self
4
+ attr_reader :options
5
+ private
6
+ include Translatomatic::DefineOptions
7
+ end
8
+
9
+ define_options(
10
+ { name: :translator, type: :string, aliases: "-t",
11
+ desc: "Translator implementation to use",
12
+ enum: Translatomatic::Translator.names },
13
+ { name: :dry_run, type: :boolean, aliases: "-n", desc:
14
+ "Print actions without performing translations or writing files" },
15
+ { name: :use_database, type: :boolean, default: true, desc:
16
+ "Store and retrieve translations in the database" }
17
+ )
18
+
19
+ # @return [Translatomatic::ConverterStats] translation statistics
19
20
  attr_reader :stats
20
21
 
21
- # Create a converter to translate files
22
- #
23
- # @param options A hash of converter and/or translator options.
24
- def initialize(options = {})
25
- @dry_run = options[:dry_run]
26
- @translator = options[:translator]
27
- if @translator.kind_of?(String) || @translator.kind_of?(Symbol)
28
- klass = Translatomatic::Translator.find(@translator)
29
- @translator = klass.new(options)
30
- end
31
- raise "translator required" unless @translator
32
- @from_db = 0
22
+ # @return [Array<Translatomatic::Model::Text>] A list of translations saved to the database
23
+ attr_reader :db_translations
24
+
25
+ # Create a converter to translate files
26
+ #
27
+ # @param options A hash of converter and/or translator options.
28
+ def initialize(options = {})
29
+ @dry_run = options[:dry_run]
30
+ @translator = options[:translator]
31
+ @listener = options[:listener]
32
+
33
+ # use database by default if we're connected to a database
34
+ use_db = options.include?(:use_database) ? options[:use_database] : true
35
+ @use_db = use_db && ActiveRecord::Base.connected?
36
+
37
+ log.debug("database is disabled") unless @use_db
38
+ if @translator && !@translator.respond_to?(:translate)
39
+ klass = Translatomatic::Translator.find(@translator)
40
+ @translator = klass.new(options)
41
+ end
42
+ raise "translator required" unless @translator
43
+ @translator.listener = @listener if @listener
44
+ @from_db = 0
33
45
  @from_translator = 0
34
- end
35
-
36
- # @return [Translatomatic::ConverterStats] Translation statistics
37
- def stats
38
- Translatomatic::ConverterStats.new(@from_db, @from_translator)
39
- end
40
-
41
- # Translate contents of source_file to the target locale.
42
- # Automatically determines the target filename based on target locale.
43
- #
44
- # @param [String, Translatomatic::ResourceFile] source_file File to translate
45
- # @param [String] to_locale The target locale, e.g. "fr"
46
- # @return [Translatomatic::ResourceFile] The translated resource file
47
- def translate(source_file, to_locale)
48
- if source_file.kind_of?(Translatomatic::ResourceFile::Base)
49
- source = source_file
50
- else
51
- source = Translatomatic::ResourceFile.load(source_file)
52
- raise "unsupported file type #{source_file}" unless source
46
+ @db_translations = []
47
+ end
48
+
49
+ # @return [Translatomatic::ConverterStats] Translation statistics
50
+ def stats
51
+ Translatomatic::ConverterStats.new(@from_db, @from_translator)
52
+ end
53
+
54
+ # Translate contents of source_file to the target locale.
55
+ # Automatically determines the target filename based on target locale.
56
+ #
57
+ # @param [String, Translatomatic::ResourceFile] source_file File to translate
58
+ # @param [String] to_locale The target locale, e.g. "fr"
59
+ # @return [Translatomatic::ResourceFile] The translated resource file
60
+ def translate(source_file, to_locale)
61
+ if source_file.kind_of?(Translatomatic::ResourceFile::Base)
62
+ source = source_file
63
+ else
64
+ source = Translatomatic::ResourceFile.load(source_file)
65
+ raise "unsupported file type #{source_file}" unless source
66
+ end
67
+
68
+ to_locale = parse_locale(to_locale)
69
+ target = Translatomatic::ResourceFile.load(source.path)
70
+ target.path = source.locale_path(to_locale)
71
+ target.locale = to_locale
72
+ translate_to_target(source, target)
73
+ end
74
+
75
+ # Translates a resource file and writes results to a target resource file
76
+ #
77
+ # @param source [Translatomatic::ResourceFile] The source
78
+ # @param target [Translatomatic::ResourceFile] The file to write
79
+ # @return [Translatomatic::ResourceFile] The translated resource file
80
+ def translate_to_target(source, target)
81
+ # perform translation
82
+ log.info("translating #{source} to #{target}")
83
+ properties = translate_properties(source.properties, source.locale, target.locale)
84
+ target.properties = properties
85
+ unless @dry_run
86
+ target.path.parent.mkpath
87
+ target.save
88
+ end
89
+ target
90
+ end
91
+
92
+ # Translate values in the hash of properties.
93
+ # Uses existing translations from the database if available.
94
+ #
95
+ # @param [Hash] properties Text to translate
96
+ # @param [String, Locale] from_locale The locale of the given properties
97
+ # @param [String, Locale] to_locale The target locale for translations
98
+ # @return [Hash] Translated properties
99
+ def translate_properties(properties, from_locale, to_locale)
100
+ from_locale = parse_locale(from_locale)
101
+ to_locale = parse_locale(to_locale)
102
+
103
+ # sanity check
104
+ return properties if from_locale.language == to_locale.language
105
+
106
+ result = Translatomatic::TranslationResult.new(properties,
107
+ from_locale, to_locale)
108
+
109
+ # translate using strings from the database first
110
+ db_texts = translate_properties_with_db(result)
111
+
112
+ # send remaining unknown strings to translator
113
+ tr_texts = translate_properties_with_translator(result)
114
+
115
+ log.debug("translations from db: %d translator: %d untranslated: %d" %
116
+ [db_texts.length, tr_texts.length, result.untranslated.length])
117
+ @listener.untranslated_texts(result.untranslated) if @listener
118
+
119
+ result.properties
120
+ end
121
+
122
+ private
123
+
124
+ include Translatomatic::Util
125
+
126
+ # update result with translations from the database.
127
+ # returns a list of text records from the database.
128
+ def translate_properties_with_db(result)
129
+ db_texts = []
130
+ unless database_disabled?
131
+ untranslated = result.untranslated.to_a
132
+ db_texts = find_database_translations(result, untranslated)
133
+
134
+ # find strings in untranslated that were matched in the database
135
+ original_map = {} # map of original text to translated text from db
136
+ db_texts.each do |db_text|
137
+ original_map[db_text.from_text.value] = db_text
138
+ end
139
+ matched = untranslated.select { |i| original_map[i.value] }
140
+ db_texts = db_texts.collect { |i| i.value }
141
+ result.update_strings(matched, db_texts)
142
+ @from_db += db_texts.length
143
+ @listener.translated_texts(db_texts) if @listener
53
144
  end
54
-
55
- to_locale = parse_locale(to_locale)
56
- target = Translatomatic::ResourceFile.load(source.path)
57
- target.path = source.locale_path(to_locale)
58
- target.locale = to_locale
59
- translate_to_target(source, target)
60
- end
61
-
62
- # Translates a resource file and writes results to a target resource file
63
- #
64
- # @param source [Translatomatic::ResourceFile] The source
65
- # @param target [Translatomatic::ResourceFile] The file to write
66
- # @return [Translatomatic::ResourceFile] The translated resource file
67
- def translate_to_target(source, target)
68
- # perform translation
69
- log.info "translating #{source} to #{target}"
70
- properties = translate_properties(source.properties, source.locale, target.locale)
71
- target.properties = properties
72
- target.save unless @dry_run
73
- target
145
+ db_texts
74
146
  end
75
147
 
76
- # Translate values in the hash of properties.
77
- # Uses existing translations from the database if available.
78
- #
79
- # @param [Hash] properties Text to translate
80
- # @param [String, Locale] from_locale The locale of the given properties
81
- # @param [String, Locale] to_locale The target locale for translations
82
- # @return [Hash] Translated properties
83
- def translate_properties(properties, from_locale, to_locale)
84
- from_locale = parse_locale(from_locale)
85
- to_locale = parse_locale(to_locale)
86
-
87
- # sanity check
88
- return properties if from_locale.language == to_locale.language
89
-
90
- result = Translatomatic::TranslationResult.new(properties,
91
- from_locale, to_locale)
92
-
93
- # find translations in database first
94
- texts = find_database_translations(result)
95
- result.update_db_strings(texts)
96
- @from_db += texts.length
97
-
98
- # send remaining unknown strings to translator
99
- # (copy untranslated set from result)
148
+ # update result with translations from the translator.
149
+ # returns a list of strings from the translator.
150
+ def translate_properties_with_translator(result)
100
151
  untranslated = result.untranslated.to_a.select { |i| translatable?(i) }
152
+ translated = []
101
153
  @from_translator += untranslated.length
102
154
  if !untranslated.empty? && !@dry_run
103
- translated = @translator.translate(untranslated, from_locale, to_locale)
155
+ translated = @translator.translate(untranslated.collect { |i| i.to_s },
156
+ result.from_locale, result.to_locale)
104
157
  result.update_strings(untranslated, translated)
105
- save_database_translations(result, untranslated, translated)
106
- end
107
-
108
- log.debug("translations from db: %d translator: %d untranslated: %d" %
109
- [texts.length, untranslated.length, result.untranslated.length])
110
- result.properties
111
- end
112
-
113
- private
114
-
115
- def translatable?(string)
116
- # don't translate numbers
117
- !string.empty? && !string.match(/^[\d,]+$/)
118
- end
119
-
120
- def save_database_translations(result, untranslated, translated)
121
- ActiveRecord::Base.transaction do
122
- from = db_locale(result.from_locale)
123
- to = db_locale(result.to_locale)
124
- untranslated.zip(translated).each do |t1, t2|
125
- save_database_translation(from, to, t1, t2)
158
+ unless database_disabled?
159
+ save_database_translations(result, untranslated, translated)
126
160
  end
127
161
  end
162
+ translated
128
163
  end
129
164
 
130
- def save_database_translation(from_locale, to_locale, t1, t2)
131
- original_text = Translatomatic::Model::Text.find_or_create_by!(
132
- locale: from_locale,
133
- value: t1
134
- )
135
-
136
- Translatomatic::Model::Text.find_or_create_by!(
137
- locale: to_locale,
138
- value: t2,
139
- from_text: original_text,
140
- translator: @translator.class.name.demodulize
141
- )
142
- end
143
-
144
- def find_database_translations(result)
145
- from = db_locale(result.from_locale)
146
- to = db_locale(result.to_locale)
147
-
148
- Translatomatic::Model::Text.where({
149
- locale: to,
150
- from_texts_texts: { locale_id: from, value: result.untranslated.to_a }
151
- }).joins(:from_text)
152
- end
153
-
154
- def db_locale(locale)
155
- Translatomatic::Model::Locale.from_tag(locale)
165
+ def database_disabled?
166
+ !@use_db
156
167
  end
157
- end
168
+
169
+ def parse_locale(locale)
170
+ Translatomatic::Locale.parse(locale)
171
+ end
172
+
173
+ def translatable?(string)
174
+ # don't translate numbers
175
+ !string.empty? && !string.match(/^[\d,]+$/)
176
+ end
177
+
178
+ def save_database_translations(result, untranslated, translated)
179
+ ActiveRecord::Base.transaction do
180
+ from = db_locale(result.from_locale)
181
+ to = db_locale(result.to_locale)
182
+ untranslated.zip(translated).each do |t1, t2|
183
+ save_database_translation(from, to, t1, t2)
184
+ end
185
+ end
186
+ end
187
+
188
+ def save_database_translation(from_locale, to_locale, t1, t2)
189
+ original_text = Translatomatic::Model::Text.find_or_create_by!(
190
+ locale: from_locale,
191
+ value: t1.to_s
192
+ )
193
+
194
+ text = Translatomatic::Model::Text.find_or_create_by!(
195
+ locale: to_locale,
196
+ value: t2.to_s,
197
+ from_text: original_text,
198
+ translator: @translator.name
199
+ )
200
+ @db_translations += [original_text, text]
201
+ text
202
+ end
203
+
204
+ def find_database_translations(result, untranslated)
205
+ from = db_locale(result.from_locale)
206
+ to = db_locale(result.to_locale)
207
+
208
+ # convert untranslated set to strings
209
+ Translatomatic::Model::Text.where({
210
+ locale: to,
211
+ from_texts_texts: {
212
+ locale_id: from,
213
+ value: untranslated.collect { |i| i.to_s }
214
+ }
215
+ }).joins(:from_text)
216
+ end
217
+
218
+ def db_locale(locale)
219
+ Translatomatic::Model::Locale.from_tag(locale)
220
+ end
221
+ end
@@ -1,27 +1,27 @@
1
- # Translation statistics
2
- class Translatomatic::ConverterStats
3
-
4
- # @return [Number] The total number of strings translated.
5
- attr_reader :translations
6
-
7
- # @return [Number] The number of translations that came from the database.
8
- attr_reader :from_db
9
-
10
- # @return [Number] The number of translations that came from the translator.
11
- attr_reader :from_translator
12
-
13
- def initialize(from_db, from_translator)
14
- @translations = from_db + from_translator
15
- @from_db = from_db
16
- @from_translator = from_translator
17
- end
18
-
19
- def +(other)
20
- self.class.new(@from_db + other.from_db, @from_translator + other.from_translator)
21
- end
22
-
23
- def to_s
24
- "Total translations: #{@translations} " +
25
- "(#{@from_db} from database, #{@from_translator} from translator)"
26
- end
27
- end
1
+ # Translation statistics
2
+ class Translatomatic::ConverterStats
3
+
4
+ # @return [Number] The total number of strings translated.
5
+ attr_reader :translations
6
+
7
+ # @return [Number] The number of translations that came from the database.
8
+ attr_reader :from_db
9
+
10
+ # @return [Number] The number of translations that came from the translator.
11
+ attr_reader :from_translator
12
+
13
+ def initialize(from_db, from_translator)
14
+ @translations = from_db + from_translator
15
+ @from_db = from_db
16
+ @from_translator = from_translator
17
+ end
18
+
19
+ def +(other)
20
+ self.class.new(@from_db + other.from_db, @from_translator + other.from_translator)
21
+ end
22
+
23
+ def to_s
24
+ "Total translations: #{@translations} " +
25
+ "(#{@from_db} from database, #{@from_translator} from translator)"
26
+ end
27
+ end
@@ -1,105 +1,145 @@
1
- require 'active_record'
2
-
3
- class Translatomatic::Database
4
-
5
- include Translatomatic::Util
6
-
7
- class << self
8
- attr_reader :options
9
- private
10
- include Translatomatic::DefineOptions
11
- end
12
-
13
- def initialize(options = {})
14
- db_config_path = db_config_path(options)
15
- dbconfig = File.read(db_config_path)
16
- dbconfig.gsub!(/\$HOME/, Dir.home)
17
- dbconfig.gsub!(/\$GEM_ROOT/, GEM_ROOT)
1
+ require 'active_record'
2
+
3
+ class Translatomatic::Database
4
+
5
+ include Translatomatic::Util
6
+
7
+ class << self
8
+ attr_reader :options
9
+
10
+ # @param [Hash<Symbol,Object>] options Database options
11
+ # @return True if we can connect to the database
12
+ def enabled?(options = {})
13
+ new(options).connect
14
+ end
15
+
16
+ private
17
+
18
+ include Translatomatic::DefineOptions
19
+ end
20
+
21
+ def initialize(options = {})
18
22
  @env = options[:database_env] || DEFAULT_ENV
19
- @db_config = YAML::load(dbconfig) || {}
20
- @env_config = @db_config
21
- raise "no environment '#{@env}' in #{db_config_path}" unless @env_config[@env]
22
- @env_config = @env_config[@env]
23
- ActiveRecord::Base.configurations = @db_config
24
- ActiveRecord::Tasks::DatabaseTasks.env = @env
25
- ActiveRecord::Tasks::DatabaseTasks.db_dir = DB_PATH
26
- ActiveRecord::Tasks::DatabaseTasks.root = DB_PATH
27
- ActiveRecord::Tasks::DatabaseTasks.database_configuration = @db_config
28
- create unless exists?
29
- migrate
30
- end
31
-
32
- # Connect to the database
33
- # @return [void]
34
- def connect
35
- ActiveRecord::Base.establish_connection(@env_config)
36
- end
23
+ @db_config = database_config(@env, options)
24
+ @env_config = @db_config
25
+ raise "no environment '#{@env}' in #{db_config_path}" unless @env_config[@env]
26
+ @env_config = @env_config[@env] || {}
27
+
28
+ ActiveRecord::Base.configurations = @db_config
29
+ ActiveRecord::Tasks::DatabaseTasks.env = @env
30
+ ActiveRecord::Tasks::DatabaseTasks.db_dir = DB_PATH
31
+ ActiveRecord::Tasks::DatabaseTasks.root = DB_PATH
32
+ ActiveRecord::Tasks::DatabaseTasks.database_configuration = @db_config
33
+ create unless exists?
34
+ migrate
35
+ end
36
+
37
+ # Connect to the database
38
+ # @return [boolean] True if the connection was established
39
+ def connect
40
+ begin
41
+ ActiveRecord::Base.establish_connection(@env_config)
42
+ true
43
+ rescue LoadError
44
+ false
45
+ end
46
+ end
47
+
48
+ # Disconnect from the database
49
+ # @return [void]
50
+ def disconnect
51
+ ActiveRecord::Base.remove_connection
52
+ end
53
+
54
+ # Test if the database exists
55
+ # @return [Boolean] true if the database exists
56
+ def exists?
57
+ begin
58
+ return true if sqlite_database_exists?
59
+ return false unless connect
60
+ ActiveRecord::Base.connection.tables
61
+ rescue
62
+ return false
63
+ end
64
+ true
65
+ end
66
+
67
+ # Run outstanding migrations against the database
68
+ # @return [void]
69
+ def migrate
70
+ return false unless connect
71
+ ActiveRecord::Migrator.migrate(MIGRATIONS_PATH)
72
+ ActiveRecord::Base.clear_cache!
73
+ log.debug "Database migrated."
74
+ end
75
+
76
+ # Create the database
77
+ # @return [boolean] True if the database was created
78
+ def create
79
+ begin
80
+ ActiveRecord::Tasks::DatabaseTasks.create(@env_config)
81
+ log.debug "Database created."
82
+ true
83
+ rescue LoadError => e
84
+ log.debug "Database could not be created: " + e.message
85
+ false
86
+ end
87
+ end
88
+
89
+ # Drop the database
90
+ # @return [void]
91
+ def drop
92
+ disconnect
93
+ ActiveRecord::Tasks::DatabaseTasks.drop(@env_config)
94
+ log.debug "Database deleted."
95
+ end
96
+
97
+ private
98
+
99
+ def sqlite_database_exists?
100
+ @env_config['adapter'] == 'sqlite3' && File.exist?(@env_config['database'])
101
+ end
102
+
103
+ def self.join_path(*parts)
104
+ File.realpath(File.join(*parts))
105
+ end
106
+
107
+ DB_PATH = join_path(File.dirname(__FILE__), "..", "..", "db")
108
+ INTERNAL_CONFIG = File.join(DB_PATH, "database.yml")
109
+ CUSTOM_CONFIG = File.join(Dir.home, ".translatomatic", "database.yml")
110
+ DEFAULT_CONFIG = File.exist?(CUSTOM_CONFIG) ? CUSTOM_CONFIG : INTERNAL_CONFIG
111
+ MIGRATIONS_PATH = File.join(DB_PATH, "migrate")
112
+ GEM_ROOT = join_path(File.dirname(__FILE__), "..", "..")
113
+ DEFAULT_ENV = "production"
114
+
115
+ define_options(
116
+ { name: :database_config, description: "Database config file",
117
+ default: DEFAULT_CONFIG },
118
+ { name: :database_env, description: "Database environment",
119
+ default: DEFAULT_ENV })
37
120
 
38
- # Disconnect from the database
39
- # @return [void]
40
- def disconnect
41
- ActiveRecord::Base.remove_connection
121
+ # return path to database config
122
+ def database_config_path(options)
123
+ if options[:database_env] == "test"
124
+ INTERNAL_CONFIG # rspec
125
+ elsif options[:database_config]
126
+ return options[:database_config]
127
+ else
128
+ DEFAULT_CONFIG
129
+ end
42
130
  end
43
131
 
44
- # Test if the database exists
45
- # @return [Boolean] true if the database exists
46
- def exists?
47
- begin
48
- connect
49
- ActiveRecord::Base.connection.tables
50
- rescue
51
- return false
132
+ # return database config as a hash
133
+ def database_config(env, options)
134
+ if options[:database_config].kind_of?(Hash)
135
+ return { env => options[:database_config] }
52
136
  end
53
- true
54
- end
55
-
56
- # Run outstanding migrations against the database
57
- # @return [void]
58
- def migrate
59
- connect
60
- ActiveRecord::Migrator.migrate(MIGRATIONS_PATH)
61
- ActiveRecord::Base.clear_cache!
62
- log.debug "Database migrated."
63
- end
64
-
65
- # Create the database
66
- # @return [void]
67
- def create
68
- ActiveRecord::Tasks::DatabaseTasks.create(@env_config)
69
- log.debug "Database created."
70
- end
71
-
72
- # Drop the database
73
- # @return [void]
74
- def drop
75
- disconnect
76
- ActiveRecord::Tasks::DatabaseTasks.drop(@env_config)
77
- log.debug "Database deleted."
78
- end
79
-
80
- private
81
-
82
- DB_PATH = File.join(File.dirname(__FILE__), "..", "..", "db")
83
- INTERNAL_DB_CONFIG = File.join(DB_PATH, "database.yml")
84
- CUSTOM_DB_CONFIG = File.join(Dir.home, ".translatomatic", "database.yml")
85
- DEFAULT_DB_CONFIG = File.exist?(CUSTOM_DB_CONFIG) ? CUSTOM_DB_CONFIG : INTERNAL_DB_CONFIG
86
- MIGRATIONS_PATH = File.join(DB_PATH, "migrate")
87
- GEM_ROOT = File.join(File.dirname(__FILE__), "..", "..")
88
- DEFAULT_ENV = "production"
89
137
 
90
- define_options(
91
- { name: :database_config, description: "Database config file",
92
- default: DEFAULT_DB_CONFIG },
93
- { name: :database_env, description: "Database environment",
94
- default: DEFAULT_ENV })
95
-
96
- def db_config_path(options)
97
- if options[:database_env] == "test"
98
- INTERNAL_DB_CONFIG # rspec
99
- elsif options[:database_config]
100
- return options[:database_config]
101
- else
102
- DEFAULT_DB_CONFIG
103
- end
104
- end
105
- end
138
+ db_config_path = database_config_path(options)
139
+ dbconfig = File.read(db_config_path)
140
+ dbconfig.gsub!(/\$HOME/, Dir.home)
141
+ dbconfig.gsub!(/\$GEM_ROOT/, GEM_ROOT)
142
+ YAML::load(dbconfig) || {}
143
+ end
144
+
145
+ end