bin/crowdin-cli in crowdin-cli-0.2.5 vs bin/crowdin-cli in crowdin-cli-0.3.0
- old
+ new
@@ -77,11 +77,11 @@
}
placeholders = pattern.inject([]){ |memo, h| memo << h.first[/%(.*)%/, 1] }
unless languages_mapping.nil?
- pattern = Hash[pattern.map{ |placeholder, str| [
+ pattern = Hash[pattern.map { |placeholder, str| [
placeholder,
(languages_mapping[placeholder[/%(.*)%/, 1]][lang['crowdin_code']] rescue nil) || str]
}]
end
@@ -227,11 +227,10 @@
# files that exists in archive and doesn't match current project configuration
unmatched_files = []
Zip::File.open(zipfile_name) do |zipfile|
zipfile.select{ |zip_entry| zip_entry.file? }.each do |f|
- # XXX
# `f' - relative path in archive
file = files_list[f.name]
if file
fpath = File.join(dest_path, file)
FileUtils.mkdir_p(File.dirname(fpath))
@@ -243,15 +242,64 @@
end
end
unless unmatched_files.empty?
puts "Warning: Downloaded translations does not match current project configuration. Some of the resulted files will be omitted."
- unmatched_files.each{ |file| puts " - `#{file}'" }
+ unmatched_files.each { |file| puts " - `#{file}'" }
puts "Crowdin has internal caching mechanisms that prevents us from overload. Please try to download translations later."
end
end
+# Build a Hash tree from Array of +filenames*
+#
+def build_hash_tree(filenames)
+ files_tree = filenames.inject({}) { |h, i| t = h; i.split("/").each { |n| t[n] ||= {}; t = t[n] }; h }
+end
+
+# Box-drawing character - https://en.wikipedia.org/wiki/Box-drawing_character
+# ├ └ ─ │
+#
+def display_tree(files_tree, level = -2, branches = [])
+ tab = ' ' * 4
+ level += 1
+
+ files_tree.each_with_index do |(key, val), index|
+ if val.empty? # this is a file
+ result = branches.take(level).inject('') { |s, i| s << (i == 1 ? '│ ': ' ') }
+
+ if index == files_tree.length - 1
+ # this is a last element
+ result << '└' + '── ' + key
+ else
+ result << '├' + '── ' + key
+ end
+
+ puts result
+ else # this is directory
+ if key == '' # root directory
+ result = '.'
+ else
+ result = branches.take(level).inject('') { |s, i| s << (i == 1 ? '│ ' : ' ') }
+ if index == files_tree.length - 1
+ # this is a last element
+ result << '└' + '── ' + key
+
+ branches[level] = 0
+ else
+ result << '├' + '── ' + key
+
+ branches[level] = 1
+ end
+ end
+ puts result
+
+ # recursion \(^_^)/
+ display_tree(val, level, branches)
+ end
+ end
+end
+
###
include GLI::App
version Crowdin::CLI::VERSION
@@ -287,11 +335,11 @@
source_language = project_info['details']['source_language']['code']
# Crowdin supported languages list
supported_languages = @crowdin.supported_languages
- source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language }
+ source_language = supported_languages.find { |lang| lang['crowdin_code'] == source_language }
remote_project_tree = get_remote_files_hierarchy(project_info['files'])
local_files = []
dest_files = []
@@ -317,17 +365,17 @@
else
Find.find(@base_path) do |source_path|
dest = source_path.sub(@base_path, '') # relative path in Crowdin
if File.directory?(source_path)
- if ignores.any?{ |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
Find.prune # Don't look any further into this directory
else
next
end
elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME)
- next if ignores.any?{ |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ next if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
dest_files << dest
export_pattern = construct_export_pattern(dest, file['source'], file['translation'])
@@ -352,13 +400,13 @@
EOS
end
common_dir = @preserve_hierarchy ? '' : find_common_directory_path(dest_files)
- local_project_tree = get_local_files_hierarchy(local_files.collect{ |h| h[:dest].sub(common_dir, '') })
+ local_project_tree = get_local_files_hierarchy(local_files.collect { |h| h[:dest].sub(common_dir, '') })
- local_files.each{ |file| file[:dest].sub!(common_dir, '') }
+ local_files.each { |file| file[:dest].sub!(common_dir, '') }
# Create directory tree
#
create_dirs = local_project_tree[:dirs] - remote_project_tree[:dirs]
create_dirs.each do |dir|
@@ -369,11 +417,11 @@
if options['auto-update']
# Update existing files in Crowdin project
#
# array containing elements common to the two arrays
update_files = local_project_tree[:files] & remote_project_tree[:files]
- files_for_upload = local_files.select{ |file| update_files.include?(file[:dest]) }
+ files_for_upload = local_files.select { |file| update_files.include?(file[:dest]) }
files_for_upload.each do |file|
print "Updating source file `#{file[:dest]}'"
params = {}
params[:scheme] = file.delete(:sheme)
@@ -392,11 +440,11 @@
end
# Add new files to Crowdin project
#
add_files = local_project_tree[:files] - remote_project_tree[:files]
- files_for_add = local_files.select{ |file| add_files.include?(file[:dest]) }
+ files_for_add = local_files.select { |file| add_files.include?(file[:dest]) }
files_for_add.each do |file|
print "Uploading source file `#{file[:dest]}'"
params = {}
params[:scheme] = file.delete(:sheme)
@@ -406,11 +454,11 @@
puts "\rUploading source file `#{file[:dest]}' - OK"
end
end # action
- end # command
+ end # upload sources
c.desc I18n.t('app.commands.upload.commands.translations.desc')
c.long_desc I18n.t('app.commands.upload.commands.translations.long_desc')
c.command :translations do |c|
@@ -438,25 +486,26 @@
project_info = @crowdin.project_info
remote_project_tree = get_remote_files_hierarchy(project_info['files'])
- project_languages = project_info['languages'].collect{ |h| h['code'] }
- if language != 'all'
+ if language == 'all'
+ project_languages = project_info['languages'].collect { |h| h['code'] }
+ else
if project_languages.include?(language)
project_languages = [] << language
else
exit_now!("language '#{language}' doesn't exist in a project")
end
end
supported_languages = @crowdin.supported_languages
source_language = project_info['details']['source_language']['code']
- source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language }
+ source_language = supported_languages.find { |lang| lang['crowdin_code'] == source_language }
- translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) }
+ translation_languages = supported_languages.select { |lang| project_languages.include?(lang['crowdin_code']) }
translated_files = Hash.new{ |hash, key| hash[key] = Array.new }
dest_files = []
@config['files'].each do |file|
@@ -488,17 +537,17 @@
else
Find.find(@base_path) do |source_path|
dest = source_path.sub(@base_path, '') # relative path in Crowdin
if File.directory?(source_path)
- if ignores.any?{ |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
Find.prune # Don't look any further into this directory
else
next
end
elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME)
- next if ignores.any?{ |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ next if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
dest_files << dest
export_pattern = construct_export_pattern(dest, file['source'], file['translation'])
@@ -547,42 +596,198 @@
end
end
end
end # action
- end # command
+ end # upload translations
end
+desc I18n.t('app.commands.list.desc')
+long_desc I18n.t('app.commands.list.long_desc')
+command :list do |ls_cmd|
+
+ ls_cmd.desc I18n.t('app.commands.list.commands.project.desc')
+ ls_cmd.command :project do |proj_cmd|
+ proj_cmd.desc I18n.t('app.commands.list.switches.tree.desc')
+ proj_cmd.switch ['tree'], :negatable => false
+
+ proj_cmd.action do |global_options, options, args|
+ project_info = @crowdin.project_info
+ remote_project_tree = get_remote_files_hierarchy(project_info['files'])
+
+ if options[:tree]
+ tree = build_hash_tree(remote_project_tree[:files])
+ display_tree(tree)
+ else
+ puts remote_project_tree[:files]
+ end
+ end
+ end
+
+ ls_cmd.desc I18n.t('app.commands.list.commands.sources.desc')
+ ls_cmd.command :sources do |src_cmd|
+ src_cmd.desc I18n.t('app.commands.list.switches.tree.desc')
+ src_cmd.switch ['tree'], :negatable => false
+
+ src_cmd.action do |global_options, options, args|
+ local_files = []
+ dest_files = []
+
+ @config['files'].each do |file|
+ get_invalid_placeholders(file['translation']).each do |placeholder|
+ puts "Warning: #{placeholder} is not valid variable supported by Crowdin. See http://crowdin.net/page/cli-tool#configuration-file for more details."
+ end
+
+ ignores = file['ignore'] || []
+
+ if File.exist?(File.join(@base_path, file['source']))
+ dest = file['source']
+ dest_files << dest
+
+ local_file = { dest: dest, source: File.join(@base_path, file['source']), export_pattern: file['translation'] }
+
+ local_file.merge!({ sheme: file['scheme'] }) if file.has_key?('scheme')
+ local_file.merge!({ first_line_contains_header: file['first_line_contains_header'] }) if file.has_key?('first_line_contains_header')
+ local_file.merge!({ update_option: file['update_option'] }) if file.has_key?('update_option')
+
+ local_files << local_file
+ else
+ Find.find(@base_path) do |source_path|
+ dest = source_path.sub(@base_path, '') # relative path in Crowdin
+
+ if File.directory?(source_path)
+ if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ Find.prune # Don't look any further into this directory
+ else
+ next
+ end
+ elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME)
+ next if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+
+ dest_files << dest
+
+ export_pattern = construct_export_pattern(dest, file['source'], file['translation'])
+
+ local_file = { dest: dest, source: source_path, export_pattern: export_pattern }
+
+ local_file.merge!({ sheme: file['scheme'] }) if file.has_key?('scheme')
+ local_file.merge!({ first_line_contains_header: file['first_line_contains_header'] }) if file.has_key?('first_line_contains_header')
+ local_file.merge!({ update_option: file['update_option'] }) if file.has_key?('update_option')
+
+ local_files << local_file
+ end
+ end # Find
+
+ end # if File.exists?
+ end # @config['files']
+
+ common_dir = @preserve_hierarchy ? '' : find_common_directory_path(dest_files)
+
+ local_project_tree = get_local_files_hierarchy(local_files.collect { |h| h[:dest].sub(common_dir, '') })
+
+ if options[:tree]
+ tree = build_hash_tree(local_project_tree[:files])
+ display_tree(tree)
+ else
+ puts local_project_tree[:files]
+ end
+ end
+ end # list sources
+
+ ls_cmd.desc I18n.t('app.commands.list.commands.translations.desc')
+ ls_cmd.command :translations do |trans_cmd|
+ trans_cmd.desc I18n.t('app.commands.list.switches.tree.desc')
+ trans_cmd.switch ['tree'], :negatable => false
+
+ trans_cmd.action do |global_options, options, args|
+ project_info = @crowdin.project_info
+
+ project_languages = project_info['languages'].collect{ |h| h['code'] }
+
+ supported_languages = @crowdin.supported_languages
+ translation_languages = supported_languages.select { |lang| project_languages.include?(lang['crowdin_code']) }
+
+ translation_files = []
+ @config['files'].each do |file|
+ languages_mapping = file['languages_mapping'] # Hash or NilClass
+
+ ignores = file['ignore'] || []
+
+ if File.exists?(File.join(@base_path, file['source']))
+ dest = file['source'].sub("#{@base_path}", '')
+
+ translation_languages.each do |lang|
+ local_file = export_pattern_to_path(dest, file['translation'], lang, languages_mapping)
+ translations_files << local_file
+ end
+
+ else
+ Find.find(@base_path) do |source_path|
+ dest = source_path.sub(@base_path, '') # relative path in Crowdin
+
+ if File.directory?(source_path)
+ if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ Find.prune # Don't look any further into this directory
+ else
+ next
+ end
+ elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME)
+ next if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+
+ export_pattern = construct_export_pattern(dest, file['source'], file['translation'])
+
+ translation_languages.each do |lang|
+ local_file = export_pattern_to_path(dest, export_pattern, lang, languages_mapping)
+ translation_files << local_file
+ end
+
+ end
+ end # Find
+ end # if
+ end # @config['files']
+
+ if options[:tree]
+ tree = build_hash_tree(translation_files)
+ display_tree(tree)
+ else
+ puts translation_files
+ end
+
+ end
+ end # list translations
+
+ #ls_cmd.default_command :project
+end # list
+
desc I18n.t('app.commands.download.desc')
#arg_name 'Describe arguments to download here'
command :download do |c|
c.desc I18n.t('app.commands.download.flags.language.desc')
+ c.long_desc I18n.t('app.commands.download.flags.language.long_desc')
c.arg_name 'language_code'
c.flag [:l, :language], :default_value => 'all'
c.action do |global_options ,options, args|
language = options[:language]
supported_languages = @crowdin.supported_languages
project_info = @crowdin.project_info
- remote_project_tree = get_remote_files_hierarchy(project_info['files'])
+ if language == 'all'
+ project_languages = project_info['languages'].collect{ |h| h['code'] }
- project_languages = project_info['languages'].collect{ |h| h['code'] }
-
- if @jipt_language
- if supported_languages.find{ |lang| lang['crowdin_code'] == @jipt_language }
- project_languages << @jipt_language # crowdin_language_code
- else
- exit_now!("invalid jipt language `#{@jipt_language}`")
+ if @jipt_language
+ if supported_languages.find { |lang| lang['crowdin_code'] == @jipt_language }
+ project_languages << @jipt_language # crowdin_language_code
+ else
+ exit_now!("invalid jipt language `#{@jipt_language}`")
+ end
end
- end
-
- if language != 'all'
+ else
if project_languages.include?(language)
project_languages = [] << language
else
exit_now!("language '#{language}' doesn't exist in a project")
end
@@ -590,13 +795,13 @@
# use export API method before to download the most recent translations
@crowdin.export_translations
source_language = project_info['details']['source_language']['code']
- source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language }
+ source_language = supported_languages.find { |lang| lang['crowdin_code'] == source_language }
- translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) }
+ translation_languages = supported_languages.select { |lang| project_languages.include?(lang['crowdin_code']) }
# keys is all possible files in .ZIP archive
# values is resulted local files
downloadable_files_hash = {}
@@ -627,17 +832,17 @@
else
Find.find(@base_path) do |source_path|
dest = source_path.sub(@base_path, '') # relative path in Crowdin
if File.directory?(source_path)
- if ignores.any?{ |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
Find.prune # Don't look any further into this directory
else
next
end
elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME)
- next if ignores.any?{ |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
+ next if ignores.any? { |pattern| File.fnmatch?(pattern, dest, File::FNM_PATHNAME) }
export_pattern = construct_export_pattern(dest, file['source'], file['translation'])
file_translation_languages.each do |lang|
zipped_file = export_pattern_to_path(dest, export_pattern, lang)
@@ -660,12 +865,12 @@
unzip_file_with_translations(zipfile_name, @base_path, downloadable_files_hash)
ensure
tempfile.close
tempfile.unlink # delete the tempfile
end
- end
-end
+ end # action
+end # download
pre do |globals ,command, options, args|
# Pre logic here
# Return true to proceed; false to abourt and not call the
# chosen command