xref: /aosp_15_r20/external/autotest/utils/compile_gwt_clients.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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