translatomatic 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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