bin/crowdin-cli in crowdin-cli-0.1.6 vs bin/crowdin-cli in crowdin-cli-0.1.8

- old
+ new

@@ -3,10 +3,15 @@ require 'pp' require 'crowdin-cli' # GLI_DEBUG=true bundle exec bin/crowdin-cli +# Setup i18n +# tell the I18n library where to find your translations +I18n.load_path += Dir[Pathname(__FILE__).dirname.expand_path + '../locales/*.yml'] +I18n.locale = :en + # Return +hierarchy+ of directories and files in Crowdin project # # +files+ - basically, it's project files details from API method `project_info` # def get_remote_files_hierarchy(files, root = '/', hierarchy = { dirs: [], files: [] }) @@ -70,11 +75,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 @@ -179,11 +184,11 @@ zip_file.select{ |f| f.file? }.each do |f| file = files_list['/' + f.name] if file f_path = File.join(dest, file) FileUtils.mkdir_p(File.dirname(f_path)) - puts "Download: #{file}" + puts "Download: `#{file}'" zip_file.extract(f, f_path) else unmatched_files << f end end @@ -199,37 +204,34 @@ ### include GLI::App version Crowdin::CLI::VERSION -program_desc 'is a command line tool that allows you to manage and synchronize your localization resources with Crowdin project' -program_long_desc 'This tool requires configuration file to be created. See http://crowdin.net/page/cli-tool#configuration-file for more details.' +subcommand_option_handling :normal + +program_desc I18n.t('app.desc') +program_long_desc I18n.t('app.long_desc') sort_help :manually # help commands are ordered in the order declared wrap_help_text :to_terminal -desc 'Be verbose' -switch [:v, :verbose] +desc I18n.t('app.switches.verbose.desc') +switch [:verbose, :v], :negatable => false -desc 'Configuration file' +desc I18n.t('app.flags.config.desc') default_value File.join(Dir.pwd, 'crowdin.yaml') arg_name '<s>' -flag [:c, :config] +flag [:config,:c] -desc 'Allows you to upload source files and existing translations to Crowdin project' -long_desc 'This command is used to upload source files and translations to Crowdin. This command is used in combination with sub-commands `sources` and `translations`.' - +desc I18n.t('app.commands.upload.desc') +long_desc I18n.t('app.commands.upload.long_desc') command :upload do |c| - c.desc 'safely upload source files to Crowdin' - c.long_desc <<EOS -Upload source files to Crowdin project. If there are new localization files locally they will be added to Crowdin project. -Othervice files will be updated (if no --no-auto-update option specified). -EOS - + c.desc I18n.t('app.commands.upload.commands.sources.desc') + c.long_desc I18n.t('app.commands.upload.commands.sources.long_desc') c.command :sources do |c| - c.desc 'Defines whether to update source files in Crowdin project. --no-auto-update is useful when you just want to upload new files without updating existing ones.' + c.desc I18n.t('app.commands.upload.commands.sources.switches.auto_update.desc') c.switch ['auto-update'] c.action do |global_options, options, args| project_info = @crowdin.project_info @@ -274,11 +276,15 @@ end end # if end # @config['files'] if dest_files.empty? - exit_now!("nothing to upload. See http://crowdin.net/page/cli-tool#configuration-file for more details.") + exit_now! <<EOS +No source files to upload. +Check your configuration file to ensure that they contain valid directives. +See http://crowdin.net/page/cli-tool#configuration-file for more details. +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, '') }) @@ -332,32 +338,26 @@ end end # action end # command - c.desc 'upload existing translations to Crowdin project' - c.long_desc <<EOS -Upload existing translations to Crowdin. -See below available options that can be used in combination with this command. -If no options specified uploaded translations will be not approved, -imported to Crowdin project even if they are duplicated and imported even they are equal to souce string. -(In many localization formats they can be considered as not actually translations). -EOS + 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| - c.desc 'Defines what language upload translations to. By default translations will be uploaded for all Crowdin project target languages' + c.desc I18n.t('app.commands.upload.commands.translations.flags.language.desc') c.default_value 'all' c.arg_name 'crowdin_language_code' - c.flag [:l, :language] + c.flag [:language, :l] - c.desc 'Defines whether to add translation if there is the same translation already existing in Crowdin project' + c.desc I18n.t('app.commands.upload.commands.translations.switches.import_duplicates.desc') c.switch ['import-duplicates'] - c.desc 'Defines whether to add translation if it is equal to source string in Crowdin project' + c.desc I18n.t('app.commands.upload.commands.translations.switches.import_eq_suggestions.desc') c.switch ['import-eq-suggestions'] - c.desc 'Automatically approve uploaded translations' + c.desc I18n.t('app.commands.upload.commands.translations.switches.auto_approve_imported.desc') c.switch ['auto-approve-imported'] c.action do |global_options, options, args| params = {} params[:import_duplicates] = options['import-dublicates'] ? 1 : 0 @@ -368,14 +368,17 @@ 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'] } - else - project_languages = [] << language + project_languages = project_info['languages'].collect{ |h| h['code'] } + if language != 'all' + 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 translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) } @@ -415,69 +418,76 @@ end end # if end # @config['files'] if dest_files.empty? - exit_now!("Warning: nothing to upload. See http://crowdin.net/page/cli-tool#configuration-file for more details.") + exit_now! <<EOS +No translation files to upload. +Check your configuration file to ensure that they contain valid directives. +See http://crowdin.net/page/cli-tool#configuration-file for more details. +EOS end common_dir = @preserve_hierarchy ? '' : find_common_directory_path(dest_files) - translated_files.each do |language, files| + translated_files.each_pair do |language, files| files.each do |file| - file[:dest].sub!(common_dir, '') + file[:dest] = file[:dest].sub(common_dir, '') if remote_project_tree[:files].include?(file[:dest]) if File.exist?(file[:source]) print "Uploading translation file `#{file[:source].sub(@base_path, '')}'" resp = @crowdin.upload_translation([] << file, language, params) case resp['files'].first[1] when 'skipped' - puts "\rUploading translation `#{file[:source].sub(@base_path, '')}' - Skipped" + puts "\rUploading translation file `#{file[:source].sub(@base_path, '')}' - Skipped" when 'uploaded' - puts "\rUploading translation `#{file[:source].sub(@base_path, '')}' - OK" + puts "\rUploading translation file `#{file[:source].sub(@base_path, '')}' - OK" end else puts "Warning: Local file `#{file[:source]}' does not exists" end else # if source file not exist, don't upload translation puts "Warning: Skip `#{file[:source].sub(@base_path, '')}'" end - end end end # action end # command end -desc 'Download latest translations from Crowdin and put them to the right places in your project' +desc I18n.t('app.commands.download.desc') #arg_name 'Describe arguments to download here' command :download do |c| - c.desc 'If the option is defined the translations will be downloaded for single specified language. Othervice (by default) translations are downloaded for all languages' + c.desc I18n.t('app.commands.download.flags.language.desc') c.arg_name 'language_code' - c.flag :l, :language, :default_value => 'all' + c.flag [:language, :l], :default_value => 'all' c.action do |global_options ,options, args| - # use export API method before to download the most recent translations - @crowdin.export_translations - language = options[:language] + 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'] } - else - project_languages = [] << language + project_languages = project_info['languages'].collect{ |h| h['code'] } + if language != 'all' + if project_languages.include?(language) + project_languages = [] << language + else + exit_now!("language '#{language}' doesn't exist in a project") + end end + # use export API method before to download the most recent translations + @crowdin.export_translations + supported_languages = @crowdin.supported_languages translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) } source_language = project_info['details']['source_language']['code'] source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language } @@ -502,11 +512,11 @@ else Dir.glob("#{@base_path}#{file['source']}").select{ |fn| File.file?(fn) }.each do |source| dest = source.sub("#{@base_path}", '') # relative path in Crowdin export_pattern = construct_export_pattern(dest, file['source'], file['translation']) - + translation_languages.each do |lang| zipped_file = export_pattern_to_path(dest, export_pattern, lang) local_file = export_pattern_to_path(dest, export_pattern, lang, languages_mapping) downloadable_files[zipped_file] = local_file @@ -518,29 +528,29 @@ ## file = Tempfile.new(language) path = file.path begin - @crowdin.download_translation(language, :output => path) + @crowdin.download_translation(language, output: path) unzip_file(path, @base_path, downloadable_files) ensure file.close file.unlink # delete the temp file end end end -pre do |global ,command, options, args| +pre do |globals ,command, options, args| # Pre logic here # Return true to proceed; false to abourt and not call the # chosen command # Use skips_pre before a command to skip this block # on that command only - if File.exists?(global[:config]) - @config = YAML.load_file(global[:config]) + if File.exists?(globals[:config]) + @config = YAML.load_file(globals[:config]) ['api_key', 'project_identifier'].each do |key| unless @config[key] exit_now! <<EOS Configuration file misses required option `#{key}` @@ -599,14 +609,15 @@ puts <<EOS Warning: Configuration file misses parameter `base_path` that defines your project root directory. Using `#{@base_path}` as a root directory. EOS end - if @config['target_path'] - @target_path = @config['target_path'] + if @config['remote_path'] + @remote_path = @config['remote_path'] + @remote_path = '/' + @remote_path unless @remote_path.start_with?('/') else - @target_path = '' + @remote_path = '' end @preserve_hierarchy = false if @config['preserve_hierarchy'] @preserve_hierarchy = case @config['preserve_hierarchy'] @@ -619,28 +630,28 @@ Parameter `preserve_hierarchy` allows values of true or false. EOS end end - Crowdin::API.log = Logger.new($stderr) if global[:v] + Crowdin::API.log = Logger.new($stderr) if globals[:verbose] @crowdin = Crowdin::API.new(api_key: @config['api_key'], project_id: @config['project_identifier'], base_url: @config['base_url'] || 'http://api.crowdin.net') begin @crowdin.project_info rescue Crowdin::API::Errors::Error => err raise err rescue exit_now!("Seems Crowdin server API URL is not valid. Please check the `base_url` parameter in the configuration file.") end - #puts "Executing #{command.name}" if global[:v] + #puts "Executing #{command.name}" if globals[:verbose] true end -post do |global, command, options, args| +post do |globals, command, options, args| # Post logic here # Use skips_post before a command to skip this # block on that command only - #puts "Executed #{command.name}" if global[:v] + #puts "Executed #{command.name}" if globals[:verbose] end on_error do |exception| # Error logic here # return false to skip default error handling