616 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			616 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
# Gramps - a GTK+ based genealogy program
 | 
						|
#
 | 
						|
# Copyright (C) 2006       Brian Matherly
 | 
						|
# Copyright (C) 2008       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 os, glob, sys, shutil
 | 
						|
import string
 | 
						|
import os.path as path
 | 
						|
import subprocess
 | 
						|
 | 
						|
CONFIGURE_IN = 'configure.in'
 | 
						|
CONST_PY_IN = 'src/const.py.in'
 | 
						|
TRANSLATE_FOLDER = 'po'
 | 
						|
 | 
						|
EXTRA_FILES = [ 'COPYING', 'NEWS', 'FAQ', 'AUTHORS']
 | 
						|
 | 
						|
FULL_COLON_SUBST = "~"
 | 
						|
 | 
						|
#min required version of NSIS
 | 
						|
MIN_NSIS_VERSION = (2,42)
 | 
						|
 | 
						|
#tools used during build
 | 
						|
MAKENSIS_exe = None
 | 
						|
SVN_exe = None
 | 
						|
po_errs = []
 | 
						|
po_oks = []
 | 
						|
 | 
						|
import gobject
 | 
						|
 | 
						|
 | 
						|
#==== Set up logging system
 | 
						|
# need to also set up a logger for when run as a module.
 | 
						|
 | 
						|
# change to set up a console logger in module global space.
 | 
						|
# then add the file logger later once I know the path
 | 
						|
import logging
 | 
						|
logging.basicConfig(level=logging.DEBUG,
 | 
						|
                    format='%(asctime)s %(name)-10s %(levelname)-8s %(message)s',
 | 
						|
                    datefmt='%H:%M',
 | 
						|
                    filename= 'build.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)
 | 
						|
 | 
						|
 | 
						|
class buildbase(gobject.GObject):
 | 
						|
    __gsignals__={
 | 
						|
        "build_progresstext"        :  (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_STRING]),
 | 
						|
        "build_progressfraction"    :  (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_FLOAT]),
 | 
						|
    }
 | 
						|
 | 
						|
    def __init(self):
 | 
						|
        gobject.GObject.__init__(self)
 | 
						|
        self.gramps_version = 'VERSION-UNKNOWN'
 | 
						|
        self.bTarball = bTarball
 | 
						|
        self.build_root = '.'  # the directory were the build source is located
 | 
						|
        self.out_dir = '.'     # the directory to output final installer to, and the expand source to
 | 
						|
        self.repository_path = '.' #where the source comes from, either SVN root or a tarball
 | 
						|
        self.bBuildInstaller = True
 | 
						|
        
 | 
						|
    def getbuild_src(self):
 | 
						|
        return os.path.join(self.build_root, 'src')
 | 
						|
 | 
						|
    build_src = property(getbuild_src)
 | 
						|
 | 
						|
    def isGrampsRoot(self, root ):
 | 
						|
        log.debug( 'isGrampsRoot: %s' % root )
 | 
						|
        if path.isfile(path.join(root, CONFIGURE_IN)):
 | 
						|
            if path.isfile(path.join(root, CONST_PY_IN)):
 | 
						|
                if path.isdir(path.join(root, TRANSLATE_FOLDER)):
 | 
						|
                    return True
 | 
						|
        return False
 | 
						|
 | 
						|
    def getSVNRevision(self, dir ):
 | 
						|
        log.debug('========== getSVNRevision(%s)' % dir)
 | 
						|
        cmd = 'svnversion -n %s' % dir
 | 
						|
        log.debug( "Running: %s" % cmd )
 | 
						|
        
 | 
						|
        proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
        status = proc.wait()
 | 
						|
        output = string.strip(proc.stdout.read())
 | 
						|
        err = proc.stderr.read()
 | 
						|
        proc.stderr.close()
 | 
						|
        proc.stdout.close()
 | 
						|
        del proc
 | 
						|
        
 | 
						|
        log.debug( output )
 | 
						|
        if err:
 | 
						|
            for line in err.split('\n'):
 | 
						|
                log.error(line)
 | 
						|
            if not stdout:
 | 
						|
                output = '-UNKNOWN'
 | 
						|
        return 'SVN' + output
 | 
						|
 | 
						|
    def exportSVN(self, svn_dir, destdir):
 | 
						|
        '''
 | 
						|
        svn export PATH1 PATH2
 | 
						|
        exports a clean directory tree from the working copy specified by PATH1 into PATH2.
 | 
						|
        All local changes will be preserved, but files not under version control will not be copied.
 | 
						|
 | 
						|
        destdir cannot exist, script will clean up dir first
 | 
						|
        '''
 | 
						|
        log.debug('========== exportSVN(%s, %s)' % (svn_dir, destdir) )
 | 
						|
        cmd = '"%s" export %s %s' % (SVN_exe ,svn_dir, destdir)
 | 
						|
        log.info( "Running: %s" % cmd)
 | 
						|
        
 | 
						|
        proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
        status = proc.wait()
 | 
						|
        output = string.strip(proc.stdout.read())
 | 
						|
        err = proc.stderr.read()
 | 
						|
        proc.stderr.close()
 | 
						|
        proc.stdout.close()
 | 
						|
        del proc
 | 
						|
        
 | 
						|
        log.info( output )
 | 
						|
        if err:
 | 
						|
            log.error(err)
 | 
						|
 | 
						|
    def copyExtraFilesToBuildDir(self, source_path):
 | 
						|
        '''
 | 
						|
        A few extra files not in src directory needs to be copied to the build dir
 | 
						|
        '''
 | 
						|
        log.debug('========== copyExtraFilesToBuildDir(%s)' % (source_path))
 | 
						|
        for file in EXTRA_FILES:
 | 
						|
            outfile = file
 | 
						|
            if file == 'NEWS':
 | 
						|
                #Jump through hoops tomake sure the end of line charactors are windows format (wont work on linux!!)
 | 
						|
                outfile = 'NEWS.TXT' #Lets add .TXT suffix to filename so installer knows to call notepad 
 | 
						|
                fnews = open(os.path.join(source_path,file), 'r')
 | 
						|
                newslines = fnews.readlines()
 | 
						|
                newsout = open(os.path.join(self.build_src,outfile), 'w')
 | 
						|
                newsout.writelines(newslines)
 | 
						|
                newsout.close()
 | 
						|
                fnews.close()
 | 
						|
            else:
 | 
						|
                shutil.copy(os.path.join(source_path,file), os.path.join(self.build_src,outfile) )
 | 
						|
 | 
						|
    def compileInstallScript(self):
 | 
						|
        '''
 | 
						|
        Now we got a build directory, lets create the installation program
 | 
						|
        '''
 | 
						|
        log.debug('========== compileInstallScript()')
 | 
						|
        log.info('Compiling NullSoft install script .... be patient')
 | 
						|
        # calc path to gramps2.nsi
 | 
						|
        # need to ensure __file__ has full path, under linux it does not.
 | 
						|
        thisfilepath = os.path.abspath(__file__)
 | 
						|
        pth = os.path.relpath(os.path.dirname( thisfilepath ), os.getcwd())
 | 
						|
        pth2nsis_script = os.path.join(pth, 'gramps2.nsi') 
 | 
						|
 | 
						|
        #should tests be more along lines of os.name which returns 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
 | 
						|
        if sys.platform == 'win32':
 | 
						|
            cmd = '"%s" /V3 %s' % (MAKENSIS_exe, pth2nsis_script)
 | 
						|
        elif sys.platform == 'linux2':
 | 
						|
            #assumption makensis is installed and on the path
 | 
						|
            cmd = '%s -V3 %s' % (MAKENSIS_exe, pth2nsis_script)
 | 
						|
        
 | 
						|
        log.info( "Running: %s" % cmd)
 | 
						|
        # Need to define the following enviroment variables for NSIS script
 | 
						|
        os.environ['GRAMPS_VER'] = self.gramps_version
 | 
						|
        os.environ['GRAMPS_BUILD_DIR'] = os.path.abspath(self.build_src)
 | 
						|
        os.environ['GRAMPS_OUT_DIR'] = os.path.abspath(self.out_dir)
 | 
						|
        
 | 
						|
        proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
        status = proc.wait()
 | 
						|
        output = string.strip(proc.stdout.read())
 | 
						|
        err = proc.stderr.read()
 | 
						|
        proc.stderr.close()
 | 
						|
        proc.stdout.close()
 | 
						|
        del proc
 | 
						|
        
 | 
						|
        log.info( output )
 | 
						|
        if err:
 | 
						|
            log.error(err)
 | 
						|
 | 
						|
    def getVersionFromConfigureIn(self, repository_path):
 | 
						|
        log.debug('========== read_config_in(%s)' % repository_path)
 | 
						|
        fin = open('%s/configure.in' % repository_path, 'r')
 | 
						|
        conf_lines = fin.readlines()
 | 
						|
        fin.close()
 | 
						|
        return self.getVersionFromLines(conf_lines)
 | 
						|
        
 | 
						|
    def getVersionFromLines(self, conf_lines):
 | 
						|
        log.debug('========== getVersionFromLines()')
 | 
						|
        for line in conf_lines:
 | 
						|
            if 'AC_INIT(gramps' in line:
 | 
						|
                junk, ver, junk2 = line.split(',')
 | 
						|
            elif line[:7] == 'RELEASE':
 | 
						|
                junk,release = line.split('=')
 | 
						|
                if 'SVN$' in release:#not a release version
 | 
						|
                    release = self.getSVNRevision( repository_path )
 | 
						|
                elif not self.bTarball:  # This is aRelease, lets make sure svn working copy is prestine
 | 
						|
#                elif not bTarball:  # This is aRelease, lets make sure svn working copy is prestine
 | 
						|
                    test_num = getSVNRevision( repository_path )
 | 
						|
                    if test_num.endswith('M'): # in test_num:   #endsWith
 | 
						|
                        log.warning('*==========================================================')
 | 
						|
                        log.warning('*     Building a Release from modified SVN Working Copy    ')
 | 
						|
                        log.warning('*  ===>  Creating %s-%s from %s-%s  <==' % (ver.strip(), release.strip(),ver.strip(), test_num.strip()) )
 | 
						|
                        log.warning('*==========================================================')
 | 
						|
        gversion = '%s-%s' % (ver.strip(), release.strip())
 | 
						|
        gversion = gversion.replace(":", FULL_COLON_SUBST) # if it's a mixed version, then need to replace the : with something else
 | 
						|
        log.info( 'GrampsVersion: %s' % gversion )
 | 
						|
        return gversion
 | 
						|
 | 
						|
    def processPO( self ):
 | 
						|
        log.debug('========== processPO( )')
 | 
						|
        po_dir = os.path.join(self.build_root, "po")
 | 
						|
        mo_dir = os.path.join(self.build_src, "lang")
 | 
						|
        if not os.path.exists(mo_dir):
 | 
						|
            os.makedirs(mo_dir)
 | 
						|
        #TODO: find a better way to handle  different platforms
 | 
						|
        if sys.platform == 'win32':
 | 
						|
            po_files = glob.glob(po_dir + "\*.po")
 | 
						|
            # no longer using python msgfmt as it doesn't handle plurals (april 2010)
 | 
						|
            # msgfmtCmd = path.normpath(path.join(sys.prefix, "Tools/i18n/msgfmt.py") )
 | 
						|
            
 | 
						|
            # GetText Win 32 obtained from http://gnuwin32.sourceforge.net/packages/gettext.htm
 | 
						|
            # ....\gettext\bin\msgfmt.exe needs to be on the path
 | 
						|
            msgfmtCmd = 'msgfmt.exe'
 | 
						|
            #print 'msgfmtCmd = %s' % msgfmtCmd
 | 
						|
        elif sys.platform == 'linux2':
 | 
						|
            po_files = glob.glob(po_dir + "/*.po")
 | 
						|
            msgfmtCmd = "%s/bin/msgfmt" % sys.prefix
 | 
						|
        else:
 | 
						|
            po_files = [] #empty list
 | 
						|
            msgfmtCmd = "UNKNOWN_PLATFORM"
 | 
						|
        log.debug( msgfmtCmd )
 | 
						|
        #if not os.path.exists(msgfmtCmd):
 | 
						|
        #    log.error( "msgfmt not found - unable to generate mo files")
 | 
						|
        #    return
 | 
						|
        log.info( "Generating mo files" )
 | 
						|
        global po_errs, po_oks 
 | 
						|
        po_total = len(po_files)
 | 
						|
        po_count = 0 
 | 
						|
        for po_file in po_files:
 | 
						|
            po_count = po_count + 1
 | 
						|
            #This will be interesting
 | 
						|
            self.emit("build_progresstext", 'compiling %s' % po_file)
 | 
						|
            self.emit("build_progressfraction", po_count/po_total)
 | 
						|
 | 
						|
            lan = os.path.basename(po_file).replace( ".po", "" )
 | 
						|
            lan_path = os.path.join(mo_dir,lan,"LC_MESSAGES")
 | 
						|
            if not os.path.exists(lan_path):
 | 
						|
                os.makedirs(lan_path)
 | 
						|
            mo_file = os.path.join(lan_path,"gramps.mo")
 | 
						|
            log.info( mo_file )
 | 
						|
 | 
						|
            cmd = "%s --statistics -o %s %s" % (msgfmtCmd, mo_file, po_file)
 | 
						|
            #log.debug( cmd )
 | 
						|
            
 | 
						|
            proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
            status = proc.wait()
 | 
						|
            output = string.strip(proc.stdout.read())
 | 
						|
            err = proc.stderr.read()
 | 
						|
            proc.stderr.close()
 | 
						|
            proc.stdout.close()
 | 
						|
            del proc
 | 
						|
            
 | 
						|
            # log.debug( output ) Nothing coming out here, statistics come out stderr ??
 | 
						|
            if err:
 | 
						|
                log.info(err) # statistics comming out stderr
 | 
						|
                po_errs.append(lan)
 | 
						|
            else:
 | 
						|
                po_oks.append(lan)
 | 
						|
 | 
						|
    def generateConstPy(self ):
 | 
						|
        log.debug('========== generate_const.py()')
 | 
						|
        fin = open(os.path.join(self.build_src,'const.py.in'), 'r')
 | 
						|
        in_lines = fin.readlines()
 | 
						|
        fin.close()
 | 
						|
        fout = open(os.path.join(self.build_src,'const.py'), 'w')
 | 
						|
        for line in in_lines:
 | 
						|
            if '@VERSIONSTRING@' in line: #VERSION        = "@VERSIONSTRING@"
 | 
						|
                corrline = line.replace('@VERSIONSTRING@', self.gramps_version.replace(FULL_COLON_SUBST,":") )
 | 
						|
                fout.write(corrline)
 | 
						|
                #fout.write('VERSION        = "%s"\n'% self.gramps_version.replace(FULL_COLON_SUBST,":"))
 | 
						|
 | 
						|
            #elif '@prefix@' in line: #PREFIXDIR = "@prefix@"
 | 
						|
            #       what to do? , doesnt seem to matter on windows
 | 
						|
 | 
						|
            #elif '@sysconfdir@' in line: #SYSCONFDIR = "@sysconfdir@"
 | 
						|
            #       what to do? , doesnt seem to matter on windows
 | 
						|
 | 
						|
            else:
 | 
						|
                fout.write(line)
 | 
						|
        fout.close()
 | 
						|
 | 
						|
    def cleanBuildDir(self):
 | 
						|
        log.debug( '========== cleanBuildDir()' )
 | 
						|
        log.info( 'Cleaning build and output directories' )
 | 
						|
        if sys.platform == 'win32': #both platforms emit different exceptions for the same operation, map the exception here
 | 
						|
            MY_EXCEPTION = WindowsError
 | 
						|
        elif sys.platform == 'linux2':
 | 
						|
            MY_EXCEPTION = OSError
 | 
						|
        if os.path.exists(self.build_root):
 | 
						|
            try:
 | 
						|
                log.info('removing directory: %s' % self.build_root )
 | 
						|
                shutil.rmtree(self.build_root)
 | 
						|
            except MY_EXCEPTION, e:
 | 
						|
                log.error( e )
 | 
						|
 | 
						|
        for file in ['gramps-%s.exe'%self.gramps_version ]: #, 'build.log']:
 | 
						|
            fname = os.path.join(self.out_dir, file)
 | 
						|
            if os.path.isfile(fname):
 | 
						|
                try:
 | 
						|
                    log.info('removing file:      %s' % fname )
 | 
						|
                    os.remove(fname)
 | 
						|
                except MY_EXCEPTION, e:
 | 
						|
                    log.error( e )
 | 
						|
 | 
						|
    def getNSISVersionNumber(self):
 | 
						|
        #Check version of NSIS, to ensure NSIS is compatible with script features 
 | 
						|
          # >"c:\Program Files\NSIS\makensis.exe" /version
 | 
						|
          # v2.42
 | 
						|
        cmd = '"%s" -VERSION' % (MAKENSIS_exe)
 | 
						|
        log.debug(cmd)
 | 
						|
        
 | 
						|
        proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
        status = proc.wait()
 | 
						|
        output = string.strip(proc.stdout.read())
 | 
						|
        err = proc.stderr.read()
 | 
						|
        proc.stderr.close()
 | 
						|
        proc.stdout.close()
 | 
						|
        del proc
 | 
						|
        
 | 
						|
        if err:
 | 
						|
            log.error(err)
 | 
						|
            if sys.platform == 'win32': #'not recognized' in err:
 | 
						|
                minor =0
 | 
						|
                major =0
 | 
						|
                return (major, minor)
 | 
						|
            
 | 
						|
        #parse the output to get version number into tuple
 | 
						|
        ver =  output[1:].split('.') 
 | 
						|
        major = int(ver[0])
 | 
						|
        try:
 | 
						|
            minor = int(ver[1]) 
 | 
						|
        except ValueError, e:
 | 
						|
            m = ver[1]
 | 
						|
            minor = int(m[:2])        
 | 
						|
        return (major, minor)
 | 
						|
 | 
						|
    def checkForBuildTools(self):
 | 
						|
        global MAKENSIS_exe, SVN_exe
 | 
						|
        log.debug( '========== checkForBuildTools()' )
 | 
						|
        if sys.platform == 'win32':
 | 
						|
            import _winreg as winreg
 | 
						|
            # Find NSIS on system
 | 
						|
            try:
 | 
						|
                with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\NSIS') as key:
 | 
						|
                    nsispath = winreg.QueryValue(key, '')
 | 
						|
                    makensisexe = path.join( nsispath, 'makensis.exe')
 | 
						|
                    if path.isfile( makensisexe ):
 | 
						|
                        MAKENSIS_exe = makensisexe
 | 
						|
            except WindowsError, e:
 | 
						|
                log.warning('NSIS not found, in registory')
 | 
						|
                log.warning('..Testing if makensis is on the path')
 | 
						|
                MAKENSIS_exe = 'makensis'
 | 
						|
                #cmd = os.path.join(nsis_dir, MAKENSIS_exe)
 | 
						|
                
 | 
						|
                cmd = '%s /VERSION' % MAKENSIS_exe
 | 
						|
                proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
                status = proc.wait()
 | 
						|
                output = string.strip(proc.stdout.read())
 | 
						|
                err = proc.stderr.read()
 | 
						|
                proc.stderr.close()
 | 
						|
                proc.stdout.close()
 | 
						|
                del proc
 | 
						|
                
 | 
						|
                if err:
 | 
						|
                    log.error(err)
 | 
						|
                    log.error('....makensis.exe not found on path')
 | 
						|
                    sys.exit(0)
 | 
						|
                #else:
 | 
						|
                #    log.info("makensis version %s" % output)
 | 
						|
 | 
						|
            # Find msgfmt on system
 | 
						|
            cmd = os.path.join(msg_dir, 'msgfmt.exe')
 | 
						|
            
 | 
						|
            proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
 | 
						|
            status = proc.wait()
 | 
						|
            output = string.strip(proc.stdout.read())
 | 
						|
            err = proc.stderr.read()
 | 
						|
            proc.stderr.close()
 | 
						|
            proc.stdout.close()
 | 
						|
            del proc
 | 
						|
            
 | 
						|
            if not err.startswith(cmd):
 | 
						|
                #log.error(err)
 | 
						|
                log.error('msgfmt.exe not found on path')
 | 
						|
                log.error('    try the -m DIR , --msgdir=DIR option to specify the directory or put it on the path')
 | 
						|
                sys.exit(0)
 | 
						|
            
 | 
						|
            # Find SVN on system  -  optional,  if building from tarball
 | 
						|
            if not bTarball:
 | 
						|
                try:
 | 
						|
                    with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\svn.exe') as key:
 | 
						|
                        svnpath = winreg.QueryValue(key, '')
 | 
						|
                    if path.isfile(svnpath):
 | 
						|
                        SVN_exe = svnpath
 | 
						|
                except WindowsError, e:
 | 
						|
                    log.warning('SVN not found, in registory')
 | 
						|
                    log.warning('... Hoping svn is on the path')
 | 
						|
                    SVN_exe = 'svn'
 | 
						|
            
 | 
						|
        elif sys.platform == 'linux2':
 | 
						|
            #ASSUMPTION: these tools are on the path
 | 
						|
            #TODO: check for svn on Linux
 | 
						|
            log.info( 'TODO: Check for svn' )
 | 
						|
            SVN_exe = 'svn'
 | 
						|
            #TODO: check for nsis on Linux
 | 
						|
            log.info( 'TODO: Check for nsis' )
 | 
						|
            MAKENSIS_exe = 'makensis'
 | 
						|
            
 | 
						|
        # Check if we are running a compatible vesion of NSIS
 | 
						|
        vers = self.getNSISVersionNumber()
 | 
						|
        if vers < MIN_NSIS_VERSION:
 | 
						|
            log.error( "Require NSIS version %d.%d or later  ..... found NSIS version %d.%d" % (MIN_NSIS_VERSION[0],MIN_NSIS_VERSION[1], vers[0], vers[1]) )
 | 
						|
            log.info("Disabling NSIS compilation ... Please upgrade your NSIS version")
 | 
						|
            self.bBuildInstaller = False
 | 
						|
        else:
 | 
						|
            self.bBuildInstaller = True
 | 
						|
            log.info( "NSIS version %d.%d" % vers )
 | 
						|
            
 | 
						|
    def expandTarBall(self, tarball, expand_dir):
 | 
						|
        # gramps-3.1.0.tar.gz
 | 
						|
        log.info( 'expandTarBall(%s, %s)' % (tarball, expand_dir) )
 | 
						|
        if tarfile.is_tarfile(self.repository_path):
 | 
						|
            tar = tarfile.open(self.repository_path)
 | 
						|
            tar.extractall(self.out_dir)
 | 
						|
            tar.close()
 | 
						|
            base = os.path.basename(self.repository_path)
 | 
						|
            extractDir =  os.path.join(self.out_dir, base.replace('.tar.gz', '')  )
 | 
						|
            try:
 | 
						|
                os.rename( extractDir, self.build_root)
 | 
						|
            except WindowsError, e:
 | 
						|
                log.error("FAILED: extractDir=%s, build_root=%s" % (extractDir, self.build_root))
 | 
						|
                raise WindowsError, e
 | 
						|
        else:
 | 
						|
            log.error( "Sorry %s is not a tar file" % self.repository_path )
 | 
						|
 | 
						|
    def getVersionFromTarBall(self, tarball):
 | 
						|
        log.debug( 'getVersionFromTarBall(%s)' % (tarball))
 | 
						|
        
 | 
						|
        if tarfile.is_tarfile(self.repository_path):
 | 
						|
            tar = tarfile.open(self.repository_path)
 | 
						|
            members = tar.getnames()
 | 
						|
            for member in members:
 | 
						|
                if 'configure.in' in member:
 | 
						|
                    log.debug('Reading version from: %s' % member)
 | 
						|
                    file = tar.extractfile(member)
 | 
						|
                    lines = file.readlines()
 | 
						|
                    vers = self.getVersionFromLines(lines)
 | 
						|
            tar.close()
 | 
						|
        log.debug( 'Version (%s)' % (vers) )
 | 
						|
        return vers
 | 
						|
        
 | 
						|
def buildGRAMPS( base, out_dir, bTarball):
 | 
						|
    bo = buildbase()
 | 
						|
 | 
						|
    bo.repository_path = base
 | 
						|
    bo.out_dir = out_dir
 | 
						|
    bo.bTarball = bTarball
 | 
						|
    bo.bBuildInstaller = bBuildInstaller
 | 
						|
    
 | 
						|
    if not bo.bTarball and not bo.isGrampsRoot(bo.repository_path):
 | 
						|
        log.error( '$$$$ BAD Gramps Root specified $$$$')
 | 
						|
    else:
 | 
						|
        bo.checkForBuildTools()
 | 
						|
        if bo.bTarball:
 | 
						|
            bo.gramps_version = bo.getVersionFromTarBall( bo.repository_path )
 | 
						|
            bo.build_root = path.normpath(os.path.join(bo.out_dir, 'gramps-%s' % bo.gramps_version))
 | 
						|
            if bBuildAll:
 | 
						|
                bo.cleanBuildDir()
 | 
						|
                bo.expandTarBall(base, bo.out_dir)
 | 
						|
            bo.copyExtraFilesToBuildDir(bo.build_root )
 | 
						|
        else: #SVN Build
 | 
						|
            bo.gramps_version = bo.getVersionFromConfigureIn( base )
 | 
						|
            bo.build_root = path.normpath(os.path.join(bo.out_dir, 'gramps-%s' % bo.gramps_version))
 | 
						|
            if bBuildAll:
 | 
						|
                bo.cleanBuildDir()
 | 
						|
                os.mkdir(bo.build_root)
 | 
						|
                bo.exportSVN(os.path.join(base, 'src'), os.path.join(bo.build_root, 'src') )
 | 
						|
                bo.exportSVN(os.path.join(base, 'po'), os.path.join(bo.build_root, 'po') )
 | 
						|
                bo.exportSVN(os.path.join(base, 'example'), os.path.join(bo.build_root, 'examples') )
 | 
						|
            bo.generateConstPy( ) 
 | 
						|
            bo.copyExtraFilesToBuildDir(base)
 | 
						|
        
 | 
						|
        if bBuildAll:
 | 
						|
            bo.processPO( )
 | 
						|
        if bo.bBuildInstaller:
 | 
						|
            bo.compileInstallScript()
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    import getopt
 | 
						|
    import os
 | 
						|
    import sys
 | 
						|
    import tarfile
 | 
						|
 | 
						|
    usage = '''Create Gramps Windows Installer.
 | 
						|
Usage:
 | 
						|
    python build_GrampsWin32.py [options] [repository_path]
 | 
						|
 | 
						|
Arguments:
 | 
						|
    repository_path                   Path to the repository to build GRAMPS from, this can be either
 | 
						|
                                        - The root path of a SVN working copy
 | 
						|
                                        - A tarball that has been saved on local disk
 | 
						|
                                        - Left blank to build the SVN working copy this file is part of
 | 
						|
Options:
 | 
						|
    -h,     --help                This help message.
 | 
						|
    -oDIR,  --out=DIR             Directory to build files (optional)
 | 
						|
            --nsis_only           Build NSIS only (does not Clean & Build All)
 | 
						|
    -t      --tarball             Build release version from Tarball.
 | 
						|
    -mDIR, --msgdir=DIR           Directory to msgfmt.exe
 | 
						|
    '''
 | 
						|
# 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: tortoise_dir Option - accommodate windows user who dont have svn but use tortoiseSVN
 | 
						|
 | 
						|
    repository_path = '.' # Repository - either SVN working copy dir or Tarball file
 | 
						|
    out_dir = None
 | 
						|
    bBuildAll = True
 | 
						|
    bBuildInstaller = True
 | 
						|
    bTarball = False
 | 
						|
    msg_dir = ""
 | 
						|
    
 | 
						|
    try:
 | 
						|
        opts, args = getopt.getopt(sys.argv[1:], "ho:tm:",
 | 
						|
                                  ["help", "out=", "nsis_only", "tarball", "msgdir="])
 | 
						|
 | 
						|
        for o, a in opts:
 | 
						|
            if o in ("-h", "--help"):
 | 
						|
                print usage
 | 
						|
                sys.exit(0)
 | 
						|
 | 
						|
            if o in ("-o", "--out"):
 | 
						|
                out_dir =  a
 | 
						|
            if o in ("--nsis_only"):
 | 
						|
                bBuildAll = False
 | 
						|
            if o in ('-t', "--tarball"):
 | 
						|
                print 'This is a tarball build'
 | 
						|
                bTarball = True
 | 
						|
            if o in ("-m", "--msgdir"):
 | 
						|
                if os.path.isdir( a ):
 | 
						|
                    msg_dir =  a
 | 
						|
                else:
 | 
						|
                    raise getopt.GetoptError, '\nERROR: msgfmt dir 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() )
 | 
						|
 | 
						|
    #        raise getopt.GetoptError, '\nERROR: No base directory specified'
 | 
						|
 | 
						|
        if len(args) > 1:
 | 
						|
            raise getopt.GetoptError, '\nERROR: Too many arguments'
 | 
						|
 | 
						|
    except getopt.GetoptError, msg:
 | 
						|
        print msg
 | 
						|
        print '\n %s' % usage
 | 
						|
        sys.exit(2)
 | 
						|
 | 
						|
    if bTarball:
 | 
						|
        if not tarfile.is_tarfile(repository_path):
 | 
						|
            print "Tarball %s not a valid Tarball" % repository_path
 | 
						|
            sys.exit(1)
 | 
						|
            
 | 
						|
    else:    
 | 
						|
        if not os.path.isdir(repository_path):
 | 
						|
            print "WC root directory not found; %s " % repository_path
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
    if out_dir == None: 
 | 
						|
        if bTarball:
 | 
						|
            out_dir = path.normpath(os.getcwd())
 | 
						|
        else:
 | 
						|
            out_dir = path.normpath(os.path.join(repository_path, 'windows'))
 | 
						|
        log.info("Setting outdir to %s", out_dir)
 | 
						|
        
 | 
						|
 | 
						|
    s_args = ''
 | 
						|
    for value in sys.argv[1:]:
 | 
						|
        s_args = s_args + ' %s'%value
 | 
						|
 | 
						|
    print "======= build_GrampsWin32.py %s ========"  % s_args
 | 
						|
    log.debug('Using %s to find python tools' % sys.prefix)
 | 
						|
    log.info('Platform: %s' % sys.platform)
 | 
						|
    #==========================
 | 
						|
    sys.exit(buildGRAMPS(repository_path,out_dir, bTarball))
 | 
						|
 | 
						|
gobject.type_register(buildbase) |