Skip to content

Instantly share code, notes, and snippets.

@konifar
Created December 11, 2023 00:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save konifar/c3effb0c3639273012cbe86aa810ad19 to your computer and use it in GitHub Desktop.
Save konifar/c3effb0c3639273012cbe86aa810ad19 to your computer and use it in GitHub Desktop.
# ja.lproj/Localizable.strings を正として、次のチェックを行います
# 1. jaのキーと同じキーが他言語にもあるか
# 2. jaのコメントと同じコメントが他言語にもあるか
# 3. jaのバリューに"%%", "%s", "%1$s", "%@", "%1$@", "%d", "%1$d", "\n" がある時、他言語にも同じ文字列が同じ個数含まれているか
# 4. バリューに"%"だけの文字が含まれていないか
# 実行例) ruby ./scripts/localization/localizable_strings_checker.rb Project/Languages Localizable.strings
# https://github.com/rylev/apfel
require 'apfel'
require 'find'
# TODO ここはもっとよい書き方がある
SPECIAL_STRINGS = [
"%%",
"%s",
"%1$s",
"%2$s",
"%3$s",
"%4$s",
"%@",
"%1$@",
"%2$@",
"%3$@",
"%4$@",
"%d",
"%1$d",
"%2$d",
"%3$d",
"%4$d",
"\n", # これはテキストの長さにもよるのでそのうち消した方がいいかも
]
def check_same_keys(ja_keys, other_keys)
sorted_ja_keys = ja_keys.sort
sorted_other_keys = other_keys.sort
is_same_keys = sorted_ja_keys == sorted_other_keys
puts " jaのキーと同じキーが他言語にもあるかチェック: #{is_same_keys}"
if !is_same_keys
missing_keys = sorted_ja_keys - sorted_other_keys
if missing_keys.length > 0
puts " 以下のキーがjaファイルにだけあります"
missing_keys.each do |key|
puts " #{key}"
end
end
end
is_same_keys
end
def check_same_comments(ja_comments, other_comments)
sorted_ja_comments = ja_comments.sort
sorted_other_comments = other_comments.sort
is_same_comments = sorted_ja_comments == sorted_other_comments
puts " jaのコメントと同じコメントが他言語にもあるかチェック: #{is_same_comments}"
if !is_same_comments
missing_comments = sorted_ja_comments - sorted_other_comments
if missing_comments.length > 0
puts " 以下のコメントがjaファイルにだけあります"
missing_comments.each do |key|
puts " #{key}"
end
end
end
is_same_comments
end
def check_replace_strings(ja_key_values, other_key_values)
puts " jaのバリューに置換文字や改行文字がある時、他言語にも同じく存在するかチェック"
has_diff = false
ja_key_values.each do |key_value|
key = key_value.keys.first
value = key_value.values.first
# マッチする特定文字列を抽出
regex = Regexp.union(SPECIAL_STRINGS.map { |str| Regexp.escape(str) })
matches = value.scan(regex).uniq
if matches.length > 0
# keyに合致する多言語の文字列を取得
other_value = other_key_values.find { |hash| hash.key?(key) }&.[](key)
# 入っていない特定文字列を取得
missing_strings = matches.reject { |str| other_value.include?(str) }
if missing_strings.length > 0
has_diff = true
puts " key[#{key}] の値に #{missing_strings} が含まれていません"
end
end
end
!has_diff
end
def check_single_percent_string(key_values)
puts " バリューに '%' だけの文字が含まれていないかチェック"
has_error = false
key_values.each do |key_value|
key = key_value.keys.first
value = key_value.values.first
# %% や %@、%1$@、%d、%1$dという文字列以外の%があるかをチェック
has_single_percent = value.match(/(?<!%)%(?![%]|[@]|[d]|[s]|[[0-9]$@]|[[0-9]$d])/)
if has_single_percent
has_error = true
puts " key[#{key}] の値に % のみの文字列が含まれています"
end
end
!has_error
end
# 実行時引数のチェック
unless ARGV.length < 3
puts "Usage: ruby #{$0} <xx.lprojが入っているディレクトリのパス> <言語ファイル名>"
exit 1
end
root_dir = ARGV[0]
file_name = ARGV[1]
# jaのファイルの読み込み
ja_path = "#{root_dir}/ja.lproj/#{file_name}"
ja_file = Apfel.parse(ja_path)
puts "#{ja_path}をロード, key counts: #{ja_file.keys.length}"
# 4. バリューに"%"だけの文字が含まれていないか
has_single_percent = check_single_percent_string(ja_file.key_values)
# ja以外のファイルを読み込んでチェックを実行
Find.find(root_dir) do |path|
if path =~ /.*\.lproj\/#{file_name}$/ && path !~ /ja\.lproj/
other_file = Apfel.parse(path)
puts "#{path}をロード, key counts: #{other_file.keys.length}"
# 1. jaのキーと同じキーが他言語にもあるかチェック
is_same_keys = check_same_keys(ja_file.keys, other_file.keys)
# 2. jaのコメントと同じコメントが他言語にもあるかチェック
is_same_comments = check_same_comments(ja_file.comments, other_file.comments)
# 3. jaのバリューに置換文字や改行文字がある時、他言語にも同じく存在するかチェック
no_special_strings_diff = check_replace_strings(ja_file.key_values, other_file.key_values)
# 4. バリューに"%"だけの文字が含まれていないか
has_single_percent = check_single_percent_string(other_file.key_values)
has_error = !is_same_keys || !is_same_comments || !no_special_strings_diff || !has_single_percent
if has_error
exit 1
end
puts " エラーはありませんでした!"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment