source: trunk/GSASIIpath.py @ 1355

Last change on this file since 1355 was 1355, checked in by toby, 9 years ago

initial 10.9/Canopy fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 9.7 KB
Line 
1# -*- coding: utf-8 -*-
2'''
3*GSASIIpath: locations & updates*
4---------------------------------
5
6Routines for dealing with file locations, etc.
7
8Determines the location of the compiled (.pyd or .so) libraries.
9
10Interfaces with subversion (svn):
11Determine the subversion release number by determining the highest version number
12where :func:`SetVersionNumber` is called (best done in every GSASII file).
13Other routines will update GSASII from the subversion server if svn can be
14found.
15'''
16
17import os
18import sys
19import platform
20# determine a binary path for the pyd files based on the host OS and the python version, 
21# path is relative to location of the script that is called as well as this file
22# this must be imported before anything that imports any .pyd/.so file for GSASII
23bindir = None
24if sys.platform == "win32":
25    if platform.architecture()[0] == '64bit':
26        bindir = 'binwin64-%d.%d' % sys.version_info[0:2]
27    else:
28        bindir = 'binwin%d.%d' % sys.version_info[0:2]
29elif sys.platform == "darwin":
30    import platform
31    if platform.architecture()[0] == '64bit':
32        bindir = 'binmac64-%d.%d' % sys.version_info[0:2]
33    else:
34        bindir = 'binmac%d.%d' % sys.version_info[0:2]
35    if platform.mac_ver()[0].startswith('10.5.'):
36        bindir += '_10.5'
37elif sys.platform == "linux2":
38    if platform.architecture()[0] == '64bit':
39        bindir = 'binlinux64-%d.%d' % sys.version_info[0:2]
40    else:
41        bindir = 'binlinux%d.%d' % sys.version_info[0:2]
42for loc in sys.path[0],os.path.abspath(os.path.split(__file__)[0]):
43    if bindir:
44        if os.path.exists(os.path.join(loc,bindir)) and os.path.join(loc,bindir) not in sys.path: 
45            sys.path.insert(0,os.path.join(loc,bindir))
46        # is there a bin directory? (created by a local compile), if so put
47        # that at the top of the path
48    if os.path.exists(os.path.join(loc,'bin')) and os.path.getsize(os.path.join(loc,'bin')):
49        bindir = 'bin'
50        if os.path.join(loc,'bin') not in sys.path: 
51            sys.path.insert(0,os.path.join(loc,bindir))
52print 'GSAS-II binary directory: ',os.path.join(loc,bindir)
53if bindir == None:
54    raise Exception,"**** ERROR GSAS-II binary libraries not found, GSAS-II fails ****"
55# add the data import and export directory to the search path
56path2GSAS2 = os.path.dirname(os.path.realpath(__file__)) # location of this file; save before any changes in pwd
57newpath = os.path.join(path2GSAS2,'imports')
58if newpath not in sys.path: sys.path.append(newpath)
59newpath = os.path.join(path2GSAS2,'exports')
60if newpath not in sys.path: sys.path.append(newpath)
61
62# routines for looking a version numbers in files
63version = -1
64def SetVersionNumber(RevString):
65    '''Set the subversion version number
66
67    :param str RevString: something like "$Revision: 1355 $"
68      that is set by subversion when the file is retrieved from subversion.
69
70    Place ``GSASIIpath.SetVersionNumber("$Revision: 1355 $")`` in every python
71    file.
72    '''
73    try:
74        RevVersion = int(RevString.split(':')[1].split()[0])
75        global version
76        version = max(version,RevVersion)
77    except:
78        pass
79       
80def GetVersionNumber():
81    '''Return the maximum version number seen in :func:`SetVersionNumber`
82    '''
83    return version
84
85# routines to interface with subversion
86def whichsvn():
87    '''Returns a path to the subversion exe file, if any is found.
88    Searches the current path as well as subdirectory "svn" and
89    "svn/bin" in the location of the GSASII source files.
90
91    :returns: None if svn is not found or an absolute path to the subversion
92      executable file.
93    '''
94    def is_exe(fpath):
95        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
96    svnprog = 'svn'
97    if sys.platform == "win32": svnprog += '.exe'
98    pathlist = os.environ["PATH"].split(os.pathsep)
99    pathlist.insert(0,os.path.join(os.path.split(__file__)[0],'svn'))
100    pathlist.insert(1,os.path.join(os.path.split(__file__)[0],'svn','bin'))
101    for path in pathlist:
102        exe_file = os.path.join(path, svnprog)
103        if is_exe(exe_file):
104            return os.path.abspath(exe_file)
105
106def svnGetLog(fpath=os.path.split(__file__)[0],version=None):
107    '''Get the revision log information for a specific version of the
108
109    :param str fpath: path to repository dictionary, defaults to directory where
110       the current file is located.
111    :param int version: the version number to be looked up or None (default)
112       for the latest version.
113
114    :returns: a dictionary with keys (one hopes) 'author', 'date', 'msg', and 'revision'
115
116    '''
117    import subprocess
118    import xml.etree.ElementTree as ET
119    svn = whichsvn()
120    if not svn: return
121    if version is not None:
122        vstr = '-r'+str(version)
123    else:
124        vstr = '-rHEAD'
125
126    cmd = [svn,'log',fpath,'--xml',vstr]
127    s = subprocess.Popen(cmd,
128                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
129    out,err = s.communicate()
130    if err:
131        print 'out=',out
132        print 'err=',err
133        return None
134    x = ET.fromstring(out)
135    d = {}
136    for i in x.iter('logentry'):
137        d = {'revision':i.attrib.get('revision','?')}
138        for j in i:
139            d[j.tag] = j.text
140        break # only need the first
141    return d
142
143def svnGetRev(fpath=os.path.split(__file__)[0],local=True):
144    '''Obtain the version number for the either the last update of the local version
145    or contacts the subversion server to get the latest update version (# of Head).
146
147    :param str fpath: path to repository dictionary, defaults to directory where
148       the current file is located
149    :param bool local: determines the type of version number, where
150       True (default): returns the latest installed update
151       False: returns the version number of Head on the server
152
153    :Returns: the version number as an str or
154       None if there is a subversion error (likely because the path is
155       not a repository or svn is not found)
156    '''
157
158    import subprocess
159    import xml.etree.ElementTree as ET
160    svn = whichsvn()
161    if not svn: return
162    if local:
163        cmd = [svn,'info',fpath,'--xml']
164    else:
165        cmd = [svn,'info',fpath,'--xml','-rHEAD']
166    s = subprocess.Popen(cmd,
167                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
168    out,err = s.communicate()
169    if err:
170        print 'out=',out
171        print 'err=',err
172        return None
173    x = ET.fromstring(out)
174    for i in x.iter('entry'):
175        rev = i.attrib.get('revision')
176        if rev: return rev
177
178def svnFindLocalChanges(fpath=os.path.split(__file__)[0]):
179    '''Returns a list of files that were changed locally. If no files are changed,
180       the list has length 0
181
182    :param fpath: path to repository dictionary, defaults to directory where
183       the current file is located
184
185    :returns: None if there is a subversion error (likely because the path is
186       not a repository or svn is not found)
187
188    '''
189    import subprocess
190    import xml.etree.ElementTree as ET
191    svn = whichsvn()
192    if not svn: return
193    s = subprocess.Popen([svn,'status',fpath,'--xml'],
194                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
195    out,err = s.communicate()
196    if err: return None
197    x = ET.fromstring(out)
198    changed = []
199    for i in x.iter('entry'):
200        if i.find('wc-status').attrib.get('item') == 'modified': 
201            changed.append(i.attrib.get('path'))
202    return changed
203
204def svnUpdateDir(fpath=os.path.split(__file__)[0],version=None):
205    '''This performs an update of the files in a local directory from a server.
206
207    :param str fpath: path to repository dictionary, defaults to directory where
208       the current file is located
209    :param version: the number of the version to be loaded. Used only
210       cast as a string, but should be an integer or something that corresponds to a
211       string representation of an integer value when cast. A value of None (default)
212       causes the latest version on the server to be used.
213    '''
214    import subprocess
215    svn = whichsvn()
216    if not svn: return
217    if version:
218        verstr = '-r' + str(version)
219    else:
220        verstr = '-rHEAD'
221    cmd = [svn,'update',fpath,verstr,
222           '--non-interactive',
223           '--accept','theirs-conflict','--force']
224    s = subprocess.Popen(cmd, 
225                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
226    out,err = s.communicate()
227    print out
228    if err:
229        print(60*"=")
230        print ("****** An error was noted, see below *********")
231        print(60*"=")
232        print err
233        sys.exit()
234
235def svnUpdateProcess(version=None,projectfile=None):
236    '''perform an update of GSAS-II in a separate python process'''
237    import subprocess
238    if not projectfile:
239        projectfile = ''
240    else:
241        projectfile = os.path.realpath(projectfile)
242        print 'restart using',projectfile
243    if not version:
244        version = ''
245    else:
246        version = str(version)
247    # start the upgrade in a separate interpreter (avoids loading .pyd files)
248    subprocess.Popen([sys.executable,__file__,projectfile,version])
249    sys.exit()
250
251if __name__ == '__main__':
252    import subprocess
253    import time
254    time.sleep(1) # delay to give the main process a chance to exit
255    # perform an update and restart GSAS-II
256    project,version = sys.argv[1:3]
257    loc = os.path.dirname(__file__)
258    if version:
259        print("Regress to version "+str(version))
260        svnUpdateDir(loc,version=version)
261    else:
262        print("Update to current version")
263        svnUpdateDir(loc)
264    if project:
265        print("Restart GSAS-II with project file "+str(project))
266        subprocess.Popen([sys.executable,os.path.join(loc,'GSASII.py'),project])
267    else:
268        print("Restart GSAS-II without a project file ")
269        subprocess.Popen([sys.executable,os.path.join(loc,'GSASII.py')])
270    print 'exiting update process'
271    sys.exit()
272   
Note: See TracBrowser for help on using the repository browser.