source: branch/2frame/GSASIIpath.py @ 2998

Last change on this file since 2998 was 2998, checked in by toby, 5 years ago

merge trunk into 2frame

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
  • Property svn:mergeinfo set to
    /trunk/GSASIIpath.pymergedeligible
File size: 30.3 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
16Accesses configuration options, as defined in config.py
17'''
18
19import os
20import sys
21import platform
22import glob
23import subprocess
24import numpy as np
25
26g2home = 'https://subversion.xray.aps.anl.gov/pyGSAS'
27'Define the location of the GSAS-II subversion repository'
28   
29path2GSAS2 = os.path.dirname(os.path.realpath(__file__)) # location of this file; save before any changes in pwd
30
31# convert version numbers as '1.2.3' to integers (1002) and back (to 1.2)
32fmtver = lambda v: str(v//1000)+'.'+str(v%1000)
33intver = lambda vs: sum([int(i) for i in vs.split('.')[0:2]]*np.array((1000,1)))
34
35def GetConfigValue(key,default=None):
36    '''Return the configuration file value for key or a default value if not present
37   
38    :param str key: a value to be found in the configuration (config.py) file
39    :param default: a value to be supplied is none is in the config file or
40      the config file is not found. Defaults to None
41    :returns: the value found or the default.
42    '''
43    try:
44        return configDict.get(key,default)
45    except NameError: # this happens when building docs
46        return None
47
48def SetConfigValue(parmdict):
49    '''Set configuration variables from a dictionary where elements are lists
50    First item in list is the default value and second is the value to use.
51    '''
52    global configDict
53    for var in parmdict:
54        if var in configDict:
55            del configDict[var]
56        if isinstance(parmdict[var],tuple):
57            configDict[var] = parmdict[var]
58        else:
59            if parmdict[var][1] is None: continue
60            if parmdict[var][1] == '': continue
61            if parmdict[var][0] == parmdict[var][1]: continue
62            configDict[var] = parmdict[var][1]
63
64# routines for looking a version numbers in files
65version = -1
66def SetVersionNumber(RevString):
67    '''Set the subversion version number
68
69    :param str RevString: something like "$Revision: 2998 $"
70      that is set by subversion when the file is retrieved from subversion.
71
72    Place ``GSASIIpath.SetVersionNumber("$Revision: 2998 $")`` in every python
73    file.
74    '''
75    try:
76        RevVersion = int(RevString.split(':')[1].split()[0])
77        global version
78        version = max(version,RevVersion)
79    except:
80        pass
81       
82def GetVersionNumber():
83    '''Return the maximum version number seen in :func:`SetVersionNumber`
84    '''
85    if version > 1000:
86        return version
87    else:
88        return "unknown"
89
90def LoadConfigFile(filename):
91    '''Read a GSAS-II configuration file.
92    Comments (starting with "%") are removed, as are empty lines
93   
94    :param str filename: base file name (such as 'file.dat'). Files with this name
95      are located from the path and the contents of each are concatenated.
96    :returns: a list containing each non-empty (after removal of comments) line
97      found in every matching config file.
98    '''
99    info = []
100    for path in sys.path:
101        fil = os.path.join(path,filename)
102        if not os.path.exists(fil): continue
103        try:
104            i = 0
105            fp = open(fil,'r')
106            for line in fp:
107                expr = line.split('#')[0].strip()
108                if expr:
109                    info.append(expr)
110                    i += 1
111            print(str(i)+' lines read from config file '+fil)
112        finally:
113            fp.close()
114    return info
115
116
117# routines to interface with subversion
118proxycmds = []
119'Used to hold proxy information for subversion, set if needed in whichsvn'
120svnLocCache = None
121'Cached location of svn to avoid multiple searches for it'
122
123def whichsvn():
124    '''Returns a path to the subversion exe file, if any is found.
125    Searches the current path after adding likely places where GSAS-II
126    might install svn.
127
128    :returns: None if svn is not found or an absolute path to the subversion
129      executable file.
130    '''
131    # use a previosuly cached svn location
132    global svnLocCache
133    if svnLocCache: return svnLocCache
134    # prepare to find svn
135    is_exe = lambda fpath: os.path.isfile(fpath) and os.access(fpath, os.X_OK)
136    svnprog = 'svn'
137    if sys.platform.startswith('win'): svnprog += '.exe'
138    gsaspath = os.path.split(__file__)[0]
139    # check for a proxy
140    proxyinfo = os.path.join(gsaspath,"proxyinfo.txt")
141    if os.path.exists(proxyinfo):
142        global proxycmds
143        proxycmds = []
144        fp = open(proxyinfo,'r')
145        host = fp.readline().strip()
146        port = fp.readline().strip()
147        fp.close()
148        proxycmds.append('--config-option')
149        proxycmds.append('servers:global:http-proxy-host='+host)
150        proxycmds.append('--config-option')
151        proxycmds.append('servers:global:http-proxy-port='+port)
152    # add likely places to find subversion when installed with GSAS-II
153    pathlist = os.environ["PATH"].split(os.pathsep)
154    pathlist.append(os.path.split(sys.executable)[0])
155    pathlist.append(gsaspath)
156    for rpt in ('..','bin'),('..','Library','bin'),('svn','bin'),('svn',),('.'):
157        pt = os.path.normpath(os.path.join(gsaspath,*rpt))
158        if os.path.exists(pt):
159            pathlist.insert(0,pt)   
160    # search path for svn or svn.exe
161    for path in pathlist:
162        exe_file = os.path.join(path, svnprog)
163        if is_exe(exe_file):
164            try:
165                p = subprocess.Popen([exe_file,'help'],stdout=subprocess.PIPE)
166                res = p.stdout.read()
167                p.communicate()
168                svnLocCache = os.path.abspath(exe_file)
169                return svnLocCache
170            except:
171                pass       
172    svnLocCache = None
173
174def svnVersion(svn=None):
175    '''Get the version number of the current subversion executable
176
177    :returns: a string with a version number such as "1.6.6" or None if
178      subversion is not found.
179
180    '''
181    if not svn: svn = whichsvn()
182    if not svn: return
183
184    cmd = [svn,'--version','--quiet']
185    s = subprocess.Popen(cmd,
186                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
187    out,err = s.communicate()
188    if err:
189        print 'subversion error!\nout=',out
190        print 'err=',err
191        return None
192    return out.strip()
193
194def svnVersionNumber(svn=None):
195    '''Get the version number of the current subversion executable
196
197    :returns: a fractional version number such as 1.6 or None if
198      subversion is not found.
199
200    '''
201    ver = svnVersion(svn)
202    if not ver: return 
203    M,m = ver.split('.')[:2]
204    return int(M)+int(m)/10.
205
206def svnGetLog(fpath=os.path.split(__file__)[0],version=None):
207    '''Get the revision log information for a specific version of the specified package
208
209    :param str fpath: path to repository dictionary, defaults to directory where
210       the current file is located.
211    :param int version: the version number to be looked up or None (default)
212       for the latest version.
213
214    :returns: a dictionary with keys (one hopes) 'author', 'date', 'msg', and 'revision'
215
216    '''
217    import xml.etree.ElementTree as ET
218    svn = whichsvn()
219    if not svn: return
220    if version is not None:
221        vstr = '-r'+str(version)
222    else:
223        vstr = '-rHEAD'
224
225    cmd = [svn,'log',fpath,'--xml',vstr]
226    if proxycmds: cmd += proxycmds
227    s = subprocess.Popen(cmd,
228                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
229    out,err = s.communicate()
230    if err:
231        print 'out=',out
232        print 'err=',err
233        return None
234    x = ET.fromstring(out)
235    d = {}
236    for i in x.iter('logentry'):
237        d = {'revision':i.attrib.get('revision','?')}
238        for j in i:
239            d[j.tag] = j.text
240        break # only need the first
241    return d
242
243svnLastError = ''
244def svnGetRev(fpath=os.path.split(__file__)[0],local=True):
245    '''Obtain the version number for the either the last update of the local version
246    or contacts the subversion server to get the latest update version (# of Head).
247
248    :param str fpath: path to repository dictionary, defaults to directory where
249       the current file is located
250    :param bool local: determines the type of version number, where
251       True (default): returns the latest installed update
252       False: returns the version number of Head on the server
253
254    :Returns: the version number as an str or
255       None if there is a subversion error (likely because the path is
256       not a repository or svn is not found). The error message is placed in
257       global variable svnLastError
258    '''
259
260    import xml.etree.ElementTree as ET
261    svn = whichsvn()
262    if not svn: return
263    if local:
264        cmd = [svn,'info',fpath,'--xml']
265    else:
266        cmd = [svn,'info',fpath,'--xml','-rHEAD']
267    if svnVersionNumber() >= 1.6:
268        cmd += ['--non-interactive', '--trust-server-cert']
269    if proxycmds: cmd += proxycmds
270    s = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
271    out,err = s.communicate()
272    if err:
273        print 'svn failed\n',out
274        print 'err=',err
275        global svnLastError
276        svnLastError = err
277        return None
278    x = ET.fromstring(out)
279    for i in x.iter('entry'):
280        rev = i.attrib.get('revision')
281        if rev: return rev
282
283def svnFindLocalChanges(fpath=os.path.split(__file__)[0]):
284    '''Returns a list of files that were changed locally. If no files are changed,
285       the list has length 0
286
287    :param fpath: path to repository dictionary, defaults to directory where
288       the current file is located
289
290    :returns: None if there is a subversion error (likely because the path is
291       not a repository or svn is not found)
292
293    '''
294    import xml.etree.ElementTree as ET
295    svn = whichsvn()
296    if not svn: return
297    cmd = [svn,'status',fpath,'--xml']
298    if proxycmds: cmd += proxycmds
299    s = subprocess.Popen(cmd,
300                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
301    out,err = s.communicate()
302    if err: return None
303    x = ET.fromstring(out)
304    changed = []
305    for i in x.iter('entry'):
306        if i.find('wc-status').attrib.get('item') == 'modified': 
307            changed.append(i.attrib.get('path'))
308    return changed
309
310def svnUpdateDir(fpath=os.path.split(__file__)[0],version=None):
311    '''This performs an update of the files in a local directory from a server.
312
313    :param str fpath: path to repository dictionary, defaults to directory where
314       the current file is located
315    :param version: the number of the version to be loaded. Used only
316       cast as a string, but should be an integer or something that corresponds to a
317       string representation of an integer value when cast. A value of None (default)
318       causes the latest version on the server to be used.
319    '''
320    svn = whichsvn()
321    if not svn: return
322    if version:
323        verstr = '-r' + str(version)
324    else:
325        verstr = '-rHEAD'
326    cmd = [svn,'update',fpath,verstr,
327           '--non-interactive',
328           '--accept','theirs-conflict','--force']
329    if svnVersionNumber() >= 1.6:
330        cmd += ['--trust-server-cert']
331    if proxycmds: cmd += proxycmds
332    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
333    out,err = s.communicate()
334    if err:
335        print(60*"=")
336        print ("****** An error was noted, see below *********")
337        print(60*"=")
338        print err
339        sys.exit()
340
341def svnUpgrade(fpath=os.path.split(__file__)[0]):
342    '''This reformats subversion files, which may be needed if an upgrade of subversion is
343    done.
344
345    :param str fpath: path to repository dictionary, defaults to directory where
346       the current file is located
347    '''
348    svn = whichsvn()
349    if not svn: return
350    cmd = [svn,'upgrade',fpath,'--non-interactive']
351    if proxycmds: cmd += proxycmds
352    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
353    out,err = s.communicate()
354    if err:
355        print("svn upgrade did not happen (this is probably OK). Messages:")
356        print err
357           
358def svnUpdateProcess(version=None,projectfile=None,branch=None):
359    '''perform an update of GSAS-II in a separate python process'''
360    if not projectfile:
361        projectfile = ''
362    else:
363        projectfile = os.path.realpath(projectfile)
364        print 'restart using',projectfile
365    if branch:
366        version = branch
367    elif not version:
368        version = ''
369    else:
370        version = str(version)
371    # start the upgrade in a separate interpreter (avoids loading .pyd files)
372    subprocess.Popen([sys.executable,__file__,projectfile,version])
373    sys.exit()
374
375def svnSwitchDir(rpath,filename,baseURL,loadpath=None,verbose=True):
376    '''This performs a switch command to move files between subversion trees.
377    Note that if the files were previously downloaded,
378    the switch command will update the files to the newest version.
379   
380    :param str rpath: path to locate files, relative to the GSAS-II
381      installation path (defaults to path2GSAS2)
382    :param str URL: the repository URL
383    :param str loadpath: the prefix for the path, if specified. Defaults to path2GSAS2
384    :param bool verbose: if True (default) diagnostics are printed
385    '''
386    svn = whichsvn()
387    if not svn: return
388    URL = baseURL[:]
389    if baseURL[-1] != '/':
390        URL = baseURL + '/' + filename
391    else:
392        URL = baseURL + filename
393    if loadpath:
394        fpath = os.path.join(loadpath,rpath,filename)
395    else:
396        fpath = os.path.join(path2GSAS2,rpath,filename)
397    cmd = [svn,'switch',URL,fpath,
398           '--non-interactive','--trust-server-cert',
399           '--accept','theirs-conflict','--force']
400    if svnVersionNumber(svn) > 1.6: cmd += ['--ignore-ancestry']
401    if proxycmds: cmd += proxycmds
402    if verbose: print(u"Loading files to "+fpath+u"\n  from "+URL)
403    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
404    out,err = s.communicate()
405    if err:
406        print(60*"=")
407        print ("****** An error was noted, see below *********")
408        print(60*"=")
409        print 'out=',out
410        print 'err=',err
411        return False
412    if verbose:
413        print('=== Output from svn switch'+(43*'='))
414        print(out.strip())
415        print((70*'=')+'\n')
416    return True
417
418def svnInstallDir(URL,loadpath):
419    '''Load a subversion tree into a specified directory
420
421    :param str URL: the repository URL
422    :param str loadpath: path to locate files
423
424    '''
425    svn = whichsvn()
426    if not svn: return
427    cmd = [svn,'co',URL,loadpath,'--non-interactive']
428    if svnVersionNumber() >= 1.6: cmd += ['--trust-server-cert']
429    print("Loading files from "+URL)
430    if proxycmds: cmd += proxycmds
431    s = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
432    out,err = s.communicate()   #this fails too easily
433    if err:
434        print(60*"=")
435        print ("****** An error was noted, see below *********")
436        print(60*"=")
437        print err
438        return False
439    print ("Files installed at: "+loadpath)
440    return True
441
442def GetBinaryPrefix():
443    if sys.platform == "win32":
444        prefix = 'win'
445    elif sys.platform == "darwin":
446        prefix = 'mac'
447    elif sys.platform == "linux2":
448        prefix = 'linux'
449    else:
450        print(u'Unknown platform: '+sys.platform)
451        raise Exception('Unknown platform')
452    if platform.architecture()[0] == '64bit':
453        bits = '64'
454    else:
455        bits = '32'
456
457    # format current python version
458    pyver = 'p{}.{}'.format(*sys.version_info[0:2])
459
460    items = [prefix,bits,pyver]
461    return '_'.join(items)
462
463def DownloadG2Binaries(g2home,verbose=True):
464    '''Download GSAS-II binaries from appropriate section of the
465    GSAS-II svn repository based on the platform, numpy and Python
466    version
467    '''   
468    bindir = GetBinaryPrefix()
469    #npver = 'n{}.{}'.format(*np.__version__.split('.')[0:2])
470    inpver = intver(np.__version__)
471    svn = whichsvn()
472    if not svn:
473        print('**** unable to load files: svn not found ****')
474        return ''
475    # get binaries matching the required type -- other than for the numpy version
476    cmd = [svn, 'list', g2home + '/Binaries/']
477    if proxycmds: cmd += proxycmds
478    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
479    res,err = p.communicate()
480    versions = {}
481    for d in res.split():
482        if d.startswith(bindir):
483            v = intver(d.rstrip('/').split('_')[3].lstrip('n'))
484            versions[v] = d
485    intVersionsList = sorted(versions.keys())
486    if not intVersionsList:
487        print('No binaries located')
488        return
489    elif inpver < min(intVersionsList):
490        vsel = min(intVersionsList)
491        print('Warning: The current numpy version, {}, is older than\n\tthe oldest dist version, {}'
492              .format(np.__version__,fmtver(vsel)))
493    elif inpver >= max(intVersionsList):
494        vsel = max(intVersionsList)
495        if verbose: print(
496                'FYI: The current numpy version, {}, is newer than the newest dist version {}'
497                .format(np.__version__,fmtver(vsel)))
498    else:
499        vsel = min(intVersionsList)
500        for v in intVersionsList:
501            if v <= inpver:
502                vsel = v
503            else:
504                if verbose: print(
505                        'FYI: Selecting dist version {} as the current numpy version, {},\n\tis older than the next dist version {}'
506                        .format(fmtver(vsel),np.__version__,fmtver(v)))
507                break
508    distdir = g2home + '/Binaries/' + versions[vsel]
509    # switch reset command: distdir = g2home + '/trunk/bindist'
510    svnSwitchDir('bindist','',distdir,verbose=verbose)
511    return os.path.join(path2GSAS2,'bindist')
512
513def svnTestBranch(loc=None):
514    '''Returns the name of the branch directory if the installation has been switched.
515    Returns none, if not a branch
516    the test 2frame branch. False otherwise
517    '''
518    if loc is None: loc = path2GSAS2
519    svn = whichsvn()
520    if not svn:
521        print('**** unable to load files: svn not found ****')
522        return ''
523    cmd = [svn, 'info', loc]
524    if proxycmds: cmd += proxycmds
525    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
526    res,err = p.communicate()
527    for l in res.split('\n'):
528        if "Relative URL:" in l: break
529    if "/branch/" in l:
530        return l[l.find("/branch/")+8:].strip()
531    else:
532        return None
533   
534def svnSwitch2branch(branch=None,loc=None,svnHome=None):
535    '''Switch to a subversion branch if specified. Switches to trunk otherwise.
536    '''
537    if svnHome is None: svnHome = g2home
538    svnURL = svnHome + '/trunk'
539    if branch:
540        if svnHome.endswith('/'):
541            svnURL = svnHome[:-1]
542        else:
543            svnURL = svnHome
544        if branch.startswith('/'):
545            svnURL += branch
546        else:
547            svnURL += '/' + branch
548    svnSwitchDir('','',svnURL,loadpath=loc)
549   
550
551def IPyBreak_base(userMsg=None):
552    '''A routine that invokes an IPython session at the calling location
553    This routine is only used when debug=True is set in config.py
554    '''
555    savehook = sys.excepthook # save the exception hook
556    try: 
557        from IPython.terminal.embed import InteractiveShellEmbed
558    except ImportError:
559        try:
560            # try the IPython 0.12 approach
561            from IPython.frontend.terminal.embed import InteractiveShellEmbed
562        except ImportError:
563            print 'IPython InteractiveShellEmbed not found'
564            return
565    import inspect
566    ipshell = InteractiveShellEmbed()
567
568    frame = inspect.currentframe().f_back
569    msg   = 'Entering IPython console inside {0.f_code.co_filename} at line {0.f_lineno}\n'.format(frame)
570    if userMsg: msg += userMsg
571    ipshell(msg,stack_depth=2) # Go up one level, to see the calling routine
572    sys.excepthook = savehook # reset IPython's change to the exception hook
573
574def exceptHook(*args):
575    '''A routine to be called when an exception occurs. It prints the traceback
576    with fancy formatting and then calls an IPython shell with the environment
577    of the exception location.
578   
579    This routine is only used when debug=True is set in config.py   
580    '''
581    from IPython.core import ultratb
582    if 'win' in sys.platform:
583        ultratb.FormattedTB(call_pdb=False,color_scheme='NoColor')(*args)
584    else:
585        ultratb.FormattedTB(call_pdb=False,color_scheme='LightBG')(*args)
586    try: 
587        from IPython.terminal.embed import InteractiveShellEmbed
588    except ImportError:
589        try:
590            # try the IPython 0.12 approach
591            from IPython.frontend.terminal.embed import InteractiveShellEmbed
592        except ImportError:
593            print 'IPython InteractiveShellEmbed not found'
594            return
595    import inspect
596    frame = inspect.getinnerframes(args[2])[-1][0]
597    msg   = 'Entering IPython console at {0.f_code.co_filename} at line {0.f_lineno}\n'.format(frame)
598    savehook = sys.excepthook # save the exception hook
599    try:
600        InteractiveShellEmbed(banner1=msg)(local_ns=frame.f_locals,global_ns=frame.f_globals)
601    except: # use a different call for IPython 5
602        class c(object): pass
603        pseudomod = c() # create something that acts like a module
604        pseudomod.__dict__ = frame.f_locals
605        InteractiveShellEmbed(banner1=msg)(module=pseudomod,global_ns=frame.f_globals)
606    sys.excepthook = savehook # reset IPython's change to the exception hook
607
608def DoNothing():
609    '''A routine that does nothing. This is called in place of IPyBreak and pdbBreak
610    except when the debug option is set True in config.py
611    '''
612    pass 
613
614IPyBreak = DoNothing
615pdbBreak = DoNothing
616def InvokeDebugOpts():
617    'Called in GSASII.py to set up debug options'
618    if GetConfigValue('debug'):
619        print 'Debug on: IPython: Exceptions and G2path.IPyBreak(); pdb: G2path.pdbBreak()'
620        sys.excepthook = exceptHook
621        import pdb
622        global pdbBreak
623        pdbBreak = pdb.set_trace
624        global IPyBreak
625        IPyBreak = IPyBreak_base
626
627def TestSPG(fpth):
628    '''Test if pyspg.[so,.pyd] can be run from a location in the path
629    '''
630    if not os.path.exists(fpth): return False
631    if not glob.glob(os.path.join(fpth,'pyspg.*')): return False
632    savpath = sys.path[:]
633    sys.path = [fpth]
634    # test to see if a shared library can be used
635    try:
636        import pyspg
637        pyspg.sgforpy('P -1')
638    except Exception as err:
639        print(70*'=')
640        print('Failed to run pyspg in {}\nerror: {}'.format(fpth,err))
641        print(70*'=')
642        sys.path = savpath
643        return False
644    sys.path = savpath
645    return True
646   
647# see if a directory for local modifications is defined. If so, stick that in the path
648if os.path.exists(os.path.expanduser('~/.G2local/')):
649    sys.path.insert(0,os.path.expanduser('~/.G2local/'))
650    import glob
651    fl = glob.glob(os.path.expanduser('~/.G2local/GSASII*.py*'))
652    files = ""
653    prev = None
654    for f in sorted(fl): # make a list of files, dropping .pyc files where a .py exists
655        f = os.path.split(f)[1]
656        if os.path.splitext(f)[0] == prev: continue
657        prev = os.path.splitext(f)[0]
658        if files: files += ", "
659        files += f
660    if files:
661        print("*"*75)
662        print("Warning: the following source files are locally overridden in "+os.path.expanduser('~/.G2local/'))
663        print("  "+files)
664        print("*"*75)
665
666BinaryPathLoaded = False
667def SetBinaryPath(printInfo=True):
668    '''
669    Add location of GSAS-II shared libraries (binaries: .so or .pyd files) to path
670   
671    This routine must be executed after GSASIIpath is imported and before any other
672    GSAS-II imports are done.
673    '''
674    # do this only once no matter how many times it is called
675    global BinaryPathLoaded
676    if BinaryPathLoaded: return
677    try:
678        inpver = intver(np.__version__)
679    except AttributeError: # happens on building docs
680        return
681    binpath = None
682    binprfx = GetBinaryPrefix()
683    for loc in os.path.abspath(sys.path[0]),os.path.abspath(os.path.split(__file__)[0]):
684        # Look at bin directory (created by a local compile) before looking for standard dist files
685        searchpathlist = [os.path.join(loc,'bin')]
686        # also look for matching binary dist in loc/AllBinaries
687        versions = {}
688        for d in glob.glob(os.path.join(loc,'AllBinaries',binprfx+'*')):
689            v = intver(d.rstrip('/').split('_')[3].lstrip('n'))
690            versions[v] = d
691        searchpathlist = [os.path.join(loc,'bin')]
692        vmin = None
693        vmax = None
694        for v in sorted(versions.keys()):
695            if v <= inpver:
696                vmin = v
697            elif v > inpver:
698                vmax = v
699                break
700        if vmin in versions:
701            searchpathlist.append(versions[vmin])
702        if vmax in versions:
703            searchpathlist.append(versions[vmax])
704        searchpathlist.append(os.path.join(loc,'bindist'))
705        for fpth in searchpathlist:
706            if TestSPG(fpth):
707                binpath = fpth
708                break       
709        if binpath: break
710    if binpath:                                            # were GSAS-II binaries found
711        sys.path.insert(0,binpath)
712        if printInfo:
713            print('GSAS-II binary directory: {}'.format(binpath))
714        BinaryPathLoaded = True
715    else:                                                  # try loading them
716        if printInfo:
717            print('Attempting to download GSAS-II binary files...')
718        try:
719            binpath = DownloadG2Binaries(g2home)
720        except AttributeError:   # this happens when building in Read The Docs
721            if printInfo:
722                print('Problem with download')
723        if binpath and TestSPG(binpath):
724            if printInfo:
725                print('GSAS-II binary directory: {}'.format(binpath))
726            sys.path.insert(0,binpath)
727            BinaryPathLoaded = True
728        # this must be imported before anything that imports any .pyd/.so file for GSASII
729        else:
730            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
731            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
732            # patch: use old location based on the host OS and the python version, 
733            # path is relative to location of the script that is called as well as this file
734            BinaryPathLoaded = True
735            bindir = None
736            if sys.platform == "win32":
737                if platform.architecture()[0] == '64bit':
738                    bindir = 'binwin64-%d.%d' % sys.version_info[0:2]
739                else:
740                    bindir = 'binwin%d.%d' % sys.version_info[0:2]
741            elif sys.platform == "darwin":
742                if platform.architecture()[0] == '64bit':
743                    bindir = 'binmac64-%d.%d' % sys.version_info[0:2]
744                else:
745                    bindir = 'binmac%d.%d' % sys.version_info[0:2]
746                #if platform.mac_ver()[0].startswith('10.5.'):
747                #    bindir += '_10.5'
748            elif sys.platform == "linux2":
749                if platform.architecture()[0] == '64bit':
750                    bindir = 'binlinux64-%d.%d' % sys.version_info[0:2]
751                else:
752                    bindir = 'binlinux%d.%d' % sys.version_info[0:2]
753            for loc in os.path.abspath(sys.path[0]),os.path.abspath(os.path.split(__file__)[0]):
754            # Look at bin directory (created by a local compile) before standard dist
755            # that at the top of the path
756                fpth = os.path.join(loc,bindir)
757                binpath = fpth
758                if TestSPG(fpth):
759                    sys.path.insert(0,binpath)
760                    if printInfo:
761                        print('\n'+75*'*')
762                        print('  Warning. Using an old-style GSAS-II binary library. This is unexpected')
763                        print('  and will break in future GSAS-II versions. Please contact toby@anl.gov')
764                        print('  so we can learn what is not working on your installation.')
765                        print('GSAS-II binary directory: {}'.format(binpath))
766                        print(75*'*')
767                    break
768            else:
769            # end patch
770            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
771            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
772                if printInfo:
773                    print(75*'*')
774                    print('Use of GSAS-II binary directory {} failed!'.format(binpath))
775                    print(75*'*')
776                raise Exception,"**** ERROR GSAS-II binary libraries not found, GSAS-II cannot run ****"
777
778    # add the data import and export directory to the search path
779    newpath = os.path.join(path2GSAS2,'imports')
780    if newpath not in sys.path: sys.path.append(newpath)
781    newpath = os.path.join(path2GSAS2,'exports')
782    if newpath not in sys.path: sys.path.append(newpath)
783
784    # setup read of config.py, if present
785    global configDict
786    try:
787        import config
788        configDict = config.__dict__
789        import inspect
790        vals = [True for i in inspect.getmembers(config) if '__' not in i[0]]
791        if printInfo:
792            print str(len(vals))+' values read from config file '+os.path.abspath(config.__file__)
793    except ImportError:
794        configDict = {'Clip_on':True}
795    except Exception as err:
796        if printInfo:
797            print("Error importing config.py file: "+str(err))
798        configDict = {'Clip_on':True}
799
800if __name__ == '__main__':
801    '''What follows is called to update (or downdate) GSAS-II in a separate process.
802    '''
803    import time
804    time.sleep(1) # delay to give the main process a chance to exit
805    # perform an update and restart GSAS-II
806    project,version = sys.argv[1:3]
807    loc = os.path.dirname(__file__)
808    if version == 'trunk':
809        svnSwitch2branch('')
810    elif '/' in version:
811        svnSwitch2branch(version)
812    elif version:
813        print("Regress to version "+str(version))
814        svnUpdateDir(loc,version=version)
815    else:
816        print("Update to current version")
817        svnUpdateDir(loc)
818    ex = sys.executable
819    if sys.platform == "darwin": # mac requires pythonw which is not always reported as sys.executable
820        if os.path.exists(ex+'w'): ex += 'w'
821    if project:
822        print("Restart GSAS-II with project file "+str(project))
823        subprocess.Popen([ex,os.path.join(loc,'GSASII.py'),project])
824    else:
825        print("Restart GSAS-II without a project file ")
826        subprocess.Popen([ex,os.path.join(loc,'GSASII.py')])
827    print 'exiting update process'
828    sys.exit()
Note: See TracBrowser for help on using the repository browser.