source: branches/anuga_1_2_0/create_win_installer.py @ 7966

Last change on this file since 7966 was 7899, checked in by wilsonr, 14 years ago

Initial version.

File size: 8.3 KB
Line 
1"""
2Create a Windows installer EXE.
3
4usage: create_win_installer  [<revision>]
5
6where <revision> is an optional revision number - if not supplied then
7                 update through svn and use latest revision
8                 
9This program expects to be run from the root directory of the ANUGA branch
10being released.
11
12This script works only on Windows!
13"""
14
15
16import sys
17import os
18import getopt
19import tempfile
20import shutil
21
22import dirs_to_distribute
23from anuga.utilities.data_audit_wrapper import IP_verified
24
25from anuga.utilities.system_tools import get_user_name, get_host_name
26from anuga.abstract_2d_finite_volumes.util import get_revision_number
27from anuga.abstract_2d_finite_volumes.util import store_version_info
28from anuga.config import major_revision
29
30
31# name of 'home' directory containing releases
32ANUGA_RELEASE_DIR = 'anuga_releases'
33
34# prefix for temporary directory
35TEMP_DIR_PREFIX = 'anuga_release_'
36
37# path to and required contents of documentation directory
38DOC_PATH = os.path.join('anuga_core', 'documentation', 'user_manual')
39DOC_FILES = ['anuga_user_manual.pfd',
40             'anuga_installation_guide.pdf',
41             'anuga_whats_new.pdf']
42
43
44# path to NSIS install directory
45NSIS_PATH = r'C:\Program Files\NSIS'
46NSIS_EXE = os.path.join(NSIS_PATH, 'makensis.exe')
47
48# the name of the subversion commandline client
49SVN_CLIENT = 'svn'
50
51
52def abort(msg, stop=True):
53    """Some sort of error, report and abort."""
54
55    print('abort: stop=%s' % str(stop))
56   
57    xlog('*' * 80)
58    xlog(msg)
59    xlog('*' * 80)
60    if stop:
61        sys.exit(10)
62
63
64def check_doc(temp_dir, release_name):
65    """Make sure all the documentation is present.
66
67    temp_dir      released code working directory
68    release_name  ANUGA release name
69
70    Returns if everything OK.
71    """
72
73    bad = False
74   
75    for file in DOC_FILES:
76        doc_file = os.path.join(DOC_PATH, file)
77        if not os.path.isfile(doc_file):
78            xlog('Documentation file %s is missing.' % doc_file)
79            bad = True
80
81    if bad and not Force:
82        abort('You must release on Linux before Windows.', stop=False)
83
84
85def check_IP(temp_dir, verbose=False):
86    """Check IP statements in release directories."""
87
88    if not IP_verified(temp_dir, verbose=verbose):
89        if not Force:
90            abort('Files have not been verified for IP.\n'
91                  'Each data file must have a licence file with it.')
92
93
94def compile_nsi_file():
95    """Compile the installer NSI file."""
96
97    # figure out where the *.nsi file actually is
98    nsi_file = os.path.join(BranchDir, 'installation_files', 'windows',
99                            'installer.nsi')
100   
101    do_cmd('"%s" %s' % (NSIS_EXE, nsi_file))
102
103
104def copy_release_directories(revision, temp_dir):
105    """Get release dirs (correct version) into release directory."""
106   
107    for src in dirs_to_distribute.dirmap:
108        dst = os.path.join(temp_dir, dirs_to_distribute.dirmap[src])
109        do_cmd('%s export -r %s --quiet %s %s'
110               % (SVN_CLIENT, revision, src, dst))
111
112
113def do_cmd(cmd, ignore_errors=False):
114    """Execute a command, optionally ignore errors."""
115
116    try:
117        xlog(cmd)
118        os.system(cmd)
119    except:
120        if not ignore_errors:
121            raise
122
123
124def get_directories(rel_name):
125    """Create release and temporary directories, return paths.
126
127    rel_name  the ANUGA release name
128    """
129
130    # create the release directory
131    rel_area = os.path.join('~', ANUGA_RELEASE_DIR)
132    rel_area = os.path.expanduser(rel_area)
133
134    rel_dir = os.path.join(rel_area, rel_name)
135    if os.path.isdir(rel_dir):
136        if Force:
137            os.removedirs(rel_dir)
138        else:
139            abort("Sorry, release directory '%s' already exists.\n"
140                  "Please delete that directory first." % rel_dir)
141       
142    os.makedirs(rel_dir)
143
144    # create a temporary scratch directory
145    temp_dir = tempfile.mkdtemp(suffix='', prefix=TEMP_DIR_PREFIX)
146
147    return (rel_dir, temp_dir)
148   
149
150def get_release_name():
151    """Get release information and create release name.
152
153    Get release numbers from the current directory.
154
155    Returns a string which is of the form 'anuga-X-Y-Z' where X is the
156    major release number, Y is the minor and Z is the bug number.
157    """
158   
159    curr_dir = os.getcwd()
160    curr_dir = os.path.basename(curr_dir)
161    split_dir = curr_dir.split('_')
162    if len(split_dir) < 2:
163        abort('You must run this script in an ANUGA branch directory.')
164    if split_dir[0] != 'anuga':
165        abort('You must run this script in an ANUGA branch directory.')
166
167    major = split_dir[1]
168    if len(split_dir) < 3:
169        minor = '0'
170    else:
171        minor = split_dir[2]
172       
173    if len(split_dir) < 4:
174        bug = '0'
175    else:
176        bug = split_dir[3]
177
178    return 'anuga-%s-%s-%s' % (major, minor, bug)
179   
180
181def get_svn_revision():
182    """Get the current revision number from svn.
183
184    This uses the CollabNet subversion client.
185    """
186
187    try:
188        fid = os.popen('%s info' % SVN_CLIENT)
189    except:
190        abort('Subversion commandline client not found')
191
192    lines = fid.readlines()
193    fid.close()
194
195    for l in lines:
196        l = l.strip()
197        if l.startswith('Last Changed Rev:'):
198            (_, revision) = l.split(':', 1)
199            try:
200                revision = int(revision)
201            except ValueError:
202                abort('"svn info" did not return expected line: ' + l)
203            return revision
204
205    abort('"svn info" did not return expected line "Last Changed Rev:"')
206
207
208def make_installer(revision):
209    """Make a windows installer.
210
211    revision  the revision number (string) to release
212              (may be None, meaning 'use latest')
213    """
214
215    global BranchDir
216
217    # get the current branch directory path
218    BranchDir = os.getcwd()
219   
220    # if revision is None (not supplied) do update and get latest revision
221    if revision is None:
222        do_cmd('%s up' % SVN_CLIENT)
223        revision = get_svn_revision()
224       
225    # get release name form current directory
226    release_name = get_release_name()
227
228    # get working directory paths (directories have been created)
229    (release_dir, temp_dir) = get_directories(release_name)
230
231    # get the ANUGA directories that are being released
232    copy_release_directories(revision, temp_dir)
233
234    # check IP data for release directories
235    check_IP(temp_dir, verbose=True)
236
237    # generate the LaTeX documentation
238    check_doc(temp_dir, release_name)
239
240    # create ZIP release file, put into release dir
241    make_zip_file(temp_dir, release_name, release_dir)
242
243    # compile Windows *.nsi file
244    # creates EXE in <BranchDir>\installation_files\windows
245    # remove all *.exe files first
246    src = os.path.join(BranchDir, 'installation_files', 'windows', '*.exe')
247    do_cmd('rm %s' % src)   
248    compile_nsi_file()
249
250    # copy the create EXE to the release directory
251    do_cmd('move /Y %s %s' % (src, release_dir))
252
253    # clean up
254    shutil.rmtree(temp_dir)
255
256
257def make_zip_file(temp_dir, release_name, release_dir):
258    """Make a ZIP file, copy to release directory.
259
260    temp_dir      directory where we copied release files
261    release_name  the release name
262    release_dir   destination for the ZIP file
263    """
264
265    # create .tgz file in temp_dir
266   
267   
268   
269def usage(msg=None):
270    """Give befuddled user some help."""
271
272    if msg:
273        print(msg)
274    print('usage: create_win_installer [<revision_number>]\n'
275          'where <revision_number> is an optional revision number to release.')
276
277
278def xlog(msg):
279    """Print and log a message."""
280
281    print(msg)
282   
283    # uncomment this to get file logging
284##    log(msg)
285   
286
287if __name__ == '__main__':
288    global Force
289   
290    if sys.platform != 'win32':
291        msg = ('This script is not written for Linux.  '
292               'Please run it on a Windows platform.')
293        raise Exception(msg)
294
295    argv = sys.argv[1:]
296
297    try:
298        opts, args = getopt.getopt(argv, 'hf', ['help', 'force'])
299    except getopt.error, msg:
300        usage()
301        sys.exit(10)
302
303    Force = False
304    for (opt, param) in opts:
305        if opt in ['-h', '--help']:
306            usage()
307            sys.exit(0)
308        elif opt in ['-f', '--force']:
309            Force = True
310
311    if len(args) > 1:
312        usage()
313        sys.exit(10)
314
315    revision = None
316    if len(args) == 1:
317        try:
318            revision = int(args[0])
319        except ValueError:
320            usage()
321            sys.exit(10)
322
323    make_installer(revision)
Note: See TracBrowser for help on using the repository browser.