neeto-translate-cli 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19601fee62f445e2d199a073ab27dd65f1e5cb01364ca2acd92acfac9e290e4c
|
|
4
|
+
data.tar.gz: 77c013b6ec3d310416e8d6e89bee8da9ab340ee9da4b2783b3d2debebef1e32e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 176e1e1dae72b2ceebac27716bda5eca56d798238cd8632a15e6806155369cf16d7fba50c9bb0df2749a756ad2858d69fb2f4da85e56913d618f87807be63a69
|
|
7
|
+
data.tar.gz: b3ce3265a73a5254b249ef9192d0c93660e320a7470ce9c9c7fc95a1059437afa04562a2092d3f46c6b37380fd4b404101d2a533534fa604d9d92f1a4c93606e
|
|
@@ -31,7 +31,8 @@ module NeetoTranslateCli
|
|
|
31
31
|
frontend: DEFAULT_FRONTEND_LOCALE_PATH,
|
|
32
32
|
backend: DEFAULT_BACKEND_LOCALE_PATH,
|
|
33
33
|
default_languages: (ENV["DEFAULT_LANGUAGES"] || DEFAULT_LANGUAGES).to_s.split(","),
|
|
34
|
-
repo: `git rev-parse --show-toplevel`.split("/").last.strip
|
|
34
|
+
repo: `git rev-parse --show-toplevel`.split("/").last.strip,
|
|
35
|
+
branch: "main"
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
OptionParser.new do |opts|
|
|
@@ -43,6 +44,11 @@ module NeetoTranslateCli
|
|
|
43
44
|
opts.on("--repo NAME", "Name of the GitHub repository (eg: neetozone/neeto-cal-web).") do |path|
|
|
44
45
|
options[:repo] = path
|
|
45
46
|
end
|
|
47
|
+
opts.on("--branch NAME", "Base branch to which the PR should be created") { |branch| options[:branch] = branch}
|
|
48
|
+
|
|
49
|
+
# This arg is explicitly added to handle translations in neeto-website and bigbinary-website.
|
|
50
|
+
# Usage: --strategy next-i18next
|
|
51
|
+
opts.on("--strategy NAME", "Name of the i18next package used to generate the translations") { |name| options[:strategy] = name }
|
|
46
52
|
end.parse!(args)
|
|
47
53
|
|
|
48
54
|
options
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pathname"
|
|
4
|
+
|
|
5
|
+
module NeetoTranslateCli
|
|
6
|
+
module NextI18next
|
|
7
|
+
class PayloadBuilder
|
|
8
|
+
attr_reader :options, :updated_keys
|
|
9
|
+
|
|
10
|
+
def initialize(options)
|
|
11
|
+
@options = options
|
|
12
|
+
commit_id = git_commit_id
|
|
13
|
+
@updated_keys = commit_id.empty? ? { frontend: {} } : find_updated_keys(commit_id)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def process!
|
|
17
|
+
{
|
|
18
|
+
frontend: {
|
|
19
|
+
en: flatten_hash_with_colon(frontend_translations[:en]),
|
|
20
|
+
missing_keys: find_missing_keys
|
|
21
|
+
},
|
|
22
|
+
metadata: {
|
|
23
|
+
repo: options[:repo],
|
|
24
|
+
frontend: options[:frontend],
|
|
25
|
+
strategy: options[:strategy],
|
|
26
|
+
branch: options[:branch],
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def no_new_changes?(payload)
|
|
32
|
+
payload[:frontend][:missing_keys].values.all?(&:empty?)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def git_commit_id
|
|
38
|
+
`git log --grep="[neeto-translate]" --fixed-strings -n 1 --pretty=format:"%H"`.strip
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def find_updated_keys(commit_id)
|
|
42
|
+
updated_frontend_keys = {}
|
|
43
|
+
frontend_translations[:en].each do |file_path, content|
|
|
44
|
+
relative_path_from_pwd = Pathname.new(file_path).relative_path_from(Pathname.new(Dir.pwd)).to_s
|
|
45
|
+
previous_content = `git show #{commit_id}:#{relative_path_from_pwd}`
|
|
46
|
+
next if previous_content.empty?
|
|
47
|
+
|
|
48
|
+
previous_json = JSON.parse(previous_content)
|
|
49
|
+
flat_previous_json = flatten_hash(previous_json)
|
|
50
|
+
flat_current_json = flatten_hash(content)
|
|
51
|
+
|
|
52
|
+
updated_keys_for_file = flat_current_json.keys.select do |key|
|
|
53
|
+
flat_previous_json.key?(key) && flat_current_json[key] != flat_previous_json[key]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
next if updated_keys_for_file.empty?
|
|
57
|
+
|
|
58
|
+
relative_path_from_en_dir = Pathname.new(file_path)
|
|
59
|
+
.relative_path_from(Pathname.new(File.expand_path(File.join(options[:frontend], "en")))).to_s
|
|
60
|
+
path_without_ext = relative_path_from_en_dir.chomp(File.extname(relative_path_from_en_dir))
|
|
61
|
+
updated_frontend_keys[path_without_ext] = updated_keys_for_file
|
|
62
|
+
end
|
|
63
|
+
{ frontend: updated_frontend_keys }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def find_missing_keys
|
|
67
|
+
missing_keys = {}
|
|
68
|
+
base_translations = frontend_translations[:en]
|
|
69
|
+
|
|
70
|
+
options[:default_languages].each do |lang|
|
|
71
|
+
missing_keys[lang] = []
|
|
72
|
+
base_translations.each do |base_file_path, base_content|
|
|
73
|
+
lang_file_path = "#{options[:frontend]}/#{lang}/#{base_file_path}.json"
|
|
74
|
+
|
|
75
|
+
base_keys = flatten_hash(base_content).keys
|
|
76
|
+
lang_keys = File.file?(lang_file_path) ? flatten_hash(load_json(lang_file_path)).keys : []
|
|
77
|
+
|
|
78
|
+
missing_in_file = (base_keys - lang_keys).uniq
|
|
79
|
+
missing_keys[lang].concat(missing_in_file.map { |key| "#{base_file_path}:#{key}" })
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
missing_keys
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def frontend_translations
|
|
87
|
+
return @_frontend_translations if defined?(@_frontend_translations)
|
|
88
|
+
|
|
89
|
+
all_files = Dir.glob("#{options[:frontend]}/en/**/*").select { |path| File.file?(path) }
|
|
90
|
+
@_frontend_translations = { en: {} }
|
|
91
|
+
|
|
92
|
+
all_files.each do |path|
|
|
93
|
+
lang_key = path.gsub("#{options[:frontend]}/en/", "").gsub(".json", "")
|
|
94
|
+
@_frontend_translations[:en][lang_key] = load_json(path)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
@_frontend_translations
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def load_json(file_path)
|
|
101
|
+
return {} unless File.file?(file_path)
|
|
102
|
+
|
|
103
|
+
JSON.parse(File.read(file_path, encoding: "utf-8"))
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def flatten_hash(hash, prefix = nil)
|
|
107
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
108
|
+
current_key = prefix ? "#{prefix}.#{key}" : key.to_s
|
|
109
|
+
if value.is_a?(Hash)
|
|
110
|
+
result.merge!(flatten_hash(value, current_key))
|
|
111
|
+
else
|
|
112
|
+
result[current_key] = value
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def flatten_hash_with_colon(hash)
|
|
118
|
+
hash.flat_map do |file_key, file_content|
|
|
119
|
+
flatten_hash(file_content).map do |translation_key, translation_value|
|
|
120
|
+
["#{file_key}:#{translation_key}", translation_value]
|
|
121
|
+
end
|
|
122
|
+
end.to_h
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "api"
|
|
4
4
|
require_relative "payload_builder"
|
|
5
|
+
require_relative "next_i18next/payload_builder"
|
|
5
6
|
|
|
6
7
|
module NeetoTranslateCli
|
|
7
8
|
class Translator
|
|
@@ -19,7 +20,9 @@ module NeetoTranslateCli
|
|
|
19
20
|
private
|
|
20
21
|
|
|
21
22
|
def translate!
|
|
22
|
-
payload_builder =
|
|
23
|
+
payload_builder = options[:strategy] == "next-i18next" ?
|
|
24
|
+
NeetoTranslateCli::NextI18next::PayloadBuilder.new(options)
|
|
25
|
+
: PayloadBuilder.new(options)
|
|
23
26
|
payload = payload_builder.process!
|
|
24
27
|
|
|
25
28
|
if payload_builder.no_new_changes?(payload)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: neeto-translate-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abhay V Ashokan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-09-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -40,6 +40,7 @@ files:
|
|
|
40
40
|
- exe/neeto-translate-cli
|
|
41
41
|
- lib/neeto_translate_cli/api.rb
|
|
42
42
|
- lib/neeto_translate_cli/cli.rb
|
|
43
|
+
- lib/neeto_translate_cli/next_i18next/payload_builder.rb
|
|
43
44
|
- lib/neeto_translate_cli/payload_builder.rb
|
|
44
45
|
- lib/neeto_translate_cli/translator.rb
|
|
45
46
|
- lib/neeto_translate_cli/version.rb
|