Tools: Add Windows and Qt6 support to updatets.py

This commit is contained in:
Chris Hennes
2022-06-01 21:30:12 -05:00
parent d860c4bb2d
commit 213bf1ec61

View File

@@ -26,6 +26,7 @@
#***************************************************************************
# Changelog:
# 0.5 Add support for Qt 6 lupdate (which fixes MANY bugs and should be preferred)
# 0.4 Refactor to always try both C++ and Python translations
# 0.3 User-friendly output
# Corrections
@@ -47,10 +48,13 @@ Authors:
Licence: LGPL
Version:
0.4
0.5
"""
import os, sys
import subprocess
import re
import pathlib
directories = [
{"tsname":"FreeCAD", "workingdir":"./src/Gui", "tsdir":"Language"},
@@ -84,46 +88,63 @@ QMAKE = ""
LUPDATE = ""
PYLUPDATE = ""
LCONVERT = ""
QT_VERSION = ""
def find_tools(noobsolete=True):
print(Usage + "\nFirst, lets find all necessary tools on your system")
global QMAKE, LUPDATE, PYLUPDATE, LCONVERT
if (os.system("qmake -version") == 0):
QMAKE = "qmake"
elif (os.system("qmake-qt5 -version") == 0):
QMAKE = "qmake-qt5"
global QMAKE, LUPDATE, PYLUPDATE, LCONVERT, QT_VERSION
lupdate_version = subprocess.check_output(f"lupdate -version").decode()
QT_VERSION = int(re.search(r'.* ([456])\.', lupdate_version).group(1))
if QT_VERSION < 6:
if (os.system("lupdate -version") == 0):
LUPDATE = "lupdate"
# TODO: we suppose lupdate is a symlink to lupdate-qt4 for now
if noobsolete:
LUPDATE += " -no-obsolete"
elif (os.system("lupdate-qt5 -version") == 0):
LUPDATE = "lupdate-qt5"
if noobsolete:
LUPDATE += " -no-obsolete"
else:
raise Exception("Cannot find lupdate")
else:
raise Exception("Cannot find qmake")
if (os.system("lupdate -version") == 0):
LUPDATE = "lupdate"
# TODO: we suppose lupdate is a symlink to lupdate-qt4 for now
if noobsolete:
LUPDATE += " -no-obsolete"
elif (os.system("lupdate-qt5 -version") == 0):
LUPDATE = "lupdate-qt5"
if noobsolete:
LUPDATE += " -no-obsolete"
lupdate_version = subprocess.check_output(f"{LUPDATE} -version").decode()
QT_VERSION = int(re.search(r'.* ([456])\.', lupdate_version).group(1))
if QT_VERSION < 6:
if (os.system("qmake -version") == 0):
QMAKE = "qmake"
elif (os.system("qmake-qt5 -version") == 0):
QMAKE = "qmake-qt5"
else:
raise Exception("Cannot find qmake")
if (os.system("pylupdate -version") == 0):
PYLUPDATE = "pylupdate"
elif (os.system("pylupdate5 -version") == 0):
PYLUPDATE = "pylupdate5"
if noobsolete:
PYLUPDATE += " -noobsolete"
elif (os.system("pylupdate4 -version") == 0):
PYLUPDATE = "pylupdate4"
if noobsolete:
PYLUPDATE += " -noobsolete"
elif (os.system("pyside2-lupdate -version") == 0):
PYLUPDATE = "pyside2-lupdate"
raise Exception("Please do not use pyside2-lupdate at the moment, as it shows encoding problems. Please use pylupdate5 instead.")
else:
raise Exception("Cannot find pylupdate")
else:
raise Exception("Cannot find lupdate")
if (os.system("pylupdate -version") == 0):
PYLUPDATE = "pylupdate"
elif (os.system("pylupdate5 -version") == 0):
PYLUPDATE = "pylupdate5"
if noobsolete:
PYLUPDATE += " -noobsolete"
elif (os.system("pylupdate4 -version") == 0):
PYLUPDATE = "pylupdate4"
if noobsolete:
PYLUPDATE += " -noobsolete"
elif (os.system("pyside2-lupdate -version") == 0):
PYLUPDATE = "pyside2-lupdate"
raise Exception("Please do not use pyside2-lupdate at the moment, as it shows encoding problems. Please use pylupdate5 instead.")
else:
raise Exception("Cannot find pylupdate")
QMAKE = "(qmake not needed for Qt 6 and later)"
PYLUPDATE = "(pylupdate not needed for Qt 6 and later)"
if (os.system("lconvert -h") == 0):
LCONVERT = "lconvert"
if noobsolete:
if noobsolete and QT_VERSION < 6:
LCONVERT += " -no-obsolete"
else:
raise Exception("Cannot find lconvert")
@@ -136,10 +157,7 @@ def find_tools(noobsolete=True):
def update_translation(entry):
global QMAKE, LUPDATE
print ("\n\n=============================================")
print (f"EXTRACTING STRINGS FOR {entry['tsname']}")
print ("=============================================")
global QMAKE, LUPDATE, LCONVERT, QT_VERSION
cur = os.getcwd()
log_redirect = f" 2>> {cur}/tsupdate_stderr.log 1>> {cur}/tsupdate_stdout.log"
os.chdir(entry["workingdir"])
@@ -147,28 +165,57 @@ def update_translation(entry):
project_filename = entry["tsname"] + ".pro"
tsBasename = os.path.join(entry["tsdir"],entry["tsname"])
execline = []
execline.append (f"touch dummy_cpp_file_for_lupdate.cpp") #lupdate requires at least one source file to process the UI files
execline.append (f"{QMAKE} -project -o {project_filename} -r")
execline.append (f"{LUPDATE} {project_filename} -ts {tsBasename}.ts {log_redirect}")
execline.append (f"sed 's/<translation.*>.*<\/translation>/<translation type=\"unfinished\"><\/translation>/g' {tsBasename}.ts > {tsBasename}.ts.temp")
execline.append (f"mv {tsBasename}.ts.temp {tsBasename}.ts")
execline.append (f"{PYLUPDATE} `find ./ -name \"*.py\"` -ts {tsBasename}py.ts {log_redirect}")
execline.append (f"{LCONVERT} -i {tsBasename}py.ts {tsBasename}.ts -o {tsBasename}.ts {log_redirect}")
execline.append (f"rm {tsBasename}py.ts")
execline.append (f"rm dummy_cpp_file_for_lupdate.cpp")
print(f"Executing commands in {entry['workingdir']}:")
for line in execline:
print (line)
os.system(line)
print()
if QT_VERSION < 6:
print ("\n\n=============================================")
print (f"EXTRACTING STRINGS FOR {entry['tsname']}")
print ("=============================================",flush=True)
execline = []
execline.append (f"touch dummy_cpp_file_for_lupdate.cpp") #lupdate 5.x requires at least one source file to process the UI files
execline.append (f"{QMAKE} -project -o {project_filename} -r")
execline.append (f"{LUPDATE} {project_filename} -ts {tsBasename}.ts {log_redirect}")
execline.append (f"sed 's/<translation.*>.*<\/translation>/<translation type=\"unfinished\"><\/translation>/g' {tsBasename}.ts > {tsBasename}.ts.temp")
execline.append (f"mv {tsBasename}.ts.temp {tsBasename}.ts")
execline.append (f"{PYLUPDATE} `find ./ -name \"*.py\"` -ts {tsBasename}py.ts {log_redirect}")
execline.append (f"{LCONVERT} -i {tsBasename}py.ts {tsBasename}.ts -o {tsBasename}.ts {log_redirect}")
execline.append (f"rm {tsBasename}py.ts")
execline.append (f"rm dummy_cpp_file_for_lupdate.cpp")
print(f"Executing commands in {entry['workingdir']}:")
for line in execline:
print (line)
os.system(line)
print()
os.remove(project_filename)
# lupdate creates json files since Qt5.something. Remove them here too
for jsonfile in [f for f in os.listdir(".") if f.endswith(".json")]:
if not jsonfile in existingjsons:
os.remove(jsonfile)
elif QT_VERSION == 6:
# In Qt6, QMake project files are deprecated, and lupdate directly scans for source files. The same executable is
# used for all supported programming languages, so it's just a single function call
# For Windows compatibility, do most of the work in Python:
try:
print (f"Extracting recursively for {entry['tsname']} starting at {entry['workingdir']} into {tsBasename}.ts",flush=True)
p = subprocess.run([LUPDATE, "./","-I","./", "-recursive", "-ts", f"{tsBasename}.ts"], capture_output=True, timeout=60)
except Exception as e:
print(str(e))
with open (f"{cur}/tsupdate_stdout.log","a") as f:
f.write(p.stdout.decode())
print(p.stdout.decode())
with open (f"{cur}/tsupdate_stderr.log","a") as f:
f.write(p.stderr.decode())
# Strip out obsolete strings, and make sure there are no translations in the main *.ts file
subprocess.run([LCONVERT, "-drop-translations", "-i", f"{tsBasename}.ts", "-o", f"{tsBasename}.ts"])
else:
print("ERROR: unrecognized version of lupdate -- found Qt {QT_VERSION}, we only support 4, 5 and 6")
exit(1)
os.remove(project_filename)
# lupdate creates json files since Qt5.something. Remove them here too
for jsonfile in [f for f in os.listdir(".") if f.endswith(".json")]:
if not jsonfile in existingjsons:
os.remove(jsonfile)
os.chdir(cur)
def main(mod=None):