Port translations update code to git

This commit is contained in:
Kovid Goyal 2013-05-29 10:48:45 +05:30
parent a2a1bcb97f
commit d630f34d0d
3 changed files with 71 additions and 17 deletions

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import sys, re, os, platform import sys, re, os, platform, subprocess
is64bit = platform.architecture()[0] == '64bit' is64bit = platform.architecture()[0] == '64bit'
iswindows = re.search('win(32|64)', sys.platform) iswindows = re.search('win(32|64)', sys.platform)
@ -22,6 +22,24 @@ sys.extensions_location = os.path.join(SRC, 'calibre', 'plugins')
__version__ = __appname__ = modules = functions = basenames = scripts = None __version__ = __appname__ = modules = functions = basenames = scripts = None
def require_git_master():
if subprocess.check_output(['git', 'symbolic-ref', '--short', 'HEAD']).strip() != 'master':
print >>sys.stderr, 'You must be in the master git branch'
raise SystemExit(1)
def require_clean_git():
c = subprocess.check_call
p = subprocess.Popen
with open(os.devnull, 'wb') as null:
c('git rev-parse --verify HEAD'.split(), stdout=null)
c('git update-index -q --ignore-submodules --refresh'.split())
if p('git diff-files --quiet --ignore-submodules'.split()).wait() != 0:
print >>sys.stderr, 'You have unstaged changes in your working tree'
raise SystemExit(1)
if p('git diff-index --cached --quiet --ignore-submodules HEAD --'.split()).wait() != 0:
print >>sys.stderr, 'Your git index contains uncommitted changes'
raise SystemExit(1)
def initialize_constants(): def initialize_constants():
global __version__, __appname__, modules, functions, basenames, scripts global __version__, __appname__, modules, functions, basenames, scripts
@ -158,7 +176,6 @@ class Command(object):
self.running(cmd) self.running(cmd)
cmd.run(opts) cmd.run(opts)
def run_all(self, opts): def run_all(self, opts):
self.run_cmd(self, opts) self.run_cmd(self, opts)
@ -171,11 +188,9 @@ class Command(object):
command.add_options(parser) command.add_options(parser)
def add_all_options(self, parser): def add_all_options(self, parser):
self.add_command_options(self, parser) self.add_command_options(self, parser)
def run(self, opts): def run(self, opts):
pass pass
@ -230,3 +245,4 @@ def installer_name(ext, is64bit=False):
return ans return ans

View File

@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
import os, shutil, subprocess, glob import os, shutil, subprocess, glob
from setup import Command, __appname__, __version__ from setup import Command, __appname__, __version__, require_clean_git, require_git_master
class Stage1(Command): class Stage1(Command):
@ -60,6 +60,10 @@ class Publish(Command):
description = 'Publish a new calibre release' description = 'Publish a new calibre release'
sub_commands = ['stage1', 'stage2', 'stage3', 'stage4', 'stage5', ] sub_commands = ['stage1', 'stage2', 'stage3', 'stage4', 'stage5', ]
def pre_sub_commands(self, opts):
require_git_master()
require_clean_git()
class Manual(Command): class Manual(Command):
description='''Build the User Manual ''' description='''Build the User Manual '''

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import os, tempfile, shutil, subprocess, glob, re, time, textwrap import os, tempfile, shutil, subprocess, glob, re, time, textwrap
from functools import partial from functools import partial
from setup import Command, __appname__, __version__ from setup import Command, __appname__, __version__, require_git_master
def qt_sources(): def qt_sources():
qtdir = glob.glob('/usr/src/qt-*')[-1] qtdir = glob.glob('/usr/src/qt-*')[-1]
@ -20,8 +20,24 @@ def qt_sources():
class POT(Command): # {{{ class POT(Command): # {{{
description = 'Update the .pot translation template' description = 'Update the .pot translation template and upload it'
PATH = os.path.join(Command.SRC, __appname__, 'translations') POT_PATH = os.path.join(__appname__, 'translations')
PATH = os.path.join(Command.SRC, POT_PATH)
LP_SRC = os.path.join(os.path.dirname(os.path.dirname(Command.SRC)), 'calibre-translations', 'src')
LP_PATH = os.path.join(LP_SRC, POT_PATH)
def upload_pot(self, pot):
upot = os.path.join(self.LP_PATH, os.path.basename(pot))
with open(pot, 'rb') as src, open(upot, 'wb') as dest:
shutil.copyfileobj(src, dest)
if subprocess.check_output(['git', 'status', '-z', pot]):
# pot has changed
msg = 'Updated translations template'
subprocess.check_call(['bzr', 'commit', '-m', msg, upot])
subprocess.check_call(['git', 'commit', '-m', msg, pot])
subprocess.check_call(['git', 'push'])
else:
print ('No updated translations')
def source_files(self): def source_files(self):
ans = [] ans = []
@ -64,6 +80,7 @@ class POT(Command): # {{{
return '\n'.join(ans) return '\n'.join(ans)
def run(self, opts): def run(self, opts):
require_git_master()
pot_header = textwrap.dedent('''\ pot_header = textwrap.dedent('''\
# Translation template file.. # Translation template file..
# Copyright (C) %(year)s Kovid Goyal # Copyright (C) %(year)s Kovid Goyal
@ -115,6 +132,7 @@ class POT(Command): # {{{
with open(pot, 'wb') as f: with open(pot, 'wb') as f:
f.write(src) f.write(src)
self.info('Translations template:', os.path.abspath(pot)) self.info('Translations template:', os.path.abspath(pot))
self.upload_pot(os.path.abspath(pot))
return pot return pot
# }}} # }}}
@ -241,11 +259,12 @@ class GetTranslations(Translations): # {{{
description = 'Get updated translations from Launchpad' description = 'Get updated translations from Launchpad'
BRANCH = 'lp:~kovid/calibre/translations' BRANCH = 'lp:~kovid/calibre/translations'
LP_BASE = os.path.dirname(POT.LP_SRC)
CMSG = 'Updated translations'
@property @property
def modified_translations(self): def modified_translations(self):
raw = subprocess.Popen(['bzr', 'status', '-S', self.PATH], raw = subprocess.check_output(['bzr', 'status', '-S', self.LP_PATH]).strip()
stdout=subprocess.PIPE).stdout.read().strip()
ans = [] ans = []
for line in raw.splitlines(): for line in raw.splitlines():
line = line.strip() line = line.strip()
@ -255,34 +274,49 @@ class GetTranslations(Translations): # {{{
def resolve_conflicts(self): def resolve_conflicts(self):
conflict = False conflict = False
for line in subprocess.check_output(['bzr', 'status']).splitlines(): for line in subprocess.check_output(['bzr', 'status'], cwd=self.LP_BASE).splitlines():
if line == 'conflicts:': if line == 'conflicts:':
conflict = True conflict = True
break break
if not conflict: if not conflict:
raise Exception('bzr merge failed and no conflicts found') raise Exception('bzr merge failed and no conflicts found')
subprocess.check_call(['bzr', 'resolve', '--take-other']) subprocess.check_call(['bzr', 'resolve', '--take-other'], cwd=self.LP_BASE)
def run(self, opts): def run(self, opts):
require_git_master()
if not self.modified_translations: if not self.modified_translations:
try: try:
subprocess.check_call(['bzr', 'merge', self.BRANCH]) subprocess.check_call(['bzr', 'merge', self.BRANCH], cwd=self.LP_BASE)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
self.resolve_conflicts() self.resolve_conflicts()
self.check_for_errors() self.check_for_errors()
if self.modified_translations: if self.modified_translations:
subprocess.check_call(['bzr', 'commit', '-m', subprocess.check_call(['bzr', 'commit', '-m',
'IGN:Updated translations']) self.CMSG], cwd=self.LP_BASE)
self.copy_translations()
else: else:
print('No updated translations available') print('No updated translations available')
def copy_translations(self):
changed = set()
for src in glob.glob(os.path.join(self.LP_PATH, '*.po')):
dest = os.path.join(self.PATH, os.path.basename(src))
with open(src, 'rb') as fsrc, open(dest, 'wb') as fdst:
shutil.copyfileobj(fsrc, fdst)
if subprocess.check_output(['git', 'status', '-z', dest]):
changed.add(dest)
if changed:
subprocess.check_call(['git', 'commit', '--author', 'Translators',
'-m', self.CMSG] + list(changed))
subprocess.check_call(['git', 'push'])
def check_for_errors(self): def check_for_errors(self):
errors = os.path.join(tempfile.gettempdir(), 'calibre-translation-errors') errors = os.path.join(tempfile.gettempdir(), 'calibre-translation-errors')
if os.path.exists(errors): if os.path.exists(errors):
shutil.rmtree(errors) shutil.rmtree(errors)
os.mkdir(errors) os.mkdir(errors)
pofilter = ('pofilter', '-i', self.PATH, '-o', errors, pofilter = ('pofilter', '-i', self.LP_PATH, '-o', errors,
'-t', 'accelerators', '-t', 'escapes', '-t', 'variables', '-t', 'accelerators', '-t', 'escapes', '-t', 'variables',
#'-t', 'xmltags', #'-t', 'xmltags',
#'-t', 'brackets', #'-t', 'brackets',
@ -305,8 +339,8 @@ class GetTranslations(Translations): # {{{
f.truncate() f.truncate()
f.write(raw) f.write(raw)
subprocess.check_call(['pomerge', '-t', self.PATH, '-i', errors, '-o', subprocess.check_call(['pomerge', '-t', self.LP_PATH, '-i', errors, '-o',
self.PATH]) self.LP_PATH])
return True return True
return False return False