source: trunk/GSASIIpath.py @ 1047

Last change on this file since 1047 was 1047, checked in by toby, 10 years ago

change update for new windows; improve About box

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