lost_in_translation 0.2.18 → 0.2.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 353e35eab28113f4aee6ba75a6ad21f99b70dc21
4
- data.tar.gz: 5aad6ec09f1ca54236673f799d7250604d93ff64
3
+ metadata.gz: 0cd012a988d369d10222f9e41553e2c287f3db00
4
+ data.tar.gz: cc79df11ddca81bd6d222d837d761f68c61c7d6e
5
5
  SHA512:
6
- metadata.gz: 9feadd7f520d45284103ced2caf6cc29ade5a25f2a008aa47dfc29513de2835ceea5c9dc3acd89dc4838b126351e157d82ec8df68b1901bbcd29647e1dfd9bba
7
- data.tar.gz: 84a8af6f70a444f8476a35a20729076fe6f5e33faa9b71371bc5f485d6864c0df808e8a416198c3fc1a9ded4b57050dfa86c95f1db1f4ca9e7b4de9ab89a5d50
6
+ metadata.gz: 293c06e2bddb5c73360f639d9d889d85b9ee3571a0b7238d7ba200f1753053ae8ad722e2b8a6622d8fe4baf01c4b6c3183d8b5d89df881d7df15fff90787a5e7
7
+ data.tar.gz: bef7bf02e3417f17eba019d01ad07e46871ba4d6fefbb26ba29e5b3ef44b1fcfab8927b8f88b72dea3b4434066e0cc226ecd9a60185ef64a72c6abd89fb2e6e2
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at yves.goizet@hotmail.de. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in lost_in_translation.gemspec
6
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Datyv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ # LostInTranslation
2
+
3
+ This gem provides you three tasks to translate your locale yamls!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'lost_in_translation'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install lost_in_translation
20
+
21
+ ## Usage
22
+ There are three tasks you can execute.
23
+
24
+ ### ATTENTION: Use at your own risk! Back your shit up, before using this!
25
+ Each will ask you for the file
26
+ If this gem is installed inside a Rails-Application you just have to written
27
+ e.g.:
28
+ ```
29
+ 'en' -> for en.yml
30
+ 'de' -> for de.yml
31
+ ...
32
+ ```
33
+ One will be the master-file (this one will not be changed)
34
+ and
35
+ One will be the slave-file (this one will be changed)
36
+
37
+ #### Script 1: Interactive
38
+ ```bash
39
+ rake lit:interactive
40
+ ```
41
+ This script will ask you for the missing value.
42
+ It will find every difference and will ask you to fill every hole... yeah.
43
+ After everything is filled out it will merge the data back into your File.
44
+
45
+ #### Script 2: Recent
46
+ ```bash
47
+ rake lit:recent
48
+ ```
49
+ REQUIRED: Connection to Git
50
+ This script will ask you for the missing value.
51
+ It will find everything you changed in your master-file since you last pushed commit.
52
+ After everything is filled out it will merge the data back into your File.
53
+
54
+ #### Script 3: Cleanup (Deletes something!)
55
+ ```bash
56
+ rake lit:cleanup
57
+ ```
58
+ This script will find every key/value inside your slave-file that isn´t present in your master-file.
59
+ And it will be deleted!!!!
60
+
61
+ #### Sometimes the Rake tasks aren't working
62
+ In this case you can use the Rails-Console and the Class -LostInTranslation-.
63
+
64
+ ```bash
65
+ rails c
66
+ ```
67
+ ```
68
+ LostInTranslation.interactive
69
+ or
70
+ LostInTranslation.recent
71
+ or
72
+ LostInTranslation.cleanup
73
+ ```
74
+
75
+ #### Yet to come
76
+ I am planning on an integration of Translation APIs.
77
+
78
+ ## Contributing
79
+
80
+ Bug reports and pull requests are welcome on GitHub at https://github.com/datyv/lost_in_translation. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
81
+
82
+
83
+ ## License
84
+
85
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ # require 'lib/lost_in_translation'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task default: :spec
10
+
11
+ import 'lib/tasks/tasks.rake'
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "lost_in_translation"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ module LostInTranslation
5
+ def self.diff(root, compared, lang1, lang2, structure = [], new_array = [], options = {})
6
+ @slave_file = options[:slave_file] || ''
7
+ @mode = options[:mode] || 'count' # replace, clean, count
8
+ @diff_count = options[:diff_count] || 0
9
+ @diff_counter = options[:diff_counter] || 0
10
+ root.each_pair do |key, value|
11
+ next_root = root[key]
12
+ next_compared = compared.nil? ? nil : compared[key]
13
+ new_structure = structure.dup << key
14
+ if value.is_a?(String) && (compared.nil? || compared[key].nil?)
15
+ if value_missing(@slave_file, new_structure)
16
+ @diff_counter += 1
17
+ if @mode == 'replace'
18
+ new_val = ask_for_translation(value, new_structure, lang1, lang2, @diff_count, @diff_counter)
19
+ new_array << new_val unless new_val.blank?
20
+ elsif @mode == 'clean'
21
+ new_array << "#{new_structure.join('---')}---#{value}"
22
+ end
23
+ end
24
+ end
25
+ if next_root.is_a? Hash
26
+ diff(next_root, next_compared, lang1, lang2, new_structure, new_array,
27
+ diff_counter: @diff_counter, diff_count: @diff_count, mode: @mode, slave_file: @slave_file)
28
+ end
29
+ end
30
+ @mode == 'count' ? @diff_counter : new_array
31
+ end
32
+
33
+ def self.value_missing(slave_file, structure)
34
+ return true if slave_file.blank?
35
+ slave_file.dig(*structure).blank?
36
+ end
37
+
38
+ def self.get_locale(path)
39
+ path.split('/').last.split('.').first unless path.empty?
40
+ end
41
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ module LostInTranslation
5
+ def self.prepare_for_edit(options = {})
6
+ paths = tmp_paths
7
+ FileUtils.cp(options[:master], paths[:master]) if options[:master]
8
+ FileUtils.cp(options[:slave], paths[:slave]) if options[:slave]
9
+ end
10
+
11
+ def self.prepare_paths(paths = [])
12
+ paths.each do |p|
13
+ prepare_yaml(p, false)
14
+ end
15
+ end
16
+
17
+ def self.postpare_paths(paths = [])
18
+ paths.each do |p|
19
+ prepare_yaml(p, true)
20
+ end
21
+ end
22
+
23
+ def self.define_snippets
24
+ snippets = []
25
+ snippets << ['<<', 'a_greater_than_sign']
26
+ snippets << ['*', 'an_asterik_sign']
27
+ snippets << ['!', 'a_bang_sign']
28
+ snippets << ['%', 'a_percentage_sign']
29
+ snippets << ['a_bang_sign \'', '\'a_bang_sign']
30
+ snippets
31
+ end
32
+
33
+ def self.reset_tmp_files
34
+ paths = tmp_paths
35
+ paths.each_value do |path|
36
+ File.open(path, 'w') { |file| file.write('') }
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def self.prepare_yaml(path, post)
43
+ text = File.read(path)
44
+ snippets = define_snippets
45
+
46
+ snippets = snippets.reverse if post
47
+ snippets.each do |snippet|
48
+ snippet = snippet.reverse if post
49
+ text = text.gsub(snippet.first, snippet.second)
50
+ end
51
+ text = post ? postpare(snippets, text) : prepare(snippets, text)
52
+
53
+ File.open(path, 'w') { |file| file.puts text }
54
+ end
55
+
56
+ def self.postpare(variables, text)
57
+ variables = text.scan(/varyberryterry.*/)
58
+ variables.each do |var|
59
+ new_var = var.delete(':')
60
+ new_var = new_var.gsub('varyberryterry', ': &')
61
+ text = text.gsub(var, new_var)
62
+ end
63
+ text = add_single_quotes(text)
64
+ text = text.gsub(': !,', ": ! ','")
65
+ text = text.gsub('\'!', '! \'')
66
+ text = text.gsub(/---\n/, '')
67
+ text = text.gsub('!&hellip;', "! '&hellip;'")
68
+ text = text.gsub('!:distance_in_words', "! ':distance_in_words'")
69
+ text
70
+ end
71
+
72
+ def self.prepare(variables, text)
73
+ variables = text.scan(/: &.*/)
74
+ variables.each do |var|
75
+ new_var = var.gsub(': &', 'varyberryterry')
76
+ new_var += ':'
77
+ text = text.gsub(var, new_var)
78
+ end
79
+ text
80
+ end
81
+
82
+ def self.add_single_quotes(text)
83
+ tmp = ''
84
+ text.each_line do |line|
85
+ tmp += edit_line(line)
86
+ end
87
+ tmp
88
+ end
89
+
90
+ def self.edit_line(line)
91
+ return line if line.match(/: .*%.*$/).blank?
92
+ arr = line.split(': ', 2)
93
+ return line if arr[1].blank?
94
+ arr[1] = arr[1].gsub("\'", '')
95
+ arr[1] = arr[1].gsub("\"", '')
96
+ arr[1] = "'" + arr[1] unless arr[1].start_with?("\'") || arr[1].start_with?("\"")
97
+ arr[1] = arr[1].squish + "'\n" unless arr[1].squish.end_with?("\'") || arr[1].squish.end_with?("\"")
98
+ arr[1] = arr[1].gsub("\'! ", "! \'")
99
+ return arr.join(': ')
100
+ end
101
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ module LostInTranslation
5
+ def self.string_to_hash(string)
6
+ array = string.split('---')
7
+ value = array.pop
8
+ arr = array.reverse
9
+ arr[1..-1].inject(arr[0] => value) { |memo, i| { i => memo } }
10
+ end
11
+
12
+ def self.merge_hash(merge_from, merge_to)
13
+ return if merge_from.is_a?(String) || merge_to.is_a?(String)
14
+ merged_hash = merge_to
15
+ first_key = merge_from.keys.first
16
+ merged_hash[first_key] = if merge_to.key?(first_key)
17
+ merge_hash(merge_from[first_key], merge_to[first_key])
18
+ else
19
+ merge_from[first_key]
20
+ end
21
+ merged_hash
22
+ end
23
+
24
+ def self.sort_hash(object)
25
+ return object unless object.is_a?(Hash)
26
+ hash = {}
27
+ object.each { |k, v| hash[k] = sort_hash(v) }
28
+ sorted = hash.sort { |a, b| a[0].to_s <=> b[0].to_s }
29
+ hash.class[sorted]
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ module LostInTranslation
6
+ class Railtie < Rails::Railtie
7
+ railtie_name :lost_in_translation
8
+
9
+ rake_tasks do
10
+ load 'tasks/tasks.rake'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ module LostInTranslation
5
+ require 'readline'
6
+
7
+ def self.ask_for_file(master, namespace = '')
8
+ text = master ? "# Master-Locale (e.g. 'en'): " : "# Slave-Locale (e.g. 'de'): "
9
+ file = {}
10
+ file[:lang] = [(print text), Readline.readline()][1]
11
+ file[:filename] = namespace.blank? ? file[:lang] : "#{namespace}.#{file[:lang]}"
12
+ file[:path] = defined?(Rails) ? "#{Rails.root}/config/locales/#{file[:filename]}.yml" : ask_for_path
13
+ if !File.exist?(file[:path]) && master
14
+ log "File #{file[:path]} not found!"
15
+ file[:path] = ask_for_path
16
+ elsif !File.exist?(file[:path]) && !master
17
+ log "File #{file[:filename]} not found! It will be created!"
18
+ File.open(file[:path], 'w') { |f| f.write({ file[:lang] => {} }.to_yaml(line_width: -1)) }
19
+ end
20
+ file[:app_name] = Rails&.application&.class&.parent_name
21
+ file
22
+ end
23
+
24
+ def self.ask_for_locales_path
25
+ return "#{Rails.root}/config/locales" if defined?(Rails)
26
+ log
27
+ log 'Please type in the absolute path your locales-folder?'
28
+ log 'e.g. /home/youruser/Documents/your-awesome-app/config/locales'
29
+ path = [(print '# '), Readline.readline()][1]
30
+ path
31
+ end
32
+
33
+ def self.ask_for_permission(master, count, slave = nil)
34
+ log
35
+ log 'Comparing Locales'
36
+ log "Application: #{master[:app_name]}" if master[:app_name]
37
+ log "Master Locale: #{master[:filename]}.yml" if master
38
+ log "Slave Locale: #{slave[:filename]}.yml" if slave
39
+ log "Difference: #{count} Entries"
40
+ a = [(print "# Wanna do it? [Y/n]: "), Readline.readline()][1]
41
+ a == 'y' || a == 'Y' || a == ''
42
+ end
43
+
44
+ def self.ask_for_task(tasks)
45
+ log
46
+ log 'Welcome, stranger!'
47
+ log 'Are you lost in translation, too?'
48
+ log 'Then I will be glad to help you one of the following tasks!'
49
+ tasks.each_with_index do |task, i|
50
+ log "#{i + 1} => #{task[:text]}"
51
+ end
52
+ log 'Soo ... what can I do for you? (Type in the Number)'
53
+ id = [(print 'Task No.: '), Readline.readline()][1]
54
+ tasks[(id.to_i - 1)]
55
+ rescue
56
+ puts "Cannot find task with id #{id}"
57
+ end
58
+
59
+ def self.ask_for_split(file, count)
60
+ log
61
+ log "Splitting File #{file}.yml"
62
+ log "File-Count: #{count} new files will be create!"
63
+ a = [(print "# Wanna do it? [Y/n]: "), Readline.readline()][1]
64
+ a == 'y' || a == 'Y' || a == ''
65
+ end
66
+
67
+ def self.ask_for_sorting(file, app_name)
68
+ log
69
+ log "Application: #{app_name}" unless app_name.blank?
70
+ log "Do you want the #{file}.yml to be sorted?"
71
+ log 'Alphabetically & Recursive (ASC)'
72
+ a = [(print "# [Y/n]: "), Readline.readline()][1]
73
+ a == 'y' || a == 'Y' || a == ''
74
+ end
75
+
76
+ def self.ask_for_translation(value, new_structure, lang1, lang2, diff_count, diff_counter)
77
+ system 'clear'
78
+ log
79
+ log "#{diff_counter} / #{diff_count}"
80
+ new_s = new_structure.join('---')
81
+ log "#{new_s} is missing"
82
+
83
+ snippets = LostInTranslation.define_snippets.reverse
84
+ snippets.each do |snippet|
85
+ value = value.gsub(snippet.second, snippet.first)
86
+ end
87
+
88
+ puts "# In #{lang1.upcase}: #{value}"
89
+ new_val = [(print "# In #{lang2.upcase}: "), Readline.readline()][1]
90
+ new_val = (new_s + '---' + new_val) unless new_val.blank?
91
+ new_val
92
+ end
93
+
94
+ def self.log(text = '')
95
+ max_length = 80
96
+ outside = 4
97
+ puts '#' * max_length if text.blank?
98
+ arr = text.scan(/.{1,#{max_length - outside}}/)
99
+ arr.each do |str|
100
+ fill_length = max_length - str.length - outside
101
+ fill = ' ' * fill_length
102
+ puts '# ' + str + fill + ' #'
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def self.ask_for_path
109
+ log
110
+ log 'Please type in the absolute path your locale?'
111
+ log 'e.g. /home/youruser/Documents/your-awesome-app/config/locales/de.yml'
112
+ path = [(print '# '), Readline.readline()][1]
113
+ path
114
+ end
115
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lit/difference'
4
+ require 'lit/file_functions'
5
+ require 'lit/hash'
6
+ require 'lit/user_interface'
7
+ require 'lit/railties'
8
+
9
+ require 'tasks/compare'
10
+ require 'tasks/delete_missing'
11
+ require 'tasks/fully_automatic'
12
+ require 'tasks/half_automatic'
13
+ require 'tasks/recent'
14
+ require 'tasks/sort_file'
15
+ require 'tasks/split_file'
16
+ require 'tasks/start'
17
+ require 'tasks/count'
18
+
19
+ module LostInTranslation
20
+ def self.root
21
+ File.dirname __dir__
22
+ end
23
+
24
+ def self.tmp_paths
25
+ tmp_paths = {}
26
+ tmp_paths[:copy] = "#{root}/tmp/tmp_master_copy.yml"
27
+ tmp_paths[:master] = "#{root}/tmp/tmp_master.yml"
28
+ tmp_paths[:slave] = "#{root}/tmp/tmp_slave.yml"
29
+ tmp_paths
30
+ end
31
+
32
+ def self.init(with_slave = true)
33
+ system 'clear'
34
+ log
35
+ log 'What I18n-yaml files do you want to compare?'
36
+ namespace = [(print "# Namespace? ('namespace' for 'namespace.en.yml'): "), Readline.readline()][1]
37
+ master = ask_for_file(true, namespace) # lang path app_name
38
+ slave = with_slave ? ask_for_file(false, namespace) : {}
39
+ invalid_filepath if !File.exist?(master[:path]) && (!File.exist?(slave[:path]) && with_slave)
40
+ [master, slave, tmp_paths]
41
+ end
42
+
43
+ def self.breakout
44
+ raise "Well in that case, forget it!"
45
+ end
46
+
47
+ def self.invalid_filepath
48
+ raise "One on the filepaths are invalid!"
49
+ end
50
+
51
+ def self.tbd
52
+ raise "This feature is not yet implemented! Please take another!"
53
+ end
54
+ end
55
+
56
+ class Lit
57
+ extend LostInTranslation
58
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.compare
5
+ @master, @slave, paths = init
6
+
7
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
8
+ prepare_paths([paths[:master], paths[:slave]])
9
+
10
+ master_file = YAML.load_file(paths[:master])
11
+ slave_file = YAML.load_file(paths[:slave])
12
+
13
+ count = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
14
+ @slave[:lang], [@slave[:lang]], [], mode: 'count')
15
+
16
+ breakout unless ask_for_permission(@master, count, @slave)
17
+
18
+ new_strings_array = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
19
+ @slave[:lang], [@slave[:lang]], [], diff_count: count, mode: 'replace')
20
+
21
+ new_strings_array.each do |string|
22
+ result = string_to_hash(string)
23
+ merge_hash(result, slave_file)
24
+ end
25
+
26
+ File.open(paths[:slave], 'w') { |file| file.write(slave_file.to_yaml(line_width: -1)) }
27
+ postpare_paths([paths[:slave]])
28
+ FileUtils.cp(paths[:slave], @slave[:path])
29
+
30
+ reset_tmp_files
31
+
32
+ log 'Done'
33
+ log
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.count
5
+ @master, @slave, paths = init
6
+
7
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
8
+ prepare_paths([paths[:master], paths[:slave]])
9
+
10
+ master_file = YAML.load_file(paths[:master])
11
+ slave_file = YAML.load_file(paths[:slave])
12
+
13
+ count = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang], @slave[:lang],
14
+ [@slave[:lang]], [], mode: 'count')
15
+
16
+ count2 = diff(slave_file[@slave[:lang]], master_file[@master[:lang]], @slave[:lang], @master[:lang],
17
+ [@master[:lang]], [], mode: 'count')
18
+
19
+
20
+ reset_tmp_files
21
+ log
22
+ log 'Differences between Locales'
23
+ log "#{@master[:filename]}.yml => #{@slave[:filename]}.yml = #{count}"
24
+ log "#{@slave[:filename]}.yml => #{@master[:filename]}.yml = #{count2}"
25
+ log 'Done'
26
+ log
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.delete_missing
5
+ tbd
6
+ @master, @slave, paths = init
7
+
8
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
9
+ prepare_paths([paths[:master], paths[:slave]])
10
+
11
+ master_file = YAML.load_file(paths[:master])
12
+ slave_file = YAML.load_file(paths[:slave])
13
+
14
+ breakout unless ask_for_permission(@master, count, @slave)
15
+
16
+ new_strings_array = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
17
+ @slave[:lang], [@slave[:lang]], [], mode: 'clean')
18
+
19
+ master_file = {}
20
+ new_strings_array.each do |string|
21
+ string = string.split('---').map { |x| x == @slave[:lang] ? @master[:lang] : x }.join('---')
22
+ result = string_to_hash(string)
23
+ merge_hash(result, master_file)
24
+ end
25
+
26
+ File.open(@master[:path], 'w') { |file| file.write(master_file.to_yaml) }
27
+ postpare_paths([@master[:path], @slave[:path]])
28
+ reset_tmp_files
29
+ log 'Done'
30
+ log
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.fully_automatic
5
+ tbd
6
+ @master, @slave, paths = init
7
+
8
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
9
+ prepare_paths([paths[:master], paths[:slave]])
10
+
11
+ master_file = YAML.load_file(paths[:master])
12
+ slave_file = YAML.load_file(paths[:slave])
13
+
14
+ count = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
15
+ @slave[:lang], [@slave[:lang]], [], mode: 'count')
16
+
17
+ breakout unless ask_for_permission(@master, count, @slave)
18
+
19
+ new_strings_array = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
20
+ @slave[:lang], [@slave[:lang]], [], diff_count: count, mode: 'replace')
21
+
22
+ new_strings_array.each do |string|
23
+ result = string_to_hash(string)
24
+ merge_hash(result, slave_file)
25
+ end
26
+
27
+ File.open(paths[:slave], 'w') { |file| file.write(slave_file.to_yaml(line_width: -1)) }
28
+ postpare_paths([paths[:slave]])
29
+ FileUtils.cp(paths[:slave], @slave[:path])
30
+
31
+ reset_tmp_files
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.half_automatic
5
+ tbd
6
+ @master, @slave, paths = init
7
+
8
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
9
+ prepare_paths([paths[:master], paths[:slave]])
10
+
11
+ master_file = YAML.load_file(paths[:master])
12
+ slave_file = YAML.load_file(paths[:slave])
13
+
14
+ count = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
15
+ @slave[:lang], [@slave[:lang]], [], mode: 'count')
16
+
17
+ breakout unless ask_for_permission(@master, count, @slave)
18
+
19
+ new_strings_array = diff(master_file[@master[:lang]], slave_file[@slave[:lang]], @master[:lang],
20
+ @slave[:lang], [@slave[:lang]], [], diff_count: count, mode: 'replace')
21
+
22
+ new_strings_array.each do |string|
23
+ result = string_to_hash(string)
24
+ merge_hash(result, slave_file)
25
+ end
26
+
27
+ File.open(paths[:slave], 'w') { |file| file.write(slave_file.to_yaml(line_width: -1)) }
28
+ postpare_paths([paths[:slave]])
29
+ FileUtils.cp(paths[:slave], @slave[:path])
30
+
31
+ reset_tmp_files
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.recent
5
+ @master, @slave, paths = init
6
+
7
+ FileUtils.cp(@master[:path], paths[:copy])
8
+ `git checkout "#{@master[:path]}"`
9
+
10
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
11
+ FileUtils.cp(paths[:copy], @master[:path])
12
+
13
+ prepare_paths([paths[:master], paths[:slave], paths[:copy]])
14
+
15
+ master_file = YAML.load_file(paths[:master])
16
+ master_copy_file = YAML.load_file(paths[:copy])
17
+ slave_file = YAML.load_file(paths[:slave])
18
+
19
+ count = diff(master_copy_file[@master[:lang]], master_file[@master[:lang]], @master[:lang],
20
+ @slave[:lang], [@slave[:lang]], [], mode: 'count', slave_file: slave_file)
21
+
22
+ breakout unless ask_for_permission(@master, count, @slave)
23
+
24
+ new_strings_array = diff(master_copy_file[@master[:lang]], master_file[@master[:lang]], @master[:lang],
25
+ @slave[:lang], [@slave[:lang]], [], mode: 'replace', diff_counter: 0, diff_count: count,
26
+ slave_file: slave_file)
27
+
28
+ new_strings_array.each do |string|
29
+ result = string_to_hash(string)
30
+ merge_hash(result, slave_file)
31
+ end
32
+
33
+ File.open(paths[:slave], 'w') { |file| file.write(slave_file.to_yaml(line_width: -1)) }
34
+ postpare_paths([paths[:slave]])
35
+ FileUtils.cp(paths[:slave], @slave[:path])
36
+
37
+ reset_tmp_files
38
+ log 'Done'
39
+ log
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.sort_file
5
+ @master, @slave, paths = init(false)
6
+
7
+ prepare_for_edit(master: @master[:path], slave: @slave[:path])
8
+ prepare_paths([paths[:master]])
9
+
10
+ master_file = YAML.load_file(paths[:master])
11
+
12
+ if ask_for_sorting(@master[:lang], @master[:app_name])
13
+ master_file = sort_hash(master_file)
14
+ File.open(paths[:master], 'w') { |file| file.write(master_file.to_yaml(line_width: -1)) }
15
+ end
16
+
17
+ postpare_paths([paths[:master]])
18
+
19
+ FileUtils.cp(paths[:master], @master[:path])
20
+
21
+ reset_tmp_files
22
+ log 'Done'
23
+ log
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.split_file
5
+ @master, @slave, paths = init(false)
6
+
7
+ prepare_for_edit(master: @master[:path])
8
+ prepare_paths([paths[:master]])
9
+
10
+ master_file = YAML.load_file(paths[:master])[@master[:lang]]
11
+
12
+ count = master_file.select { |_k, v| v.is_a?(Hash) }.size
13
+ new_hash = {}
14
+
15
+ if ask_for_split(@master[:lang], count)
16
+ master_file.each_pair do |key, value|
17
+ next unless value.is_a?(Hash)
18
+ new_hash[@master[:lang]] = { key => value }
19
+ File.open(paths[:slave], 'w') { |file| file.write(new_hash.to_yaml(line_width: -1)) }
20
+ postpare_paths([paths[:slave]])
21
+ root_path = @master[:path].split('/').reverse.drop(1).reverse.join('/')
22
+ filename = @master[:path].split('/').last
23
+ FileUtils.cp(paths[:slave], "#{root_path}/#{key}.#{filename}")
24
+ master_file.delete(key)
25
+ end
26
+
27
+ new_hash[@master[:lang]] = master_file
28
+ File.open(paths[:master], 'w') { |file| file.write(new_hash.to_yaml(line_width: -1)) }
29
+ postpare_paths([paths[:master]])
30
+ FileUtils.cp(paths[:master], @master[:path])
31
+ end
32
+
33
+ reset_tmp_files
34
+ log 'Done'
35
+ log
36
+ end
37
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LostInTranslation
4
+ def self.start
5
+ tasks = [
6
+ { text: 'Compare & Translate two I18n-Locale-Files', method: :start_compare },
7
+ { text: 'Count Differences of 2 I18n-Locale-Files', method: :count },
8
+ { text: 'Sort an I18n-Locale-File Alphabetically & Recursive (ASC)', method: :sort_file },
9
+ { text: 'Split an I18n-Locale-File into multiple namespaced Files (1. Level)', method: :split_file },
10
+ { text: 'Show a list of available I18n-Locale-Files', method: :list_files },
11
+ { text: 'Tell me joke', method: :joke },
12
+ { text: 'Quit', method: :quit }
13
+ ]
14
+ task = ask_for_task(tasks)
15
+ LostInTranslation.send(task[:method])
16
+ end
17
+
18
+ def self.start_compare
19
+ tasks = [
20
+ { text: 'Compare everything', method: :compare },
21
+ { text: 'Just compare the recent changes (since last git commit)', method: :recent },
22
+ { text: 'Automatic translation via API', method: :fully_automatic },
23
+ { text: 'Translation suggentions from API', method: :half_automatic },
24
+ { text: 'Compare and delete the differences', method: :delete_missing },
25
+ ]
26
+ task = ask_for_task(tasks)
27
+ LostInTranslation.send(task[:method])
28
+ end
29
+
30
+ def self.joke
31
+ system 'clear'
32
+ log
33
+ log 'A: Knock, Knock!'
34
+ log 'B: Who is there?'
35
+ log 'A: Ya.'
36
+ log 'B: Ya who?'
37
+ log 'A: Oh, I prefer google.'
38
+ log
39
+ end
40
+
41
+ def self.quit
42
+ system 'clear'
43
+ log
44
+ log 'Thank you and goodbye!'
45
+ log
46
+ end
47
+
48
+ def self.list_files
49
+ system 'clear'
50
+
51
+ path = ask_for_locales_path
52
+ files = Dir["#{path}/**/*.yml"]
53
+ puts "No Files found in #{path}" if files.empty?
54
+ files&.sort&.each do |file|
55
+ puts file.split('/').last
56
+ end
57
+ start
58
+ end
59
+ end
@@ -0,0 +1,46 @@
1
+ require 'lost_in_translation'
2
+
3
+ namespace :lit do
4
+ desc 'Make the locale-yamls equal again(Interactive)'
5
+ task :compare do
6
+ system 'clear'
7
+ LostInTranslation.compare
8
+ end
9
+
10
+ desc 'Just start and get lead through the process'
11
+ task :start do
12
+ system 'clear'
13
+ LostInTranslation.start
14
+ end
15
+
16
+ desc 'Use Translator-Engine as a suggestion for translation'
17
+ task :half_automatic do
18
+ LostInTranslation.half_automatic
19
+ end
20
+
21
+ desc 'Use Translator-Engine to automatically translate everything'
22
+ task :fully_automatic do
23
+ LostInTranslation.fully_automatic
24
+ end
25
+
26
+ desc 'Split big files in many small ones'
27
+ task :split_file do
28
+ LostInTranslation.split_file
29
+ end
30
+
31
+ desc 'Sort Locale-File recursively'
32
+ task :sort_file do
33
+ LostInTranslation.sort_file
34
+ end
35
+
36
+ desc 'Cleaning out the Yaml-Closet'
37
+ task :delete_missing do
38
+ LostInTranslation.delete_missing
39
+ end
40
+
41
+ desc 'Tranlate just your recently changed Strings(requires git)'
42
+ task :recent do
43
+ abort('Please use this feature inside a Rails-Application') unless defined? Rails
44
+ LostInTranslation.recent
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'lost_in_translation'
8
+ spec.version = '0.2.19'
9
+ spec.authors = ['Datyv']
10
+ spec.email = ['yvesgoizet@gmail.com']
11
+
12
+ spec.summary = 'A Gem to compare two locale yamls'
13
+ spec.description = 'Take two locales yamls and merge them together with different values.'
14
+ spec.homepage = 'https://github.com/Datyv/lost_in_translation'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib', 'tmp', 'spec']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.11'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ end
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lost_in_translation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.18
4
+ version: 0.2.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datyv
@@ -58,7 +58,36 @@ email:
58
58
  executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
- files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - CODE_OF_CONDUCT.md
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/lit/difference.rb
72
+ - lib/lit/file_functions.rb
73
+ - lib/lit/hash.rb
74
+ - lib/lit/railties.rb
75
+ - lib/lit/user_interface.rb
76
+ - lib/lost_in_translation.rb
77
+ - lib/tasks/compare.rb
78
+ - lib/tasks/count.rb
79
+ - lib/tasks/delete_missing.rb
80
+ - lib/tasks/fully_automatic.rb
81
+ - lib/tasks/half_automatic.rb
82
+ - lib/tasks/recent.rb
83
+ - lib/tasks/sort_file.rb
84
+ - lib/tasks/split_file.rb
85
+ - lib/tasks/start.rb
86
+ - lib/tasks/tasks.rake
87
+ - lost_in_translation.gemspec
88
+ - tmp/tmp_master.yml
89
+ - tmp/tmp_master_copy.yml
90
+ - tmp/tmp_slave.yml
62
91
  homepage: https://github.com/Datyv/lost_in_translation
63
92
  licenses:
64
93
  - MIT