1*9c5db199SXin Li#!/usr/bin/env python3 2*9c5db199SXin Li 3*9c5db199SXin Lifrom __future__ import print_function 4*9c5db199SXin Lifrom __future__ import division 5*9c5db199SXin Lifrom __future__ import absolute_import 6*9c5db199SXin Li 7*9c5db199SXin Liimport common 8*9c5db199SXin Liimport sys, os, shutil, optparse, logging 9*9c5db199SXin Liimport six 10*9c5db199SXin Li 11*9c5db199SXin Lifrom autotest_lib.client.common_lib import error, utils 12*9c5db199SXin Lifrom autotest_lib.client.common_lib import logging_config, logging_manager 13*9c5db199SXin Li 14*9c5db199SXin Li 15*9c5db199SXin Li""" 16*9c5db199SXin LiCompile All Autotest GWT Clients Living in autotest/frontend/client/src 17*9c5db199SXin Li""" 18*9c5db199SXin Li 19*9c5db199SXin Li 20*9c5db199SXin Li 21*9c5db199SXin Li_AUTOTEST_DIR = common.autotest_dir 22*9c5db199SXin Li_DEFAULT_GWT_DIRS = ['/usr/local/lib/gwt', '/opt/google-web-toolkit'] 23*9c5db199SXin Li_DEFAULT_APP_DIR = os.path.join(_AUTOTEST_DIR, 'frontend/client') 24*9c5db199SXin Li_DEFAULT_INSTALL_DIR = os.path.join(_DEFAULT_APP_DIR, 'www') 25*9c5db199SXin Li_TMP_COMPILE_DIR = _DEFAULT_INSTALL_DIR + '.new' 26*9c5db199SXin Li 27*9c5db199SXin Li_COMPILE_LINE = ('java -Xmx512M %(extra_args)s ' 28*9c5db199SXin Li '-cp "%(app_dir)s/src:%(app_dir)s/bin:%(gwt_dir)s/gwt-user.jar' 29*9c5db199SXin Li ':%(gwt_dir)s/gwt-dev.jar" -Djava.awt.headless=true ' 30*9c5db199SXin Li 'com.google.gwt.dev.Compiler -war "%(compile_dir)s" ' 31*9c5db199SXin Li '%(project_client)s') 32*9c5db199SXin Li 33*9c5db199SXin Liclass CompileClientsLoggingConfig(logging_config.LoggingConfig): 34*9c5db199SXin Li def configure_logging(self, results_dir=None, verbose=False): 35*9c5db199SXin Li super(CompileClientsLoggingConfig, self).configure_logging( 36*9c5db199SXin Li use_console=True, 37*9c5db199SXin Li verbose=verbose) 38*9c5db199SXin Li 39*9c5db199SXin Lidef enumerate_projects(): 40*9c5db199SXin Li """List projects in _DEFAULT_APP_DIR.""" 41*9c5db199SXin Li src_path = os.path.join(_DEFAULT_APP_DIR, 'src') 42*9c5db199SXin Li projects = {} 43*9c5db199SXin Li for project in os.listdir(src_path): 44*9c5db199SXin Li projects[project] = [] 45*9c5db199SXin Li project_path = os.path.join(src_path, project) 46*9c5db199SXin Li for file in os.listdir(project_path): 47*9c5db199SXin Li if file.endswith('.gwt.xml'): 48*9c5db199SXin Li projects[project].append(file[:-8]) 49*9c5db199SXin Li return projects 50*9c5db199SXin Li 51*9c5db199SXin Li 52*9c5db199SXin Lidef find_gwt_dir(): 53*9c5db199SXin Li """See if GWT is installed in site-packages or in the system, 54*9c5db199SXin Li site-packages is favored over a system install or a /usr/local install. 55*9c5db199SXin Li """ 56*9c5db199SXin Li site_gwt = os.path.join(_AUTOTEST_DIR, 'site-packages', 'gwt') 57*9c5db199SXin Li gwt_dirs = [site_gwt] + _DEFAULT_GWT_DIRS 58*9c5db199SXin Li 59*9c5db199SXin Li for gwt_dir in gwt_dirs: 60*9c5db199SXin Li if os.path.isdir(gwt_dir): 61*9c5db199SXin Li return gwt_dir 62*9c5db199SXin Li logging.error('Unable to find GWT. ' 63*9c5db199SXin Li 'You can use utils/build_externals.py to install it.') 64*9c5db199SXin Li sys.exit(1) 65*9c5db199SXin Li 66*9c5db199SXin Li 67*9c5db199SXin Lidef install_completed_client(compiled_dir, project_client): 68*9c5db199SXin Li """Remove old client directory if it exists, move installed client to the 69*9c5db199SXin Li old directory and move newly compield client to the installed client 70*9c5db199SXin Li dir. 71*9c5db199SXin Li @param compiled_dir: Where the new client was compiled 72*9c5db199SXin Li @param project_client: project.client pair e.g. autotest.AfeClient 73*9c5db199SXin Li @returns True if installation was successful or False if it failed 74*9c5db199SXin Li """ 75*9c5db199SXin Li tmp_client_dir = os.path.join(_TMP_COMPILE_DIR, project_client) 76*9c5db199SXin Li install_dir = os.path.join(_DEFAULT_INSTALL_DIR, project_client) 77*9c5db199SXin Li old_install_dir = os.path.join(_DEFAULT_INSTALL_DIR, 78*9c5db199SXin Li project_client + '.old') 79*9c5db199SXin Li if not os.path.exists(_DEFAULT_INSTALL_DIR): 80*9c5db199SXin Li os.mkdir(_DEFAULT_INSTALL_DIR) 81*9c5db199SXin Li 82*9c5db199SXin Li if os.path.isdir(tmp_client_dir): 83*9c5db199SXin Li if os.path.isdir(old_install_dir): 84*9c5db199SXin Li shutil.rmtree(old_install_dir) 85*9c5db199SXin Li if os.path.isdir(install_dir): 86*9c5db199SXin Li os.rename(install_dir, old_install_dir) 87*9c5db199SXin Li try: 88*9c5db199SXin Li os.rename(tmp_client_dir, install_dir) 89*9c5db199SXin Li return True 90*9c5db199SXin Li except Exception as err: 91*9c5db199SXin Li # If we can't rename the client raise an exception 92*9c5db199SXin Li # and put the old client back 93*9c5db199SXin Li shutil.rmtree(install_dir) 94*9c5db199SXin Li shutil.copytree(old_install_dir, install_dir) 95*9c5db199SXin Li logging.error('Copying old client: %s', err) 96*9c5db199SXin Li else: 97*9c5db199SXin Li logging.error('Compiled directory is gone, something went wrong') 98*9c5db199SXin Li 99*9c5db199SXin Li return False 100*9c5db199SXin Li 101*9c5db199SXin Li 102*9c5db199SXin Lidef compile_and_install_client(project_client, extra_args='', 103*9c5db199SXin Li install_client=True): 104*9c5db199SXin Li """Compile the client into a temporary directory, if successful 105*9c5db199SXin Li call install_completed_client to install the new client. 106*9c5db199SXin Li @param project_client: project.client pair e.g. autotest.AfeClient 107*9c5db199SXin Li @param install_client: Boolean, if True install the clients 108*9c5db199SXin Li @return True if install and compile was successful False if it failed 109*9c5db199SXin Li """ 110*9c5db199SXin Li java_args = {} 111*9c5db199SXin Li java_args['compile_dir'] = _TMP_COMPILE_DIR 112*9c5db199SXin Li java_args['app_dir'] = _DEFAULT_APP_DIR 113*9c5db199SXin Li java_args['gwt_dir'] = find_gwt_dir() 114*9c5db199SXin Li java_args['extra_args'] = extra_args 115*9c5db199SXin Li java_args['project_client'] = project_client 116*9c5db199SXin Li cmd = _COMPILE_LINE % java_args 117*9c5db199SXin Li 118*9c5db199SXin Li logging.info('Compiling client %s', project_client) 119*9c5db199SXin Li try: 120*9c5db199SXin Li utils.run(cmd, verbose=True) 121*9c5db199SXin Li if install_client: 122*9c5db199SXin Li return install_completed_client(java_args['compile_dir'], 123*9c5db199SXin Li project_client) 124*9c5db199SXin Li return True 125*9c5db199SXin Li except error.CmdError: 126*9c5db199SXin Li logging.error('Error compiling %s, leaving old client', project_client) 127*9c5db199SXin Li 128*9c5db199SXin Li return False 129*9c5db199SXin Li 130*9c5db199SXin Li 131*9c5db199SXin Lidef compile_all_projects(extra_args=''): 132*9c5db199SXin Li """Compile all projects available as defined by enumerate_projects. 133*9c5db199SXin Li @returns list of failed client installations 134*9c5db199SXin Li """ 135*9c5db199SXin Li failed_clients = [] 136*9c5db199SXin Li for project,clients in six.iteritems(enumerate_projects()): 137*9c5db199SXin Li for client in clients: 138*9c5db199SXin Li project_client = '%s.%s' % (project, client) 139*9c5db199SXin Li if not compile_and_install_client(project_client, extra_args): 140*9c5db199SXin Li failed_clients.append(project_client) 141*9c5db199SXin Li 142*9c5db199SXin Li return failed_clients 143*9c5db199SXin Li 144*9c5db199SXin Li 145*9c5db199SXin Lidef print_projects(): 146*9c5db199SXin Li logging.info('Projects that can be compiled:') 147*9c5db199SXin Li for project,clients in six.iteritems(enumerate_projects()): 148*9c5db199SXin Li for client in clients: 149*9c5db199SXin Li logging.info('%s.%s', project, client) 150*9c5db199SXin Li 151*9c5db199SXin Li 152*9c5db199SXin Lidef main(): 153*9c5db199SXin Li logging_manager.configure_logging(CompileClientsLoggingConfig(), 154*9c5db199SXin Li verbose=True) 155*9c5db199SXin Li parser = optparse.OptionParser() 156*9c5db199SXin Li parser.add_option('-l', '--list-projects', 157*9c5db199SXin Li action='store_true', dest='list_projects', 158*9c5db199SXin Li default=False, 159*9c5db199SXin Li help='List all projects and clients that can be compiled') 160*9c5db199SXin Li parser.add_option('-a', '--compile-all', 161*9c5db199SXin Li action='store_true', dest='compile_all', 162*9c5db199SXin Li default=False, 163*9c5db199SXin Li help='Compile all available projects and clients') 164*9c5db199SXin Li parser.add_option('-c', '--compile', 165*9c5db199SXin Li dest='compile_list', action='store', 166*9c5db199SXin Li help='List of clients to compiled (e.g. -c "x.X c.C")') 167*9c5db199SXin Li parser.add_option('-e', '--extra-args', 168*9c5db199SXin Li dest='extra_args', action='store', 169*9c5db199SXin Li default='', 170*9c5db199SXin Li help='Extra arguments to pass to java') 171*9c5db199SXin Li parser.add_option('-d', '--no-install', dest='install_client', 172*9c5db199SXin Li action='store_false', default=True, 173*9c5db199SXin Li help='Do not install the clients just compile them') 174*9c5db199SXin Li options, args = parser.parse_args() 175*9c5db199SXin Li 176*9c5db199SXin Li if len(sys.argv) < 2: 177*9c5db199SXin Li parser.print_help() 178*9c5db199SXin Li sys.exit(0) 179*9c5db199SXin Li elif options.list_projects: 180*9c5db199SXin Li print_projects() 181*9c5db199SXin Li sys.exit(0) 182*9c5db199SXin Li elif options.compile_all and options.compile_list: 183*9c5db199SXin Li logging.error('Options -c and -a are mutually exclusive') 184*9c5db199SXin Li parser.print_help() 185*9c5db199SXin Li sys.exit(1) 186*9c5db199SXin Li 187*9c5db199SXin Li failed_clients = [] 188*9c5db199SXin Li if options.compile_all: 189*9c5db199SXin Li failed_clients = compile_all_projects(options.extra_args) 190*9c5db199SXin Li elif options.compile_list: 191*9c5db199SXin Li for client in options.compile_list.split(): 192*9c5db199SXin Li if not compile_and_install_client(client, options.extra_args, 193*9c5db199SXin Li options.install_client): 194*9c5db199SXin Li failed_clients.append(client) 195*9c5db199SXin Li 196*9c5db199SXin Li if os.path.exists(_TMP_COMPILE_DIR): 197*9c5db199SXin Li shutil.rmtree(_TMP_COMPILE_DIR) 198*9c5db199SXin Li 199*9c5db199SXin Li if failed_clients: 200*9c5db199SXin Li logging.error('The following clients failed: %s', 201*9c5db199SXin Li '\n'.join(failed_clients)) 202*9c5db199SXin Li sys.exit(1) 203*9c5db199SXin Li 204*9c5db199SXin Li 205*9c5db199SXin Liif __name__ == '__main__': 206*9c5db199SXin Li main() 207