summaryrefslogtreecommitdiff
path: root/utils/compile_gwt_clients.py
blob: cc68f3f593f5594f7bdbd3e0f5561efce9ff7859 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/python
import sys, os, shutil, errno, optparse
import common
from autotest_lib.client.common_lib import error, utils
"""
Compile All Autotest GWT Clients Living in autotest/frontend/client/src
"""

_AUTOTEST_DIR = common.autotest_dir
_DEFAULT_GWT_DIR = '/usr/local/lib/gwt'
_DEFAULT_APP_DIR = os.path.join(_AUTOTEST_DIR, 'frontend/client')
_DEFAULT_INSTALL_DIR = os.path.join(_DEFAULT_APP_DIR, 'www')
_TMP_COMPILE_DIR = _DEFAULT_INSTALL_DIR + '.new'

_COMPILE_LINE = ('java  -Xmx512M '
                 '-cp "%(app_dir)s/src:%(app_dir)s/bin:%(gwt_dir)s/gwt-user.jar'
                 ':%(gwt_dir)s/gwt-dev-linux.jar" '
                 '-Djava.awt.headless=true com.google.gwt.dev.Compiler '
                 '-war "%(compile_dir)s" %(extra_args)s %(project_client)s')


def enumerate_projects():
    """List projects in _DEFAULT_APP_DIR."""
    src_path = os.path.join(_DEFAULT_APP_DIR, 'src')
    projects = {}
    for project in os.listdir(src_path):
        projects[project] = []
        project_path = os.path.join(src_path, project)
        for file in os.listdir(project_path):
            if file.endswith('.gwt.xml'):
                projects[project].append(file[:-8])
    return projects


def find_gwt_dir():
    """See if GWT is installed in site-packages or in the system,
       site-packages is favored over a system install.
    """
    site_gwt = os.path.join(_AUTOTEST_DIR, 'site-packages', 'gwt')

    if os.path.isdir(site_gwt):
        return site_gwt

    if not os.path.isdir(_DEFAULT_GWT_DIR):
        print 'Error: Unable to find GWT, is GWT installed?\n'
        sys.exit(1)

    return _DEFAULT_GWT_DIR


def install_completed_client(compiled_dir, project_client):
    """Remove old client directory if it exists,  move installed client to the
       old directory and move newly compield client to the installed client
       dir.
       @param compiled_dir: Where the new client was compiled
       @param project_client: project.client pair e.g. autotest.AfeClient
       @returns True if installation was successful or False if it failed
    """
    tmp_client_dir = os.path.join(_TMP_COMPILE_DIR, project_client)
    install_dir = os.path.join(_DEFAULT_INSTALL_DIR, project_client)
    old_install_dir = os.path.join(_DEFAULT_INSTALL_DIR,
                                   project_client + '.old')
    if not os.path.exists(_DEFAULT_INSTALL_DIR):
        os.mkdir(_DEFAULT_INSTALL_DIR)

    if os.path.isdir(tmp_client_dir):
        if os.path.isdir(old_install_dir):
            shutil.rmtree(old_install_dir)
        if os.path.isdir(install_dir):
            os.rename(install_dir, old_install_dir)
        try:
            os.rename(tmp_client_dir, install_dir)
            return True
        except Exception, err:
            # If we can't rename the client raise an exception
            # and put the old client back
            shutil.rmtree(install_dir)
            shutil.copytree(old_install_dir, install_dir)
            print 'Error: copying old client:', err
    else:
        print 'Error: Compiled directory is gone, something went wrong'

    return False


def compile_and_install_client(project_client, extra_args='',
                               install_client=True):
    """Compile the client into a temporary directory, if successful
       call install_completed_client to install the new client.
       @param project_client: project.client pair e.g. autotest.AfeClient
       @param install_client: Boolean, if True install the clients
       @return True if install and compile was successful False if it failed
    """
    java_args = {}
    java_args['compile_dir'] = _TMP_COMPILE_DIR
    java_args['app_dir'] = _DEFAULT_APP_DIR
    java_args['gwt_dir'] = find_gwt_dir()
    java_args['extra_args'] = extra_args
    java_args['project_client'] = project_client
    cmd = _COMPILE_LINE % java_args

    print 'Compiling client %s' % project_client
    try:
        utils.run(cmd, verbose=True)
        if install_client:
            return install_completed_client(java_args['compile_dir'],
                                            project_client)
        return True
    except error.CmdError:
        print 'Error compiling %s, leaving old client' % project_client

    return False


def compile_all_projects(projects, extra_args=''):
    """Compile all projects available as defined by enumerate_projects.
       @returns list of failed client installations
    """
    failed_clients = []
    for project,clients in enumerate_projects().iteritems():
        for client in clients:
            project_client = '%s.%s' % (project, client)
            if not compile_and_install_client(project_client, extra_args):
                failed_clients.append(project_client)

    return failed_clients


def print_projects():
    print 'Projects that can be compiled:'
    for project,clients in enumerate_projects().iteritems():
        for client in clients:
            print '%s.%s' % (project, client)


def main():
    parser = optparse.OptionParser()
    parser.add_option('-l', '--list-projects',
                      action='store_true', dest='list_projects',
                      default=False,
                      help='List all projects and clients that can be compiled')
    parser.add_option('-a', '--compile-all',
                      action='store_true', dest='compile_all',
                     default=False,
                     help='Compile all available projects and clients')
    parser.add_option('-c', '--compile',
                      dest='compile_list', action='store',
                      help='List of clients to compiled (e.g. -c "x.X c.C")')
    parser.add_option('-e', '--extra-args',
                      dest='extra_args', action='store',
                      default='',
                      help='Extra arguments to pass to java')
    parser.add_option('-d', '--no-install', dest='install_client',
                      action='store_false', default=True,
                      help='Do not install the clients just compile them')
    options, args = parser.parse_args()

    if len(sys.argv) < 2:
        parser.print_help()
        sys.exit(0)
    elif options.list_projects:
        print_projects()
        sys.exit(0)
    elif options.compile_all and options.compile_list:
        print '-c and -a are mutually exclusive'
        parser.print_help()
        sys.exit(1)

    failed_clients = []
    if options.compile_all:
        failed_clients = compile_all_projects(options.extra_args)
    elif options.compile_list:
        for client in options.compile_list.split():
            if not compile_and_install_client(client, options.extra_args,
                                              options.install_client):
                failed_clients.append(client)

    if os.path.exists(_TMP_COMPILE_DIR):
        shutil.rmtree(_TMP_COMPILE_DIR)

    if failed_clients:
        print ('Error: The following clients failed: %s'
               % '\n'.join(failed_clients))
        sys.exit(1)


if __name__ == '__main__':
    main()