Windows: Provide ability to patch a release version installer
Windows: Generate a locale dependent launcher svn: r15347
This commit is contained in:
@ -478,6 +478,35 @@ class buildbase(gobject.GObject):
|
|||||||
log.debug( 'Version (%s)' % (vers) )
|
log.debug( 'Version (%s)' % (vers) )
|
||||||
return vers
|
return vers
|
||||||
|
|
||||||
|
def copyPatchTreeToDest(self, src, dst):
|
||||||
|
'''Patch a tarball build with alternate files as required.
|
||||||
|
At this stage do not allow new directories to be made or
|
||||||
|
new files to be added, just replace existing files.
|
||||||
|
'''
|
||||||
|
log.info('Patching: now in %s', src)
|
||||||
|
names = os.listdir(src)
|
||||||
|
#os.makedirs(dst) - not creating new dir
|
||||||
|
errors = []
|
||||||
|
for name in names:
|
||||||
|
srcname = os.path.join(src, name)
|
||||||
|
dstname = os.path.join(dst, name)
|
||||||
|
try:
|
||||||
|
if os.path.isfile(srcname) and os.path.isfile(dstname):
|
||||||
|
log.info('Overwriting %s -> %s' % (srcname, dstname))
|
||||||
|
shutil.copyfile(srcname, dstname)
|
||||||
|
elif os.path.isdir(srcname) and os.path.isdir(dstname):
|
||||||
|
self.copyPatchTreeToDest(srcname, dstname)
|
||||||
|
else:
|
||||||
|
log.error('UNDEFINED: %s -> %s' % (srcname, dstname))
|
||||||
|
except (IOError, os.error), why:
|
||||||
|
errors.append((srcname, dstname, str(why)))
|
||||||
|
# catch the Error from the recursive copytree so that we can
|
||||||
|
# continue with other files
|
||||||
|
except Error, err:
|
||||||
|
errors.extend(err.args[0])
|
||||||
|
if errors:
|
||||||
|
raise Error(errors)
|
||||||
|
|
||||||
def buildGRAMPS( base, out_dir, bTarball):
|
def buildGRAMPS( base, out_dir, bTarball):
|
||||||
bo = buildbase()
|
bo = buildbase()
|
||||||
|
|
||||||
@ -509,6 +538,8 @@ def buildGRAMPS( base, out_dir, bTarball):
|
|||||||
bo.generateConstPy( )
|
bo.generateConstPy( )
|
||||||
bo.copyExtraFilesToBuildDir(base)
|
bo.copyExtraFilesToBuildDir(base)
|
||||||
|
|
||||||
|
if bPatchBuild:
|
||||||
|
bo.copyPatchTreeToDest( patch_dir, bo.build_root )
|
||||||
if bBuildAll:
|
if bBuildAll:
|
||||||
bo.processPO( )
|
bo.processPO( )
|
||||||
if bo.bBuildInstaller:
|
if bo.bBuildInstaller:
|
||||||
@ -536,6 +567,12 @@ Options:
|
|||||||
--nsis_only Build NSIS only (does not Clean & Build All)
|
--nsis_only Build NSIS only (does not Clean & Build All)
|
||||||
-t --tarball Build release version from Tarball.
|
-t --tarball Build release version from Tarball.
|
||||||
-mDIR, --msgdir=DIR Directory to msgfmt.exe
|
-mDIR, --msgdir=DIR Directory to msgfmt.exe
|
||||||
|
-pDIR, --patch=DIR Specify a directory to patch files into the build.
|
||||||
|
only valid for a tarball build.
|
||||||
|
This directory will allow you to patch the release after expanding
|
||||||
|
from tarball and before creating installer.
|
||||||
|
(n.b. each file to be replaced needs to be specified with full path
|
||||||
|
to exactly mimic the paths in the expanded tarball)
|
||||||
'''
|
'''
|
||||||
# TODO: nsis_dir option - a path to nsismake (for occasions script cannot work it out)
|
# TODO: nsis_dir option - a path to nsismake (for occasions script cannot work it out)
|
||||||
# TODO: svn_dir option - a path to svn (for occasions script cannot work it out)
|
# TODO: svn_dir option - a path to svn (for occasions script cannot work it out)
|
||||||
@ -547,10 +584,11 @@ Options:
|
|||||||
bBuildInstaller = True
|
bBuildInstaller = True
|
||||||
bTarball = False
|
bTarball = False
|
||||||
msg_dir = ""
|
msg_dir = ""
|
||||||
|
bPatchBuild = False
|
||||||
|
patch_dir = ""
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "ho:tm:",
|
opts, args = getopt.getopt(sys.argv[1:], "ho:tm:p:",
|
||||||
["help", "out=", "nsis_only", "tarball", "msgdir="])
|
["help", "out=", "nsis_only", "tarball", "msgdir=", "patch="])
|
||||||
|
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o in ("-h", "--help"):
|
if o in ("-h", "--help"):
|
||||||
@ -569,12 +607,21 @@ Options:
|
|||||||
msg_dir = a
|
msg_dir = a
|
||||||
else:
|
else:
|
||||||
raise getopt.GetoptError, '\nERROR: msgfmt dir does not exist'
|
raise getopt.GetoptError, '\nERROR: msgfmt dir does not exist'
|
||||||
|
if o in ("-p", "--patch"):
|
||||||
|
if os.path.isdir( a ):
|
||||||
|
patch_dir = a
|
||||||
|
bPatchBuild = True
|
||||||
|
else:
|
||||||
|
raise getopt.GetoptError, '\nERROR: Patch directory does not exist'
|
||||||
|
|
||||||
if args: #got args use first one as base dir
|
if args: #got args use first one as base dir
|
||||||
repository_path = path.normpath(args[0])
|
repository_path = path.normpath(args[0])
|
||||||
else: # no base dir passed in, work out one from current working dir
|
else: # no base dir passed in, work out one from current working dir
|
||||||
repository_path = path.normpath("%s/../.." % os.getcwd() )
|
repository_path = path.normpath("%s/../.." % os.getcwd() )
|
||||||
|
|
||||||
|
if bPatchBuild and not bTarball:
|
||||||
|
log.warning("Cannot specify patch for SVN build, resetting patch option")
|
||||||
|
patch_dir = None
|
||||||
# raise getopt.GetoptError, '\nERROR: No base directory specified'
|
# raise getopt.GetoptError, '\nERROR: No base directory specified'
|
||||||
|
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
|
@ -377,6 +377,16 @@ Function TestDependancies
|
|||||||
; MessageBox MB_OK "python: $PythonVerText $\ngtk++: $GTKVerText $\npygtk: $pyGTKVerText$\ngobject: $GObjectVerText$\ncario: $CairoVerText"
|
; MessageBox MB_OK "python: $PythonVerText $\ngtk++: $GTKVerText $\npygtk: $pyGTKVerText$\ngobject: $GObjectVerText$\ncario: $CairoVerText"
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
Function WriteGrampsLauncher
|
||||||
|
SetOutPath $TEMP
|
||||||
|
|
||||||
|
File make_launcher.py
|
||||||
|
nsExec::ExecToStack '"$PythonExe" $TEMP\make_launcher.py'
|
||||||
|
Pop $0 # return value/error/timeout
|
||||||
|
Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
|
||||||
LangString PAGE_TITLE ${LANG_ENGLISH} "Summary of GRAMP's Dependencies"
|
LangString PAGE_TITLE ${LANG_ENGLISH} "Summary of GRAMP's Dependencies"
|
||||||
LangString PAGE_SUBTITLE ${LANG_ENGLISH} ""
|
LangString PAGE_SUBTITLE ${LANG_ENGLISH} ""
|
||||||
Var Dialog
|
Var Dialog
|
||||||
@ -405,9 +415,9 @@ Function DependenciesPageFunction
|
|||||||
!insertmacro MUI_HEADER_TEXT $(PAGE_TITLE) $(PAGE_SUBTITLE)
|
!insertmacro MUI_HEADER_TEXT $(PAGE_TITLE) $(PAGE_SUBTITLE)
|
||||||
nsDialogs::Create /NOUNLOAD 1018
|
nsDialogs::Create /NOUNLOAD 1018
|
||||||
Pop $Dialog
|
Pop $Dialog
|
||||||
${If} $Dialog == error
|
${If} $Dialog == error
|
||||||
Abort
|
Abort
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
SetOutPath $TEMP
|
SetOutPath $TEMP
|
||||||
|
|
||||||
@ -561,6 +571,7 @@ Section "MainSection" SEC01
|
|||||||
File /r ${GRAMPS_BUILD_PATH}\*.*
|
File /r ${GRAMPS_BUILD_PATH}\*.*
|
||||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "" "$INSTDIR"
|
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "" "$INSTDIR"
|
||||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "version" ${PRODUCT_VERSION}
|
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "version" ${PRODUCT_VERSION}
|
||||||
|
Call WriteGrampsLauncher
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
|
|
||||||
@ -674,8 +685,12 @@ Section -AdditionalIcons
|
|||||||
SetOutPath $INSTDIR
|
SetOutPath $INSTDIR
|
||||||
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
|
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
|
||||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||||
|
|
||||||
|
IfFileExists '$INSTDIR\gramps_locale.cmd' 0 NoLocaleFile
|
||||||
# $3 should contain the path to python, .. then pass gramps.py as an argument
|
# $3 should contain the path to python, .. then pass gramps.py as an argument
|
||||||
#CreateShortCut link.lnk target.file [parameters [icon.file [icon_index_number [start_options[keyboard_shortcut [description]]]]]]
|
#CreateShortCut link.lnk target.file [parameters [icon.file [icon_index_number [start_options[keyboard_shortcut [description]]]]]]
|
||||||
|
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} (locale) ${PRODUCT_VERSION}.lnk" CMD "/C $\"$INSTDIR\gramps_locale.cmd$\"" "$INSTDIR\images\ped24.ico" "0" "" "" "GRAMPS"
|
||||||
|
NoLocaleFile:
|
||||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} ${PRODUCT_VERSION}.lnk" "$3" "$\"$INSTDIR\gramps.py$\"" "$INSTDIR\images\ped24.ico" "0" "" "" "GRAMPS"
|
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} ${PRODUCT_VERSION}.lnk" "$3" "$\"$INSTDIR\gramps.py$\"" "$INSTDIR\images\ped24.ico" "0" "" "" "GRAMPS"
|
||||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
|
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
|
||||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
||||||
|
149
windows/builder/make_launcher.py
Normal file
149
windows/builder/make_launcher.py
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
# SetLanguage.py
|
||||||
|
#
|
||||||
|
# Gramps - a GTK+ based genealogy program
|
||||||
|
#
|
||||||
|
# Copyright (C) 2010 Stephen George
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# $Id: $
|
||||||
|
import locale
|
||||||
|
import _winreg
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logging.basicConfig(level=logging.DEBUG,
|
||||||
|
format='%(asctime)s %(name)-10s %(levelname)-8s %(message)s',
|
||||||
|
datefmt='%H:%M',
|
||||||
|
filename= 'c:/launcher.log', #path.join(out_dir,'build.log'),
|
||||||
|
filemode='w')
|
||||||
|
#create a Handler for the console
|
||||||
|
console = logging.StreamHandler()
|
||||||
|
console.setLevel(logging.INFO)
|
||||||
|
#Set a simle format for console
|
||||||
|
formatter = logging.Formatter('%(levelname)-8s %(message)s')
|
||||||
|
console.setFormatter(formatter)
|
||||||
|
#add the console handler to the root handler
|
||||||
|
log = logging.getLogger('BuildApp')
|
||||||
|
log.addHandler(console)
|
||||||
|
|
||||||
|
|
||||||
|
langLookup = {
|
||||||
|
'ar' : 'Arabic',
|
||||||
|
'bg' : 'Bulgarian',
|
||||||
|
'ca' : 'Catalan',
|
||||||
|
'cs' : 'Czech',
|
||||||
|
'da' : 'Danish ',
|
||||||
|
'de' : 'German',
|
||||||
|
'en' : 'English',
|
||||||
|
'eo' : '',
|
||||||
|
'es' : 'Spanish',
|
||||||
|
'fi' : 'Finnish',
|
||||||
|
'fr' : 'French',
|
||||||
|
'he' : 'Hebrew',
|
||||||
|
'hr' : 'Croatian',
|
||||||
|
'hu' : 'Hungarian',
|
||||||
|
'it' : 'Italian',
|
||||||
|
'lt' : 'Lithuanian',
|
||||||
|
'mk' : 'Macedonian',
|
||||||
|
'nb' : '',
|
||||||
|
'nl' : 'Dutch',
|
||||||
|
'nn' : '',
|
||||||
|
'pl' : 'Polish',
|
||||||
|
'pt_BR' : 'Portuguese (Brazil)',
|
||||||
|
'ro' : 'Romanian',
|
||||||
|
'ru' : 'Russian',
|
||||||
|
'sk' : 'Slovak',
|
||||||
|
'sl' : 'Slovenian',
|
||||||
|
'sq' : 'Albanian',
|
||||||
|
'sr' : 'Serbian',
|
||||||
|
'sv' : 'Swedish',
|
||||||
|
'tr' : 'Turkish',
|
||||||
|
'zh_CN' : 'Chinese (PRC)',
|
||||||
|
}
|
||||||
|
|
||||||
|
def GetGtkPath():
|
||||||
|
log.debug('GetGtkPath()')
|
||||||
|
dllPathInRegistry = None
|
||||||
|
try:
|
||||||
|
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\GTK\\2.0') as key:
|
||||||
|
dllPathInRegistry = _winreg.QueryValueEx(key, 'DllPath')[0]
|
||||||
|
# check a few key files exist at this location
|
||||||
|
gtkfiles = ['libgdk-win32-2.0-0.dll', 'libglib-2.0-0.dll', 'libgobject-2.0-0.dll', 'libcairo-2.dll']
|
||||||
|
for file in gtkfiles:
|
||||||
|
if not os.path.isfile(os.path.join(dllPathInRegistry, file)):
|
||||||
|
dllPathInRegistry = None # one of the files not present, so assume path is wrong
|
||||||
|
break
|
||||||
|
except WindowsError, e:
|
||||||
|
dllPathInRegistry = None
|
||||||
|
log.debug(' DLLPATH=%s'%dllPathInRegistry)
|
||||||
|
return dllPathInRegistry
|
||||||
|
|
||||||
|
def GetGrampsPath():
|
||||||
|
GrampsPathInRegistry = None
|
||||||
|
try:
|
||||||
|
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\GRAMPS') as key:
|
||||||
|
GrampsPathInRegistry = _winreg.QueryValue(key, '')
|
||||||
|
# check a few key files exist at this location
|
||||||
|
except WindowsError, e:
|
||||||
|
GrampsPathInRegistry = None
|
||||||
|
|
||||||
|
log.debug(' GRAMPSPATH=%s'%GrampsPathInRegistry)
|
||||||
|
return GrampsPathInRegistry
|
||||||
|
|
||||||
|
def GetLanguageFromLocale():
|
||||||
|
lang = ' '
|
||||||
|
try:
|
||||||
|
lang = os.environ["LANG"]
|
||||||
|
lang = lang.split('.')[0]
|
||||||
|
except:
|
||||||
|
# if LANG is not set
|
||||||
|
lang = locale.getlocale()[0]
|
||||||
|
if not lang:
|
||||||
|
# if lang is empty/None
|
||||||
|
lang = locale.getdefaultlocale()[0]
|
||||||
|
return lang
|
||||||
|
|
||||||
|
def writeLauncher(language, langcode, runtimepath, grampspath):
|
||||||
|
lines = []
|
||||||
|
lines.append('\n@rem Command file to set %s language for Gramps \n' % language)
|
||||||
|
lines.append('SET LANG=$LANG$ \nSET LANGUAGE=$LANG$\n'.replace("$LANG$", langcode) )
|
||||||
|
if runtimepath:
|
||||||
|
path = '\npath="%s";%%PATH%%' % runtimepath
|
||||||
|
else:
|
||||||
|
path = "\n@rem path=PATH_TO_YOUR_GTK_RUNTIME;%%PATH%%\n"
|
||||||
|
lines.append(path)
|
||||||
|
lines.append('\n@rem start Gramps')
|
||||||
|
lines.append('\n"%s" "%s"\n' % (os.path.join(sys.prefix, 'pythonw.exe') , os.path.join(grampspath, 'gramps.py' ) ))
|
||||||
|
fout = open( os.path.join(grampspath, 'gramps_locale.cmd'), 'w')
|
||||||
|
fout.writelines(lines)
|
||||||
|
fout.close()
|
||||||
|
for line in lines:
|
||||||
|
print line
|
||||||
|
|
||||||
|
gtkpath = GetGtkPath()
|
||||||
|
grampspath = GetGrampsPath()
|
||||||
|
lang = GetLanguageFromLocale()
|
||||||
|
if lang:
|
||||||
|
try:
|
||||||
|
lang_text = langLookup[lang.split('_', 1)[0]]
|
||||||
|
except KeyError, e:
|
||||||
|
try:
|
||||||
|
lang_text = langLookup[lang]
|
||||||
|
except KeyError, e:
|
||||||
|
lang_text = "Unknown"
|
||||||
|
|
||||||
|
writeLauncher(lang_text, "%s.UTF8"%lang, gtkpath, grampspath)
|
Reference in New Issue
Block a user