source: trunk/GSASIIpath.py @ 939

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

fix & cleanup unit tests; add/change doc strings for sphinx; add all G2 py files to sphinx

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 6.8 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.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
53# routines for looking a version numbers in files
54version = -1
55def SetVersionNumber(RevString):
56    '''Set the subversion version number
57
58    :param str RevString: something like "$Revision: 939 $"
59      that is set by subversion when the file is retrieved from subversion.
60
61    Place ``GSASIIpath.SetVersionNumber("$Revision: 939 $")`` in every python
62    file.
63    '''
64    try:
65        RevVersion = int(RevString.split(':')[1].split()[0])
66        global version
67        version = max(version,RevVersion)
68    except:
69        pass
70       
71def GetVersionNumber():
72    '''Return the maximum version number seen in :func:`SetVersionNumber`
73    '''
74    return version
75
76# routines to interface with subversion
77def whichsvn():
78    '''Returns a path to the subversion exe file, if any is found.
79    Searches the current path as well as subdirectory "svn" and
80    "svn/bin" in the location of the GSASII source files.
81
82    :returns: None if svn is not found.
83    '''
84    def is_exe(fpath):
85        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
86    svnprog = 'svn'
87    if sys.platform == "win32": svnprog += '.exe'
88    pathlist = os.environ["PATH"].split(os.pathsep)
89    pathlist.insert(0,os.path.join(os.path.split(__file__)[0],'svn'))
90    pathlist.insert(1,os.path.join(os.path.split(__file__)[0],'svn','bin'))
91    for path in pathlist:
92        exe_file = os.path.join(path, svnprog)
93        if is_exe(exe_file):
94            return exe_file
95
96def svnGetRev(fpath=os.path.split(__file__)[0],local=True):
97    '''This obtains the version number for the either the latest local last update
98    or contacts the subversion server to get the latest update version (# of Head).
99
100    :param fpath: path to repository dictionary, defaults to directory where
101       the current file is located
102    :param local: determines the type of version number, where
103       True (default): returns the latest installed update
104       False: returns the version number of Head on the server
105
106    :Returns: the version number as an str or
107       None if there is a subversion error (likely because the path is
108       not a repository or svn is not found)
109    '''
110
111    import subprocess
112    import xml.etree.ElementTree as ET
113    svn = whichsvn()
114    if not svn: return
115    if local:
116        cmd = [svn,'info',fpath,'--xml']
117    else:
118        cmd = [svn,'info',fpath,'--xml','-rHEAD']
119    s = subprocess.Popen(cmd,
120                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
121    out,err = s.communicate()
122    if err:
123        print 'out=',out
124        print 'err=',err
125        return None
126    x = ET.fromstring(out)
127    for i in x.iter('entry'):
128        rev = i.attrib.get('revision')
129        if rev: return rev
130
131def svnFindLocalChanges(fpath=os.path.split(__file__)[0]):
132    '''Returns a list of files that were changed locally. If no files are changed,
133       the list has length 0
134
135    :param fpath: path to repository dictionary, defaults to directory where
136       the current file is located
137
138    :returns: None if there is a subversion error (likely because the path is
139       not a repository or svn is not found)
140
141    '''
142    import subprocess
143    import xml.etree.ElementTree as ET
144    svn = whichsvn()
145    if not svn: return
146    s = subprocess.Popen([svn,'status',fpath,'--xml'],
147                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
148    out,err = s.communicate()
149    if err: return None
150    x = ET.fromstring(out)
151    changed = []
152    for i in x.iter('entry'):
153        if i.find('wc-status').attrib.get('item') == 'modified': 
154            changed.append(i.attrib.get('path'))
155    return changed
156
157def svnUpdateDir(fpath=os.path.split(__file__)[0]):
158    '''This performs an update of the files in a local directory from a server.
159
160    :param fpath: path to repository dictionary, defaults to directory where
161       the current file is located
162
163    :returns: A dictionary with the files that have been changed/added and
164          a code describing how they have been updated (see changetype) ro
165          None if there is a subversion error (likely because the path is
166          not a repository or svn is not found)
167
168    '''
169    import subprocess
170    changetype = {'A': 'Added', 'D': 'Deleted', 'U': 'Updated',
171                  'C': 'Conflict', 'G': 'Merged', 'E': 'Replaced'}
172    svn = whichsvn()
173    if not svn: return
174    cmd = [svn,'update',fpath,'-rHEAD',
175           '--non-interactive',
176           '--accept','theirs-conflict','--force']
177    s = subprocess.Popen(cmd, 
178                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
179    out,err = s.communicate()
180    if err: return
181    l = out.split()
182    updates = {}
183    for i,j in zip(l[::2],l[1::2]):
184        if i == 'Updated': break
185        if i == 'At': break
186        t = changetype.get(i[0])
187        if not t: continue
188        updates[j] = t
189    return updates
Note: See TracBrowser for help on using the repository browser.