source: trunk/create_win_installer.py @ 8721

Last change on this file since 8721 was 8011, checked in by steve, 14 years ago

Tested parallel code with new anuga interface. Seems to be working

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