#!/usr/bin/python

# Copyright MetaCommunications, Inc. 2003-2007
# Copyright Redshift Software, Inc. 2007
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

import glob
import optparse
import os
import os.path
import platform
import sys
import time

#~ Place holder for xsl_reports/util module
utils = None

repo_root = {
    'anon'          : 'http://svn.boost.org/svn/boost/',
    'user'          : 'https://svn.boost.org/svn/boost/'
    }
repo_path = {
    'trunk'         : 'trunk',
    'release'       : 'branches/release',
    'build'         : 'trunk/tools/build/v2',
    'jam'           : 'trunk/tools/build/v2/engine/src',
    'regression'    : 'trunk/tools/regression',
    'boost-build.jam'
                    : 'trunk/boost-build.jam'
    }

class runner:
    
    def __init__(self,root):
        commands = map(
            lambda m: m[8:].replace('_','-'),
            filter(
                lambda m: m.startswith('command_'),
                runner.__dict__.keys())
            )
        commands.sort()
        commands = "commands: %s" % ', '.join(commands)
        
        opt = optparse.OptionParser(
            usage="%prog [options] [commands]",
            description=commands)
            
        #~ Base Options:
        opt.add_option( '--runner',
            help="runner ID (e.g. 'Metacomm')" )
        opt.add_option( '--comment',
            help="an HTML comment file to be inserted in the reports" )
        opt.add_option( '--tag',
            help="the tag for the results" )
        opt.add_option( '--toolsets',
            help="comma-separated list of toolsets to test with" )
        opt.add_option( '--incremental',
            help="do incremental run (do not remove previous binaries)",
            action='store_true' )
        opt.add_option( '--timeout',
            help="specifies the timeout, in minutes, for a single test run/compilation",
            type='int' )
        opt.add_option( '--bjam-options',
            help="options to pass to the regression test" )
        opt.add_option( '--bjam-toolset',
            help="bootstrap toolset for 'bjam' executable" )
        opt.add_option( '--pjl-toolset',
            help="bootstrap toolset for 'process_jam_log' executable" )
        opt.add_option( '--platform' )

        #~ Source Options:
        opt.add_option( '--user',
            help="Boost SVN user ID" )
        opt.add_option( '--local',
            help="the name of the boost tarball" )
        opt.add_option( '--force-update',
            help="do an SVN update (if applicable) instead of a clean checkout, even when performing a full run",
            action='store_true' )
        opt.add_option( '--have-source',
            help="do neither a tarball download nor an SVN update; used primarily for testing script changes",
            action='store_true' )

        #~ Connection Options:
        opt.add_option( '--ftp',
            help="FTP URL to upload results to." )
        opt.add_option( '--proxy',
            help="HTTP proxy server address and port (e.g.'http://www.someproxy.com:3128')" )
        opt.add_option( '--ftp-proxy',
            help="FTP proxy server (e.g. 'ftpproxy')" )
        opt.add_option( '--dart-server',
            help="the dart server to send results to" )

        #~ Debug Options:
        opt.add_option( '--debug-level',
            help="debugging level; controls the amount of debugging output printed",
            type='int' )
        opt.add_option( '--send-bjam-log',
            help="send full bjam log of the regression run",
            action='store_true' )
        opt.add_option( '--mail',
            help="email address to send run notification to" )
        opt.add_option( '--smtp-login',
            help="STMP server address/login information, in the following form: <user>:<password>@<host>[:<port>]" )
        opt.add_option( '--skip-tests',
            help="do not run bjam; used for testing script changes",
            action='store_true' )
        
        #~ Defaults
        self.runner = None
        self.comment='comment.html'
        self.tag='trunk'
        self.toolsets=None
        self.incremental=False
        self.timeout=5
        self.bjam_options=''
        self.bjam_toolset=''
        self.pjl_toolset=''
        self.platform=self.platform_name()
        self.user='anonymous'
        self.local=None
        self.force_update=False
        self.have_source=False
        self.ftp=None
        self.proxy=None
        self.ftp_proxy=None
        self.dart_server=None
        self.debug_level=0
        self.send_bjam_log=False
        self.mail=None
        self.smtp_login=None
        self.skip_tests=False
        ( _opt_, self.actions ) = opt.parse_args(None,self)
        if not self.actions or self.actions == []:
            self.actions = [ 'regression' ]
        
        #~ Initialize option dependent values.
        self.regression_root = root
        self.boost_root = os.path.join( self.regression_root, 'boost' )
        self.regression_results = os.path.join( self.regression_root, 'results' )
        if self.pjl_toolset != 'python':
            self.regression_log = os.path.join( self.regression_results, 'bjam.log' )
        else:
            self.regression_log = os.path.join( self.regression_results, 'bjam.xml' )
        self.tools_bb_root = os.path.join( self.regression_root,'tools_bb' )
        self.tools_bjam_root = os.path.join( self.regression_root,'tools_bjam' )
        self.tools_regression_root = os.path.join( self.regression_root,'tools_regression' )
        self.xsl_reports_dir = os.path.join( self.tools_regression_root, 'xsl_reports' )
        self.timestamp_path = os.path.join( self.regression_root, 'timestamp' )
        if sys.platform == 'win32':
            self.patch_boost = 'patch_boost.bat'
            self.bjam = { 'name' : 'bjam.exe' }
            self.process_jam_log = { 'name' : 'process_jam_log.exe' }
        elif sys.platform == 'cygwin':
            self.patch_boost = 'patch_boost'
            self.bjam = { 'name' : 'bjam.exe' }
            self.process_jam_log = { 'name' : 'process_jam_log.exe' }
        else:
            self.patch_boost = 'patch_boost'
            self.bjam = { 'name' : 'bjam' }
            self.process_jam_log = { 'name' : 'process_jam_log' }
        self.bjam = {
            'name' : self.bjam['name'],
            'build_cmd' : self.bjam_build_cmd,
            'path' : os.path.join(self.regression_root,self.bjam['name']),
            'source_dir' : self.tools_bjam_root,
            'build_dir' : self.tools_bjam_root,
            'build_args' : ''
            }
        self.process_jam_log = {
            'name' : self.process_jam_log['name'],
            'build_cmd' : self.bjam_cmd,
            'path' : os.path.join(self.regression_root,self.process_jam_log['name']),
            'source_dir' : os.path.join(self.tools_regression_root,'build'),
            'build_dir' : os.path.join(self.tools_regression_root,'build'),
            'build_args' : 'process_jam_log -d2'
            }
        
        if self.debug_level > 0:
            self.log('Regression root =     %s'%self.regression_root)
            self.log('Boost root =          %s'%self.boost_root)
            self.log('Regression results =  %s'%self.regression_results)
            self.log('Regression log =      %s'%self.regression_log)
            self.log('BB root =             %s'%self.tools_bb_root)
            self.log('Bjam root =           %s'%self.tools_bjam_root)
            self.log('Tools root =          %s'%self.tools_regression_root)
            self.log('XSL reports dir =     %s'%self.xsl_reports_dir)
            self.log('Timestamp =           %s'%self.timestamp_path)
            self.log('Patch Boost script =  %s'%self.patch_boost)
        
        self.main()
    
    #~ The various commands that make up the testing sequence...
    
    def command_cleanup(self,*args):
        if not args or args == None or args == []: args = [ 'source', 'bin' ]

        if 'source' in args:
            self.log( 'Cleaning up "%s" directory ...' % self.boost_root )
            self.rmtree( self.boost_root )

        if 'bin' in args:
            boost_bin_dir = os.path.join( self.boost_root, 'bin' )
            self.log( 'Cleaning up "%s" directory ...' % boost_bin_dir )
            self.rmtree( boost_bin_dir )

            boost_binv2_dir = os.path.join( self.boost_root, 'bin.v2' )
            self.log( 'Cleaning up "%s" directory ...' % boost_binv2_dir )
            self.rmtree( boost_binv2_dir )

            self.log( 'Cleaning up "%s" directory ...' % self.regression_results )
            self.rmtree( self.regression_results )
    
    def command_get_tools(self):
        #~ Get Boost.Build v2...
        self.log( 'Getting Boost.Build v2...' )
        if self.user and self.user != '':
            os.chdir( os.path.dirname(self.tools_bb_root) )
            self.svn_command( 'co %s %s' % (
                self.svn_repository_url(repo_path['build']),
                os.path.basename(self.tools_bb_root) ) )
        else:
            self.retry( lambda: self.download_tarball(
                os.path.basename(self.tools_bb_root)+".tar.bz2",
                self.tarball_url(repo_path['build']) ) )
            self.unpack_tarball(
                self.tools_bb_root+".tar.bz2",
                os.path.basename(self.tools_bb_root) )
        #~ Get Boost.Jam...
        self.log( 'Getting Boost.Jam...' )
        if self.user and self.user != '':
            os.chdir( os.path.dirname(self.tools_bjam_root) )
            self.svn_command( 'co %s %s' % (
                self.svn_repository_url(repo_path['jam']),
                os.path.basename(self.tools_bjam_root) ) )
        else:
            self.retry( lambda: self.download_tarball(
                os.path.basename(self.tools_bjam_root)+".tar.bz2",
                self.tarball_url(repo_path['jam']) ) )
            self.unpack_tarball(
                self.tools_bjam_root+".tar.bz2",
                os.path.basename(self.tools_bjam_root) )
        #~ Get the regression tools and utilities...
        self.log( 'Getting regression tools an utilities...' )
        if self.user and self.user != '':
            os.chdir( os.path.dirname(self.tools_regression_root) )
            self.svn_command( 'co %s %s' % (
                self.svn_repository_url(repo_path['regression']),
                os.path.basename(self.tools_regression_root) ) )
        else:
            self.retry( lambda: self.download_tarball(
                os.path.basename(self.tools_regression_root)+".tar.bz2",
                self.tarball_url(repo_path['regression']) ) )
            self.unpack_tarball(
                self.tools_regression_root+".tar.bz2",
                os.path.basename(self.tools_regression_root) )
        
        #~ We get a boost-build.jam to make the tool build work even if there's
        #~ and existing boost-build.jam above the testing root.
        self.log( 'Getting boost-build.jam...' )
        self.http_get(
            self.svn_repository_url(repo_path['boost-build.jam']),
            os.path.join( self.regression_root, 'boost-build.jam' ) )
    
    def command_get_source(self):
        self.refresh_timestamp()
        self.log( 'Getting sources (%s)...' % self.timestamp() )

        if self.user and self.user != '':
            self.retry( self.svn_checkout )
        else:
            self.retry( self.get_tarball )
        pass
    
    def command_update_source(self):
        if self.user and self.user != '' \
            or os.path.exists( os.path.join( self.boost_root, '.svn' ) ):
            open( self.timestamp_path, 'w' ).close()
            self.log( 'Updating sources from SVN (%s)...' % self.timestamp() )
            self.retry( self.svn_update )
        else:
            self.command_get_source( )
        pass
    
    def command_patch(self):
        self.import_utils()
        patch_boost_path = os.path.join( self.regression_root, self.patch_boost )
        if os.path.exists( patch_boost_path ):
            self.log( 'Found patch file "%s". Executing it.' % patch_boost_path )
            os.chdir( self.regression_root )
            utils.system( [ patch_boost_path ] )
        pass
    
    def command_setup(self):
        self.command_patch()
        self.build_if_needed(self.bjam,self.bjam_toolset)
        if self.pjl_toolset != 'python':
            self.build_if_needed(self.process_jam_log,self.pjl_toolset)
    
    def command_test(self, *args):
        if not args or args == None or args == []: args = [ "test", "process" ]
        self.import_utils()

        self.log( 'Making "%s" directory...' % self.regression_results )
        utils.makedirs( self.regression_results )

        results_libs = os.path.join( self.regression_results, 'libs' )
        results_status = os.path.join( self.regression_results, 'status' )

        if "clean" in args:
            self.command_test_clean()

        if "test" in args:
            self.command_test_run()
            self.command_test_boost_build()

        if "process" in args:
            if self.pjl_toolset != 'python':
                self.command_test_process()
    
    def command_test_clean(self):
        results_libs = os.path.join( self.regression_results, 'libs' )
        results_status = os.path.join( self.regression_results, 'status' )
        self.rmtree( results_libs )
        self.rmtree( results_status )
    
    def command_test_run(self):
        self.import_utils()
        if self.pjl_toolset != 'python':
            test_cmd = '%s -d2 preserve-test-targets=off --dump-tests %s "--build-dir=%s" >>"%s" 2>&1' % (
                self.bjam_cmd( self.toolsets ),
                self.bjam_options,
                self.regression_results,
                self.regression_log )
        else:
            test_cmd = '%s -d1 preserve-test-targets=off --dump-tests --verbose-test %s "--build-dir=%s" "--out-xml=%s"' % (
                self.bjam_cmd( self.toolsets ),
                self.bjam_options,
                self.regression_results,
                self.regression_log )
        self.log( 'Starting tests (%s)...' % test_cmd )
        cd = os.getcwd()
        os.chdir( os.path.join( self.boost_root, 'status' ) )
        utils.system( [ test_cmd ] )
        os.chdir( cd )

    def command_test_boost_build(self):
        self.import_utils()
        self.log( 'Running Boost.Build tests' )
        # Find the true names of the toolsets used for testing
        toolsets = os.listdir(os.path.join(self.regression_results,
                                           "boost/bin.v2/libs/any/test/any_test.test"));
        for t in toolsets:
            d = os.path.join(self.regression_results, ("boost-build-%s" % (t)))
            utils.makedirs (d)
            fn = os.path.join(d, "test_log.xml")
            cd = os.getcwd()
            try:                
                os.chdir (os.path.join (self.boost_root, 'tools/build/v2/test'));
                bjam_path = os.path.dirname (self.tool_path( self.bjam ))
                self.log( "Using bjam binary in '%s'" % (bjam_path))
                os.putenv('PATH', bjam_path + os.pathsep + os.environ['PATH'])
                utils.system ( [ "%s test_all.py --default-bjam --xml %s > %s" % (sys.executable, t, fn) ] )
            finally:
                os.chdir( cd )
                            
    def command_test_process(self):
        self.import_utils()
        self.log( 'Getting test case results out of "%s"...' % self.regression_log )
        cd = os.getcwd()
        os.chdir( os.path.join( self.boost_root, 'status' ) )
        utils.checked_system( [
            '"%s" "%s" <"%s"' % (
                self.tool_path(self.process_jam_log),
                self.regression_results,
                self.regression_log )
            ] )
        os.chdir( cd )
    
    def command_collect_logs(self):
        self.import_utils()
        comment_path = os.path.join( self.regression_root, self.comment )
        if not os.path.exists( comment_path ):
            self.log( 'Comment file "%s" not found; creating default comment.' % comment_path )
            f = open( comment_path, 'w' )
            f.write( '<p>Tests are run on %s platform.</p>' % self.platform_name() )
            f.close()

        source = 'tarball'
        revision = ''
        svn_root_file = os.path.join( self.boost_root, '.svn' )
        svn_info_file = os.path.join( self.boost_root, 'svn_info.txt' )
        if os.path.exists( svn_root_file ):
            source = 'SVN'
            self.svn_command( 'info --xml "%s" >"%s"' % (self.boost_root,svn_info_file) )

        if os.path.exists( svn_info_file ):
            f = open( svn_info_file, 'r' )
            svn_info = f.read()
            f.close()
            i = svn_info.find( 'Revision:' )
            if i < 0: i = svn_info.find( 'revision=' )  # --xml format
            if i >= 0:
                i += 10
                while svn_info[i] >= '0' and svn_info[i] <= '9':
                  revision += svn_info[i]
                  i += 1

        if self.pjl_toolset != 'python':
            from collect_and_upload_logs import collect_logs
            if self.incremental:
                run_type = 'incremental'
            else:
                run_type = 'full'
            collect_logs(
                self.regression_results,
                self.runner, self.tag, self.platform, comment_path,
                self.timestamp_path,
                self.user,
                source, run_type,
                self.dart_server, self.proxy,
                revision )
        else:
            from process_jam_log import BJamLog2Results
            if self.incremental:
                run_type = '--incremental'
            else:
                run_type = ''
            BJamLog2Results([
                '--output='+os.path.join(self.regression_results,self.runner+'.xml'),
                '--runner='+self.runner,
                '--comment='+comment_path,
                '--tag='+self.tag,
                '--platform='+self.platform,
                '--source='+source,
                '--revision='+revision,
                run_type,
                self.regression_log
                ])
            self.compress_file(
                os.path.join(self.regression_results,self.runner+'.xml'),
                os.path.join(self.regression_results,self.runner+'.zip')
                )
        
    def command_upload_logs(self):
        self.import_utils()
        from collect_and_upload_logs import upload_logs
        if self.ftp:
            self.retry(
                lambda:
                    upload_logs(
                        self.regression_results,
                        self.runner, self.tag,
                        self.user,
                        self.ftp_proxy,
                        self.debug_level, self.send_bjam_log,
                        self.timestamp_path,
                        self.dart_server,
                        ftp_url = self.ftp )
                )
        else:
            self.retry(
                lambda:
                    upload_logs(
                        self.regression_results,
                        self.runner, self.tag,
                        self.user,
                        self.ftp_proxy,
                        self.debug_level, self.send_bjam_log,
                        self.timestamp_path,
                        self.dart_server )
                )
    
    def command_regression(self):
        import socket
        import string
        try:
            mail_subject = 'Boost regression for %s on %s' % ( self.tag,
                string.split(socket.gethostname(), '.')[0] )
            start_time = time.localtime()
            if self.mail:
                self.log( 'Sending start notification to "%s"' % self.mail )
                self.send_mail(
                    '%s started at %s.' % ( mail_subject, format_time( start_time ) )
                    )
            
            self.command_get_tools()

            if self.local is not None:
                self.log( 'Using local file "%s"' % self.local )
                b = os.path.basename( self.local )
                tag = b[ 0: b.find( '.' ) ]
                self.log( 'Tag: "%s"' % tag  )
                self.unpack_tarball( self.local, self.boost_root )
                
            elif self.have_source:
                if not self.incremental: self.command_cleanup( [ 'bin' ] )
                
            else:
                if self.incremental or self.force_update:
                    if not self.incremental: self.command_cleanup( [ 'bin' ] )
                else:
                    self.command_cleanup()
                self.command_get_source()

            self.command_setup()

            # Not specifying --toolset in command line is not enough
            # that would mean to use Boost.Build default ones
            # We can skip test only we were explictly 
            # told to have no toolsets in command line "--toolset="
            if self.toolsets != '': # --toolset=,
                if not self.skip_tests:
                    self.command_test()
                self.command_collect_logs()
                self.command_upload_logs()

            if self.mail:
                self.log( 'Sending report to "%s"' % self.mail )
                end_time = time.localtime()
                self.send_mail(
                    '%s completed successfully at %s.' % ( mail_subject, format_time( end_time ) )
                    )
        except:
            if self.mail:
                self.log( 'Sending report to "%s"' % self.mail )
                traceback_ = '\n'.join( apply( traceback.format_exception, sys.exc_info() ) )
                end_time = time.localtime()
                self.send_mail(
                    '%s failed at %s.' % ( mail_subject, format_time( end_time ) ),
                    traceback_ )
            raise

    def command_show_revision(self):
        modified = '$Date: 2010-09-04 07:40:26 -0400 (Sat, 04 Sep 2010) $'
        revision = '$Revision: 65234 $'

        import re
        re_keyword_value = re.compile( r'^\$\w+:\s+(.*)\s+\$$' )
        print '\n\tRevision: %s' % re_keyword_value.match( revision ).group( 1 )
        print '\tLast modified on: %s\n' % re_keyword_value.match( modified ).group( 1 )
    
    #~ Utilities...
    
    def main(self):
        for action in self.actions:
            action_m = "command_"+action.replace('-','_')
            if hasattr(self,action_m):
                getattr(self,action_m)()

    def platform_name(self):
        # See http://article.gmane.org/gmane.comp.lib.boost.testing/933
        if sys.platform == 'win32':
            return 'Windows'
        elif sys.platform == 'cygwin':
            return 'Windows/Cygwin'
        return platform.system()

    def log(self,message):
        sys.stdout.flush()
        sys.stderr.flush()
        sys.stderr.write( '# %s\n' % message )
        sys.stderr.flush()

    def rmtree(self,path):
        if os.path.exists( path ):
            import shutil
            #~ shutil.rmtree( unicode( path ) )
            if sys.platform == 'win32':
                os.system( 'del /f /s /q "%s" >nul 2>&1' % path )
                shutil.rmtree( unicode( path ) )
            else:
                os.system( 'rm -f -r "%s"' % path )

    def refresh_timestamp( self ):
        if os.path.exists( self.timestamp_path ):
           os.unlink( self.timestamp_path )
        open( self.timestamp_path, 'w' ).close()

    def timestamp( self ):
        return time.strftime(
            '%Y-%m-%dT%H:%M:%SZ',
            time.gmtime( os.stat( self.timestamp_path ).st_mtime ) )

    def retry( self, f, max_attempts=5, sleep_secs=10 ):
        for attempts in range( max_attempts, -1, -1 ):
            try:
                return f()
            except Exception, msg:
                self.log( '%s failed with message "%s"' % ( f.__name__, msg ) )
                if attempts == 0:
                    self.log( 'Giving up.' )
                    raise

                self.log( 'Retrying (%d more attempts).' % attempts )
                time.sleep( sleep_secs )

    def http_get( self, source_url, destination_file ):
        import urllib
        
        proxies = None
        if hasattr(self,'proxy') and self.proxy is not None:
            proxies = { 'http' : self.proxy }

        src = urllib.urlopen( source_url, proxies = proxies )

        f = open( destination_file, 'wb' )
        while True:
            data = src.read( 16*1024 )
            if len( data ) == 0: break
            f.write( data )

        f.close()
        src.close()

    def import_utils(self):
        global utils
        if utils is None:
            sys.path.append( self.xsl_reports_dir )
            import utils as utils_module
            utils = utils_module

    def build_if_needed( self, tool, toolset ):
        self.import_utils()
        if os.path.exists( tool[ 'path' ] ):
            self.log( 'Found preinstalled "%s"; will use it.' % tool[ 'path' ] )
            return

        self.log( 'Preinstalled "%s" is not found; building one...' % tool[ 'path' ] )

        if toolset is None:
            if self.toolsets is not None:
                toolset = string.split( self.toolsets, ',' )[0]
            else:
                toolset = tool[ 'default_toolset' ]
                self.log( 'Warning: No bootstrap toolset for "%s" was specified.' % tool[ 'name' ] )
                self.log( '         Using default toolset for the platform (%s).' % toolset )

        if os.path.exists( tool[ 'source_dir' ] ):
            self.log( 'Found "%s" source directory "%s"' % ( tool[ 'name' ], tool[ 'source_dir' ] ) )
            build_cmd = tool[ 'build_cmd' ]( toolset, tool['build_args'] )
            self.log( 'Building "%s" (%s)...' % ( tool[ 'name'], build_cmd ) )
            utils.system( [ 'cd "%s"' % tool[ 'source_dir' ], build_cmd ] )
        else:
            raise 'Could not find "%s" source directory "%s"' % ( tool[ 'name' ], tool[ 'source_dir' ] )

        if not tool.has_key( 'build_path' ):
            tool[ 'build_path' ] = self.tool_path( tool )

        if not os.path.exists( tool[ 'build_path' ] ):
            raise 'Failed to find "%s" after build.' % tool[ 'build_path' ]

        self.log( '%s succesfully built in "%s" location' % ( tool[ 'name' ], tool[ 'build_path' ] ) )

    def tool_path( self, name_or_spec ):
        if isinstance( name_or_spec, basestring ):
            return os.path.join( self.regression_root, name_or_spec )

        if os.path.exists( name_or_spec[ 'path' ] ):
            return name_or_spec[ 'path' ]

        if name_or_spec.has_key( 'build_path' ):
            return name_or_spec[ 'build_path' ]

        build_dir = name_or_spec[ 'build_dir' ]
        self.log( 'Searching for "%s" in "%s"...' % ( name_or_spec[ 'name' ], build_dir ) )
        for root, dirs, files in os.walk( build_dir ):
            if name_or_spec[ 'name' ] in files:
                return os.path.join( root, name_or_spec[ 'name' ] )

        raise Exception( 'Cannot find "%s" in any of the following locations:\n%s' % (
              name_or_spec[ 'name' ]
            , '\n'.join( [ name_or_spec[ 'path' ], build_dir ] )
            ) )
    
    def bjam_build_cmd( self, *rest ):
        if sys.platform == 'win32':
            cmd = 'build.bat %s' % self.bjam_toolset
        else:
            cmd = './build.sh %s' % self.bjam_toolset
        env_setup_key = 'BJAM_ENVIRONMENT_SETUP'
        if os.environ.has_key( env_setup_key ):
            return '%s & %s' % ( os.environ[env_setup_key], cmd )
        return cmd
    
    def bjam_cmd( self, toolsets, args = '', *rest ):
        build_path = self.regression_root
        if build_path[-1] == '\\': build_path += '\\'
        
        if self.timeout > 0:
            args += ' -l%s' % (self.timeout*60)

        cmd = '"%(bjam)s"' +\
            ' "-sBOOST_BUILD_PATH=%(bbpath)s"' +\
            ' "-sBOOST_ROOT=%(boost)s"' +\
            ' "--boost=%(boost)s"' +\
            ' "--boost-build=%(bb)s"' +\
            ' "--debug-configuration"' +\
            ' %(arg)s'
        cmd %= {
            'bjam' : self.tool_path( self.bjam ),
            'bbpath' : os.pathsep.join([build_path,self.tools_bb_root]),
            'bb' : self.tools_bb_root,
            'boost' : self.boost_root,
            'arg' : args }

        if toolsets:
            import string
            cmd += ' ' + string.join(string.split( toolsets, ',' ), ' ' )

        return cmd

    def send_mail( self, subject, msg = '' ):
        import smtplib
        if not self.smtp_login:
            server_name = 'mail.%s' % mail.split( '@' )[-1]
            user_name = None
            password = None
        else:
            server_name = self.smtp_login.split( '@' )[-1]
            ( user_name, password ) = string.split( self.smtp_login.split( '@' )[0], ':' )

        log( '    Sending mail through "%s"...' % server_name )
        smtp_server = smtplib.SMTP( server_name )
        smtp_server.set_debuglevel( self.debug_level )
        if user_name:
            smtp_server.login( user_name, password )

        smtp_server.sendmail( self.mail, [ self.mail ],
            'Subject: %s\nTo: %s\n\n%s' % ( subject, self.mail, msg ) )

    def compress_file( self, file_path, archive_path ):
        self.import_utils()
        utils.log( 'Compressing "%s"...' % file_path )

        try:
            import zipfile
            z = zipfile.ZipFile( archive_path, 'w', zipfile.ZIP_DEFLATED )
            z.write( file_path, os.path.basename( file_path ) )
            z.close()
            utils.log( 'Done writing "%s".'% archive_path )
        except Exception, msg:
            utils.log( 'Warning: Compressing falied (%s)' % msg )
            utils.log( '         Trying to compress using a platform-specific tool...' )
            try:
                import zip_cmd
            except ImportError:
                script_dir = os.path.dirname( os.path.abspath( sys.argv[0] ) )
                utils.log( 'Could not find \'zip_cmd\' module in the script directory (%s).' % script_dir )
                raise Exception( 'Compressing failed!' )
            else:
                if os.path.exists( archive_path ):
                    os.unlink( archive_path )
                    utils.log( 'Removing stale "%s".' % archive_path )
                    
                zip_cmd.main( file_path, archive_path )
                utils.log( 'Done compressing "%s".' % archive_path )

    #~ Dowloading source, from SVN...

    def svn_checkout( self ):
        os.chdir( self.regression_root )
        self.svn_command( 'co %s %s' % (self.svn_repository_url(self.tag),'boost') )

    def svn_update( self ):
        os.chdir( self.boost_root )
        self.svn_command( 'update' )

    def svn_command( self, command ):
        svn_anonymous_command_line  = 'svn --non-interactive %(command)s'
        svn_command_line            = 'svn --non-interactive --username=%(user)s %(command)s'
        
        if not hasattr(self,'user') or self.user is None or self.user == 'anonymous':
            cmd = svn_anonymous_command_line % { 'command': command }
        else:
            cmd = svn_command_line % { 'user': self.user, 'command': command }

        self.log( 'Executing SVN command "%s"' % cmd )
        rc = os.system( cmd )
        if rc != 0:
            raise Exception( 'SVN command "%s" failed with code %d' % ( cmd, rc ) )

    def svn_repository_url( self, path ):
        if self.user != 'anonymous' and self.user != '':
            return '%s%s' % (repo_root['user'],path)
        else:
            return '%s%s' % (repo_root['anon'],path)
    
    #~ Downloading and extracting source archives, from tarballs or zipballs...
    
    def get_tarball( self, *args ):
        if not args or args == []:
            args = [ 'download', 'unpack' ]

        tarball_path = None

        if hasattr(self,'local') and self.local is not None:
            tarball_path = self.local
        elif 'download' in args:
            tarball_path = self.download_tarball(self.boost_tarball_name(),self.boost_tarball_url())
        if not tarball_path:
            tarball_path = os.path.join( self.regression_root, self.boost_tarball_url() )

        if 'unpack' in args:
            self.unpack_tarball( tarball_path, self.boost_root )
        pass

    def download_tarball( self, tarball_name, tarball_url ):
        tarball_path = os.path.join( self.regression_root, tarball_name )

        self.log( 'Downloading "%s" to "%s"...'  % ( tarball_url, os.path.dirname( tarball_path ) ) )

        if os.path.exists( tarball_path ):
            os.unlink( tarball_path )
        self.http_get( tarball_url, tarball_path )

        return tarball_path
    
    def tarball_url( self, path ):
        return 'http://beta.boost.org/development/snapshot.php/%s' % path

    def boost_tarball_name( self ):
        return 'boost-%s.tar.bz2' % self.tag.split( '/' )[-1]

    def boost_tarball_url( self ):
        return self.tarball_url( self.tag )

    def unpack_tarball( self, tarball_path, target_path ):
        self.log( 'Looking for old unpacked archives...' )
        old_boost_dirs = self.find_boost_dirs( )

        for old_boost_dir in old_boost_dirs:
            if old_boost_dir != tarball_path:
                self.log( 'Deleting old directory %s.' % old_boost_dir )
                self.rmtree( old_boost_dir )

        self.log( 'Unpacking boost tarball ("%s")...' % tarball_path )

        tarball_name = os.path.basename( tarball_path )
        extension = tarball_name[ tarball_name.find( '.' ) : ]

        if extension in ( ".tar.gz", ".tar.bz2" ):
            import tarfile
            import stat
            
            mode = os.path.splitext( extension )[1][1:]
            tar = tarfile.open( tarball_path, 'r:%s' % mode )
            for tarinfo in tar:
                tar.extract( tarinfo, self.regression_root )
                if sys.platform == 'win32' and not tarinfo.isdir():
                    # workaround what appears to be a Win32-specific bug in 'tarfile'
                    # (modification times for extracted files are not set properly)
                    f = os.path.join( self.regression_root, tarinfo.name )
                    os.chmod( f, stat.S_IWRITE )
                    os.utime( f, ( tarinfo.mtime, tarinfo.mtime ) )
            tar.close()
        elif extension in ( ".zip" ):
            import zipfile

            z = zipfile.ZipFile( tarball_path, 'r', zipfile.ZIP_DEFLATED )
            for f in z.infolist():
                destination_file_path = os.path.join( self.regression_root, f.filename )
                if destination_file_path[-1] == "/": # directory
                    if not os.path.exists( destination_file_path  ):
                        os.makedirs( destination_file_path  )
                else: # file
                    result = open( destination_file_path, 'wb' )
                    result.write( z.read( f.filename ) )
                    result.close()
            z.close()
        else:
            raise 'Do not know how to unpack archives with extension \"%s\"' % extension

        boost_dir = self.find_boost_dirs()[0]
        self.log( '    Unpacked into directory "%s"' % boost_dir )

        if os.path.exists( target_path ):
            self.log( 'Deleting "%s" directory...' % target_path )
            self.rmtree( target_path )

        self.log( 'Renaming "%s" into "%s"' % ( boost_dir, target_path ) )
        os.rename( boost_dir, target_path )

    def find_boost_dirs( self ):
        return [
            x for x in
                glob.glob( os.path.join( self.regression_root, 'boost[-_]*' ) )
                if os.path.isdir( x )
            ]


