source: anuga_core/source/anuga/utilities/system_tools.py @ 5921

Last change on this file since 5921 was 5921, checked in by ole, 14 years ago

Fixed CRC computation for Itanium 64 bit architecture.
All 769 tests now pass on the ANU ac

File size: 7.1 KB
Line 
1"""Implementation of tools to do with system administration made as platform independent as possible.
2
3
4"""
5
6import sys
7import os
8
9def log_to_file(filename, s, verbose=False):
10    """Log string to file name
11    """
12
13    fid = open(filename, 'a')
14    if verbose: print s
15    fid.write(s + '\n')
16    fid.close()
17
18
19def get_user_name():
20    """Get user name provide by operating system
21    """
22
23    if sys.platform == 'win32':
24        #user = os.getenv('USERPROFILE')
25        user = os.getenv('USERNAME')
26    else:
27        user = os.getenv('LOGNAME')
28
29
30    return user   
31
32def get_host_name():
33    """Get host name provide by operating system
34    """
35
36    if sys.platform == 'win32':
37        host = os.getenv('COMPUTERNAME')
38    else:
39        host = os.uname()[1]
40
41
42    return host   
43
44def get_revision_number():
45    """Get the version number of the SVN
46    NOTE: This requires that the command svn is on the system PATH
47    (simply aliasing svn to the binary will not work)
48    """
49
50    # Create dummy info
51    #info = 'Revision: Version info could not be obtained.'
52    #info += 'A command line version of svn must be availbable '
53    #info += 'on the system PATH, access to the subversion '
54    #info += 'repository is necessary and the output must '
55    #info += 'contain a line starting with "Revision:"'
56   
57
58    #FIXME (Ole): Change this so that svn info is attempted first.
59    # If that fails, try to read a stored file with that same info (this would be created by e.g. the release script). Failing that, throw an exception.
60
61    #FIXME (Ole): Move this and store_version_info to utilities
62
63
64    try:
65        from anuga.stored_version_info import version_info
66    except:
67        msg = 'No version info stored and command "svn" is not '
68        msg += 'recognised on the system PATH.\n\n'
69        msg += 'If ANUGA has been installed from a distribution e.g. as '
70        msg += 'obtained from SourceForge,\n'
71        msg += 'the version info should be '
72        msg += 'available in the automatically generated file '
73        msg += 'stored_version_info.py\n'
74        msg += 'in the anuga root directory.\n'
75        msg += 'If run from a Subversion sandpit, '
76        msg += 'ANUGA will try to obtain the version info '
77        msg += 'by using the command: "svn info".\n'
78        msg += 'In this case, make sure svn is accessible on the system path. '
79        msg += 'Simply aliasing svn to the binary will not work. '
80        msg += 'Good luck!'
81
82        # No file available - try using Subversion
83        try:
84            # The null stuff is so this section fails quitly.
85            # This could cause the svn info command to fail due to
86            # the redirection being bad on some platforms.
87            # If that occurs then change this code.
88            if sys.platform[0:3] == 'win':
89                fid = os.popen('svn info 2> null')
90            else:
91                fid = os.popen('svn info 2>/dev/null')
92       
93        except:
94            raise Exception(msg)
95        else:
96            #print 'Got version from svn'           
97            version_info = fid.read()
98           
99            if version_info == '':
100                raise Exception(msg)   
101    else:
102        pass
103        #print 'Got version from file'
104
105           
106    for line in version_info.split('\n'):
107        if line.startswith('Revision:'):
108            break
109
110    fields = line.split(':')
111    msg = 'Keyword "Revision" was not found anywhere in text: %s' %version_info
112    assert fields[0].startswith('Revision'), msg           
113
114    try:
115        revision_number = int(fields[1])
116    except:
117        msg = 'Revision number must be an integer. I got %s' %fields[1]
118        msg += 'Check that the command svn is on the system path' 
119        raise Exception(msg)               
120       
121    return revision_number
122
123
124def store_version_info(destination_path='.', verbose=False):
125    """Obtain current version from Subversion and store it.
126   
127    Title: store_version_info()
128
129    Author: Ole Nielsen (Ole.Nielsen@ga.gov.au)
130
131    CreationDate: January 2006
132
133    Description:
134        This function obtains current version from Subversion and stores it
135        is a Python file named 'stored_version_info.py' for use with
136        get_version_info()
137
138        If svn is not available on the system PATH, an Exception is thrown
139    """
140
141    # Note (Ole): This function should not be unit tested as it will only
142    # work when running out of the sandpit. End users downloading the
143    # ANUGA distribution would see a failure.
144    #
145    # FIXME: This function should really only be used by developers (
146    # (e.g. for creating new ANUGA releases), so maybe it should move
147    # to somewhere else.
148   
149    import config
150
151    try:
152        fid = os.popen('svn info')
153    except:
154        msg = 'Command "svn" is not recognised on the system PATH'
155        raise Exception(msg)
156    else:   
157        txt = fid.read()
158        fid.close()
159
160
161        # Determine absolute filename
162        if destination_path[-1] != os.sep:
163            destination_path += os.sep
164           
165        filename = destination_path + config.version_filename
166
167        fid = open(filename, 'w')
168
169        docstring = 'Stored version info.\n\n'
170        docstring += 'This file provides the version for distributions '
171        docstring += 'that are not accessing Subversion directly.\n'
172        docstring += 'The file is automatically generated and should not '
173        docstring += 'be modified manually.\n'
174        fid.write('"""%s"""\n\n' %docstring)
175       
176        fid.write('version_info = """\n%s"""' %txt)
177        fid.close()
178
179
180        if verbose is True:
181            print 'Version info stored to %s' %filename
182
183def safe_crc(string):
184    """64 bit safe crc computation.
185
186       See Guido's 64 bit fix at http://bugs.python.org/issue1202           
187    """
188
189    from zlib import crc32
190    import os
191
192    x = crc32(string)
193       
194    if os.name == 'posix' and os.uname()[4] in ['x86_64', 'ia64']:
195        crcval = x - ((x & 0x80000000) << 1)
196    else:
197        crcval = x
198       
199    return crcval
200
201
202def compute_checksum(filename, max_length=2**20):
203    """Compute the CRC32 checksum for specified file
204
205    Optional parameter max_length sets the maximum number
206    of bytes used to limit time used with large files.
207    Default = 2**20 (1MB)
208    """
209
210    fid = open(filename, 'rb') # Use binary for portability
211    crcval = safe_crc(fid.read(max_length))
212    fid.close()
213
214    return crcval
215
216def get_pathname_from_package(package):
217    """Get pathname of given package (provided as string)
218
219    This is useful for reading files residing in the same directory as
220    a particular module. Typically, this is required in unit tests depending
221    on external files.
222
223    The given module must start from a directory on the pythonpath
224    and be importable using the import statement.
225
226    Example
227    path = get_pathname_from_package('anuga.utilities')
228
229    """
230
231    exec('import %s as x' %package)
232
233    path = x.__path__[0]
234   
235    return path
236
237    # Alternative approach that has been used at times
238    #try:
239    #    # When unit test is run from current dir
240    #    p1 = read_polygon('mainland_only.csv')
241    #except:
242    #    # When unit test is run from ANUGA root dir
243    #    from os.path import join, split
244    #    dir, tail = split(__file__)
245    #    path = join(dir, 'mainland_only.csv')
246    #    p1 = read_polygon(path)
247       
248           
249
250
Note: See TracBrowser for help on using the repository browser.