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) ) | ||||
|         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): | ||||
|     bo = buildbase() | ||||
|  | ||||
| @@ -509,6 +538,8 @@ def buildGRAMPS( base, out_dir, bTarball): | ||||
|             bo.generateConstPy( )  | ||||
|             bo.copyExtraFilesToBuildDir(base) | ||||
|          | ||||
|         if bPatchBuild: | ||||
|             bo.copyPatchTreeToDest( patch_dir, bo.build_root ) | ||||
|         if bBuildAll: | ||||
|             bo.processPO( ) | ||||
|         if bo.bBuildInstaller: | ||||
| @@ -536,6 +567,12 @@ Options: | ||||
|             --nsis_only           Build NSIS only (does not Clean & Build All) | ||||
|     -t      --tarball             Build release version from Tarball. | ||||
|     -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: svn_dir  option - a path to svn (for occasions script cannot work it out) | ||||
| @@ -547,10 +584,11 @@ Options: | ||||
|     bBuildInstaller = True | ||||
|     bTarball = False | ||||
|     msg_dir = "" | ||||
|      | ||||
|     bPatchBuild = False | ||||
|     patch_dir = "" | ||||
|     try: | ||||
|         opts, args = getopt.getopt(sys.argv[1:], "ho:tm:", | ||||
|                                   ["help", "out=", "nsis_only", "tarball", "msgdir="]) | ||||
|         opts, args = getopt.getopt(sys.argv[1:], "ho:tm:p:", | ||||
|                                   ["help", "out=", "nsis_only", "tarball", "msgdir=", "patch="]) | ||||
|  | ||||
|         for o, a in opts: | ||||
|             if o in ("-h", "--help"): | ||||
| @@ -569,12 +607,21 @@ Options: | ||||
|                     msg_dir =  a | ||||
|                 else: | ||||
|                     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 | ||||
|             repository_path = path.normpath(args[0]) | ||||
|         else:   # no base dir passed in, work out one from current working dir | ||||
|             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' | ||||
|  | ||||
|         if len(args) > 1: | ||||
|   | ||||
| @@ -377,6 +377,16 @@ Function TestDependancies | ||||
| ;    MessageBox MB_OK "python: $PythonVerText $\ngtk++: $GTKVerText $\npygtk: $pyGTKVerText$\ngobject: $GObjectVerText$\ncario: $CairoVerText" | ||||
| 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_SUBTITLE ${LANG_ENGLISH} "" | ||||
| Var Dialog | ||||
| @@ -405,9 +415,9 @@ Function DependenciesPageFunction | ||||
|     !insertmacro MUI_HEADER_TEXT $(PAGE_TITLE) $(PAGE_SUBTITLE) | ||||
|     nsDialogs::Create  /NOUNLOAD 1018  | ||||
|     Pop $Dialog | ||||
| 	${If} $Dialog == error | ||||
| 		Abort | ||||
| 	${EndIf} | ||||
|     ${If} $Dialog == error | ||||
|         Abort | ||||
|     ${EndIf} | ||||
|      | ||||
|     SetOutPath $TEMP | ||||
|      | ||||
| @@ -561,6 +571,7 @@ Section "MainSection" SEC01 | ||||
|     File /r ${GRAMPS_BUILD_PATH}\*.* | ||||
|     WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "" "$INSTDIR" | ||||
|     WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "version" ${PRODUCT_VERSION} | ||||
|     Call WriteGrampsLauncher | ||||
| SectionEnd | ||||
|  | ||||
|  | ||||
| @@ -674,8 +685,12 @@ Section -AdditionalIcons | ||||
|     SetOutPath $INSTDIR | ||||
|     WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" | ||||
|     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 | ||||
|     #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}\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" | ||||
|     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