From 35efa6af6ff45f1bbc539215f29e39ffe2c99bbb Mon Sep 17 00:00:00 2001 From: Christine Lytwynec Date: Wed, 4 Jun 2014 17:45:13 -0400 Subject: [PATCH] deprecating i18n tasks from rake to paver --- pavelib/__init__.py | 2 +- pavelib/assets.py | 4 +- pavelib/i18n.py | 163 +++++++++++++++++++++++++++++++++++ rakelib/helpers.rb | 9 -- rakelib/i18n.rake | 91 ------------------- rakelib/i18n_deprecated.rake | 29 +++++++ 6 files changed, 196 insertions(+), 102 deletions(-) create mode 100644 pavelib/i18n.py delete mode 100644 rakelib/i18n.rake create mode 100644 rakelib/i18n_deprecated.rake diff --git a/pavelib/__init__.py b/pavelib/__init__.py index d2edaa42a2..4f0c49debd 100644 --- a/pavelib/__init__.py +++ b/pavelib/__init__.py @@ -1,4 +1,4 @@ """ paver commands """ -from . import assets, servers, docs, prereqs, quality, tests, js_test +from . import assets, servers, docs, prereqs, quality, tests, js_test, i18n diff --git a/pavelib/assets.py b/pavelib/assets.py index 8f8217643c..df154fce32 100644 --- a/pavelib/assets.py +++ b/pavelib/assets.py @@ -3,7 +3,7 @@ Asset compilation and collection. """ from __future__ import print_function import argparse -from paver.easy import sh, path, task, cmdopts, needs, consume_args, call_task +from paver.easy import sh, path, task, cmdopts, needs, consume_args, call_task, no_help from watchdog.observers import Observer from watchdog.events import PatternMatchingEventHandler import glob @@ -113,6 +113,8 @@ def coffeescript_files(): return cmd('find', dirs, '-type f', '-name \"*.coffee\"') +@task +@no_help def compile_coffeescript(*files): """ Compile CoffeeScript to JavaScript. diff --git a/pavelib/i18n.py b/pavelib/i18n.py new file mode 100644 index 0000000000..31605002c5 --- /dev/null +++ b/pavelib/i18n.py @@ -0,0 +1,163 @@ +""" +Internationalization tasks +""" +import sys +import subprocess +from path import path +from paver.easy import task, cmdopts, needs, sh +from pavelib.utils.envs import Env + +try: + from pygments.console import colorize +except ImportError: + colorize = lambda color, text: text # pylint: disable-msg=invalid-name + + +@task +@needs( + "pavelib.i18n.i18n_validate_gettext", + "pavelib.assets.compile_coffeescript", +) +@cmdopts([ + ("verbose", "v", "Sets 'verbose' to True"), +]) +def i18n_extract(options): + """ + Extract localizable strings from sources + """ + verbose = getattr(options, "verbose", None) + cmd = Env.REPO_ROOT / "i18n" / "extract.py" + + if verbose: + cmd += " -vv" + + sh(cmd) + + +@task +@needs("pavelib.i18n.i18n_extract") +def i18n_generate(): + """ + Compile localizable strings from sources, extracting strings first. + """ + cmd = Env.REPO_ROOT / "i18n" / "generate.py" + sh(cmd) + + +@task +@needs("pavelib.i18n.i18n_extract") +def i18n_generate_strict(): + """ + Compile localizable strings from sources, extracting strings first. + Complains if files are missing. + """ + cmd = Env.REPO_ROOT / "i18n" / "generate.py" + sh(cmd + " --strict") + + +@task +@needs("pavelib.i18n.i18n_extract") +def i18n_dummy(): + """ + Simulate international translation by generating dummy strings + corresponding to source strings. + """ + cmd = Env.REPO_ROOT / "i18n" / "dummy.py" + sh(cmd) + + +@task +def i18n_validate_gettext(): + """ + Make sure GNU gettext utilities are available + """ + + returncode = subprocess.call(['which', 'xgettext']) + + if returncode != 0: + msg = colorize( + 'red', + "Cannot locate GNU gettext utilities, which are " + "required by django for internationalization.\n (see " + "https://docs.djangoproject.com/en/dev/topics/i18n/" + "translation/#message-files)\nTry downloading them from " + "http://www.gnu.org/software/gettext/ \n" + ) + + sys.stderr.write(msg) + sys.exit(1) + + +@task +def i18n_validate_transifex_config(): + """ + Make sure config file with username/password exists + """ + home = path('~').expanduser() + config = home / '.transifexrc' + + if not config.isfile or config.getsize == 0: + msg = colorize( + 'red', + "Cannot connect to Transifex, config file is missing" + " or empty: {config} \nSee " + "http://help.transifex.com/features/client/#transifexrc \n".format( + config=config, + ) + ) + + sys.stderr.write(msg) + sys.exit(1) + + +@task +@needs("pavelib.i18n.i18n_validate_transifex_config") +def i18n_transifex_push(): + """ + Push source strings to Transifex for translation + """ + cmd = Env.REPO_ROOT / "i18n" / "transifex.py" + sh("{cmd} push".format(cmd=cmd)) + + +@task +@needs("pavelib.i18n.i18n_validate_transifex_config") +def i18n_transifex_pull(): + """ + Pull translated strings from Transifex + """ + cmd = Env.REPO_ROOT / "i18n" / "transifex.py" + sh("{cmd} pull".format(cmd=cmd)) + + +@task +@needs( + "pavelib.i18n.i18n_transifex_pull", + "pavelib.i18n.i18n_extract", + "pavelib.i18n.i18n_dummy", + "pavelib.i18n.i18n_generate_strict", +) +def i18n_robot_pull(): + """ + Pull source strings, generate po and mo files, and validate + """ + sh('git clean -fdX conf/locale') + sh('paver test_i18n') + sh('git add conf/locale') + + sh( + 'git commit --message="Update translations ' + '(autogenerated message)" --edit' + ) + + +@task +@needs( + "pavelib.i18n.i18n_extract", + "pavelib.i18n.i18n_transifex_push", +) +def i18n_robot_push(): + """ + Extract new strings, and push to transifex + """ + pass diff --git a/rakelib/helpers.rb b/rakelib/helpers.rb index 230c5a5551..3b73238251 100644 --- a/rakelib/helpers.rb +++ b/rakelib/helpers.rb @@ -4,15 +4,6 @@ require 'colorize' require 'timeout' require 'net/http' -def find_executable(exec) - path = %x(which #{exec}).strip - $?.exitstatus == 0 ? path : nil -end - -def select_executable(*cmds) - cmds.find_all{ |cmd| !find_executable(cmd).nil? }[0] || fail("No executables found from #{cmds.join(', ')}") -end - def django_admin(system, env, command, *args) return "./manage.py #{system} --settings #{env} #{command} --traceback #{args.join(' ')}" end diff --git a/rakelib/i18n.rake b/rakelib/i18n.rake deleted file mode 100644 index a29439e520..0000000000 --- a/rakelib/i18n.rake +++ /dev/null @@ -1,91 +0,0 @@ -# --- Internationalization tasks - -I18N_REPORT_DIR = report_dir_path('i18n') -I18N_XUNIT_REPORT = File.join(I18N_REPORT_DIR, 'nosetests.xml') - -directory I18N_REPORT_DIR - - -namespace :i18n do - - desc "Extract localizable strings from sources" - task :extract => ["i18n:validate:gettext", "assets:coffee"] do - command = File.join(REPO_ROOT, "i18n", "extract.py") - if verbose == true - command += " -vv" - end - sh(command) - end - - desc "Compile localizable strings from sources, extracting strings first." - task :generate => "i18n:extract" do - cmd = File.join(REPO_ROOT, "i18n", "generate.py") - sh("#{cmd}") - end - - desc "Compile localizable strings from sources, extracting strings first, and complain if files are missing." - task :generate_strict => "i18n:extract" do - cmd = File.join(REPO_ROOT, "i18n", "generate.py") - sh("#{cmd} --strict") - end - - desc "Simulate international translation by generating dummy strings corresponding to source strings." - task :dummy => "i18n:extract" do - sh(File.join(REPO_ROOT, "i18n", "dummy.py")) - end - - namespace :validate do - - desc "Make sure GNU gettext utilities are available" - task :gettext do - begin - select_executable('xgettext') - rescue - msg = "Cannot locate GNU gettext utilities, which are required by django for internationalization.\n" - msg += "(see https://docs.djangoproject.com/en/dev/topics/i18n/translation/#message-files)\n" - msg += "Try downloading them from http://www.gnu.org/software/gettext/" - abort(msg.red) - end - end - - desc "Make sure config file with username/password exists" - task :transifex_config do - config_file = "#{Dir.home}/.transifexrc" - if !File.file?(config_file) or File.size(config_file)==0 - msg ="Cannot connect to Transifex, config file is missing or empty: #{config_file}\n" - msg += "See http://help.transifex.com/features/client/#transifexrc" - abort(msg.red) - end - end - end - - namespace :transifex do - desc "Push source strings to Transifex for translation" - task :push => "i18n:validate:transifex_config" do - cmd = File.join(REPO_ROOT, "i18n", "transifex.py") - sh("#{cmd} push") - end - - desc "Pull translated strings from Transifex" - task :pull => "i18n:validate:transifex_config" do - cmd = File.join(REPO_ROOT, "i18n", "transifex.py") - sh("#{cmd} pull") - end - end - - # Commands for automating the process of including translations in edx-platform. - # Will eventually be run by jenkins. - namespace :robot do - desc "Pull source strings, generate po and mo files, and validate" - task :pull => ["i18n:transifex:pull", "i18n:extract", "i18n:dummy", "i18n:generate_strict"] do - sh('git clean -fdX conf/locale') - Rake::Task["i18n:test"].invoke - sh('git add conf/locale') - sh('git commit --message="Update translations (autogenerated message)" --edit') - end - - desc "Extract new strings, and push to transifex" - task :push => ["i18n:extract", "i18n:transifex:push"] - end - -end diff --git a/rakelib/i18n_deprecated.rake b/rakelib/i18n_deprecated.rake new file mode 100644 index 0000000000..82de4329a1 --- /dev/null +++ b/rakelib/i18n_deprecated.rake @@ -0,0 +1,29 @@ +# Internationalization tasks deprecated to paver + +require 'colorize' + +def deprecated(deprecated, deprecated_by, *args) + + task deprecated do + + # Need to install paver dependencies for the commands to work! + sh("pip install -r requirements/edx/paver.txt") + + new_cmd = deprecated_by + + puts("Task #{deprecated} has been deprecated. Using #{deprecated_by} instead.".red) + sh(new_cmd) + exit + end +end + +deprecated("i18n:extract", "paver i18n_extract") +deprecated("i18n:generate", "paver i18n_generate") +deprecated("i18n:generate_strict", "paver i18n_generate_strict") +deprecated("i18n:dummy", "paver i18n_dummy") +deprecated("i18n:validate:gettext", "paver i18n_validate_gettext") +deprecated("i18n:validate:transifex_config", "paver i18n_validate_transifex_config") +deprecated("i18n:transifex:push", "paver i18n_transifex_push") +deprecated("i18n:transifex:pull", "paver i18n_transifex_pull") +deprecated("i18n:robot:push", "paver i18n_robot_push") +deprecated("i18n:robot:pull", "paver i18n_robot_pull")