source: install/bootstrap.py @ 3107

Last change on this file since 3107 was 3107, checked in by toby, 4 years ago

more diagnostics; start improvements on Linux shortcut

File size: 14.8 KB
Line 
1#!/usr/bin/env python
2# Installs GSAS-II from network using subversion and creates platform-specific shortcuts.
3# works for Mac & Linux & Windows
4import os, stat, sys, platform, subprocess
5
6g2home = 'https://subversion.xray.aps.anl.gov/pyGSAS/'
7path2GSAS2 = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
8print('Running bootstrap from {}'.format(path2GSAS2))
9################################################################################
10################################################################################
11# routines copied from GSASIIpath.py
12proxycmds = []
13'Used to hold proxy information for subversion, set if needed in whichsvn'
14svnLocCache = None
15'Cached location of svn to avoid multiple searches for it'
16
17def whichsvn():
18    '''Returns a path to the subversion exe file, if any is found.
19    Searches the current path after adding likely places where GSAS-II
20    might install svn.
21
22    :returns: None if svn is not found or an absolute path to the subversion
23      executable file.
24    '''
25    # use a previosuly cached svn location
26    global svnLocCache
27    if svnLocCache: return svnLocCache
28    # prepare to find svn
29    is_exe = lambda fpath: os.path.isfile(fpath) and os.access(fpath, os.X_OK)
30    svnprog = 'svn'
31    if sys.platform.startswith('win'): svnprog += '.exe'
32    gsaspath = os.path.split(__file__)[0]
33    # check for a proxy
34    proxyinfo = os.path.join(gsaspath,"proxyinfo.txt")
35    if os.path.exists(proxyinfo):
36        global proxycmds
37        proxycmds = []
38        fp = open(proxyinfo,'r')
39        host = fp.readline().strip()
40        port = fp.readline().strip()
41        fp.close()
42        proxycmds.append('--config-option')
43        proxycmds.append('servers:global:http-proxy-host='+host)
44        proxycmds.append('--config-option')
45        proxycmds.append('servers:global:http-proxy-port='+port)
46    # add likely places to find subversion when installed with GSAS-II
47    pathlist = os.environ["PATH"].split(os.pathsep)
48    pathlist.append(os.path.split(sys.executable)[0])
49    pathlist.append(gsaspath)
50    for rpt in ('..','bin'),('..','Library','bin'),('svn','bin'),('svn',),('.'):
51        pt = os.path.normpath(os.path.join(gsaspath,*rpt))
52        if os.path.exists(pt):
53            pathlist.insert(0,pt)   
54    # search path for svn or svn.exe
55    for path in pathlist:
56        exe_file = os.path.join(path, svnprog)
57        if is_exe(exe_file):
58            try:
59                p = subprocess.Popen([exe_file,'help'],stdout=subprocess.PIPE)
60                res = p.stdout.read()
61                p.communicate()
62                svnLocCache = os.path.abspath(exe_file)
63                return svnLocCache
64            except:
65                pass       
66    svnLocCache = None
67
68def svnVersion(svn=None):
69    '''Get the version number of the current subversion executable
70
71    :returns: a string with a version number such as "1.6.6" or None if
72      subversion is not found.
73
74    '''
75    if not svn: svn = whichsvn()
76    if not svn: return
77
78    cmd = [svn,'--version','--quiet']
79    s = subprocess.Popen(cmd,
80                         stdout=subprocess.PIPE,stderr=subprocess.PIPE)
81    out,err = s.communicate()
82    if err:
83        print 'subversion error!\nout=',out
84        print 'err=',err
85        return None
86    return out.strip()
87
88def svnVersionNumber(svn=None):
89    '''Get the version number of the current subversion executable
90
91    :returns: a fractional version number such as 1.6 or None if
92      subversion is not found.
93
94    '''
95    ver = svnVersion(svn)
96    if not ver: return 
97    M,m = ver.split('.')[:2]
98    return int(M)+int(m)/10.
99
100################################################################################
101################################################################################
102print 70*'*'
103#testing for incorrect locale code'
104try:
105    import locale
106    locale.getdefaultlocale()
107except ValueError:
108    print 'Your location is not set properly. This causes problems for matplotlib'
109    print '  (see https://github.com/matplotlib/matplotlib/issues/5420.)'
110    print 'Will try to bypass problem by setting LC_ALL to en_US.UTF-8 (US English)'
111    os.environ['LC_ALL'] = 'en_US.UTF-8'
112    locale.getdefaultlocale()
113print 'Preloading matplotlib to build fonts...'
114try:
115    import matplotlib
116except:
117    pass
118print 'Checking python packages...',
119missing = []
120for pkg in ['numpy','scipy','matplotlib','wx',]:
121    try:
122        exec('import '+pkg)
123    except:
124        missing.append(pkg)
125
126if missing:
127    print """Sorry, this version of Python cannot be used
128for GSAS-II. It is missing the following package(s):
129\t""",
130    for pkg in missing: print " ",pkg,
131    print "\nPlease install these package(s) and try running this again."
132    print "Showing first error: "
133    for pkg in ['numpy','scipy','matplotlib','wx',]:
134        exec('import '+pkg)
135    sys.exit()
136try:
137    import OpenGL
138    install_with_easyinstall = None 
139except:
140    try:                 
141            from setuptools.command import easy_install                 
142    except ImportError:
143        print 'You are missing the OpenGL Python package. This can be '
144        print 'installed by this script if the setuptools package is installed'
145        print 'Please install either OpenGL (pyopengl) or setuptools'
146        print "package and try running this again."
147        sys.exit()
148    print "Missing the OpenGL Python package. Will attempt to install this later."
149    def install_with_easyinstall(package):               
150        try:             
151            print "trying system-wide ",                 
152            easy_install.main(['-f',os.path.split(__file__)[0],package])                 
153            return               
154        except:                 
155            pass                 
156        try:             
157            print "trying user level ",                 
158            easy_install.main(['-f',os.path.split(__file__)[0],'--user',package])               
159            return               
160        except:                 
161            print "\nInstall of "+package+" failed. Error traceback follows:"           
162            import traceback             
163            print traceback.format_exc()                 
164            sys.exit() 
165
166print '\nChecking for subversion...',
167svn = whichsvn()
168if not svn:
169    print "Sorry, subversion (svn) could not be found on your system."
170    print "Please install this or place in path and rerun this."
171    #raise Exception('Subversion (svn) not found')
172    sys.exit()
173print ' found svn image: '+svn
174
175if install_with_easyinstall:             
176    print '\nInstalling PyOpenGL. Lots of warnings will follow... ',             
177    install_with_easyinstall('PyOpenGl')                 
178    print 'done.'
179   
180print 'Ready to bootstrap GSAS-II from repository\n\t',g2home,'\nto '+path2GSAS2
181proxycmds = []
182proxyinfo = os.path.join(path2GSAS2,"proxyinfo.txt")
183host = None
184port = '8080'
185if os.path.exists(proxyinfo):
186    fp = open(proxyinfo,'r')
187    host = fp.readline().strip()
188    port = fp.readline().strip()
189    fp.close()
190    os.remove(proxyinfo)
191print(70*"=")
192if host:
193    ans = raw_input("Enter the proxy address (type none to remove) ["+host+"]: ")
194    if ans.strip().lower() == "none": host = ans = ""
195else:
196    ans = raw_input("Enter the proxy address [none needed]: ")
197if ans.strip() != "" or host:
198    proxycmds.append('--config-option')
199    if ans.strip() == "": ans=host
200    proxycmds.append('servers:global:http-proxy-host='+ans.strip())
201    fp = open(proxyinfo,'w')
202    fp.write(ans.strip()+'\n')
203    ans = raw_input("Enter the proxy port ["+port+"]: ")
204    if ans.strip() == "": ans=port
205    proxycmds.append('--config-option')
206    proxycmds.append('servers:global:http-proxy-port='+ans.strip())
207    fp.write(ans.strip()+'\n')
208    fp.close()
209
210# patch: switch GSAS-II location if linked to XOR server (removed May/June 2017)
211cmd = [svn, 'info']
212p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
213res,err = p.communicate()
214if '.xor.' in res:
215    print('Switching previous install with .xor. download location to\n\thttps://subversion.xray.aps.anl.gov/pyGSAS')
216    cmd = [svn, 'switch','--relocate','https://subversion.xor.aps.anl.gov/pyGSAS',
217           'https://subversion.xray.aps.anl.gov/pyGSAS']
218    if proxycmds: cmd += proxycmds
219    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
220    res,err = p.communicate()
221    if err:
222        print('Please report this error to toby@anl.gov:')
223        print(err)
224        print(res)
225# patch: switch GSAS-II location if switched to 2frame version (removed August 2017)
226if '2frame' in res:
227    print('Switching previous 2frame install to trunk\n\thttps://subversion.xray.aps.anl.gov/pyGSAS')
228    cmd = [svn, 'switch',g2home + '/trunk',path2GSAS2,
229           '--non-interactive','--trust-server-cert',
230           '--accept','theirs-conflict','--force','--ignore-ancestry']
231    if proxycmds: cmd += proxycmds
232    p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
233    res,err = p.communicate()
234    if err:
235        print('Please report this error to toby@anl.gov:')
236        print(err)
237        print(res)
238
239cmd = [svn, 'co', g2home+ 'trunk/', path2GSAS2, '--non-interactive', '--trust-server-cert']
240if proxycmds: cmd += proxycmds
241msg = 'Now preparing to install GSAS-II'
242print('\n'+75*'*')
243print(msg + u' from ' + cmd[2])
244print 'svn load command:'
245for item in cmd: print item,
246print ""
247s = subprocess.Popen(cmd,stderr=subprocess.PIPE)
248print('\nsubversion output:')
249out,err = s.communicate()
250if err:
251    print('subversion returned an error:')
252    print(err)
253    print('Retrying with a cleanup and a command for older svn version...')
254    cmd = [svn, 'cleanup', path2GSAS2]
255    s = subprocess.Popen(cmd,stderr=subprocess.PIPE)
256    out,err = s.communicate()   
257    cmd = [svn, 'co', g2home+ 'trunk/', path2GSAS2]
258    if proxycmds: cmd += proxycmds
259    for item in cmd: print item,
260    print ""
261    s = subprocess.Popen(cmd,stderr=subprocess.PIPE)
262    out,err = s.communicate()
263    if err:
264        print('subversion returned an error:')
265        print(err)
266        print('  *** GSAS-II failed to be installed. In case the cleanup worked, try running this again')
267        print('  *** If this installation continues to fail, a likely reason is a network access')
268        print('  *** problem, most commonly because you need to use a network proxy. Please')
269        print('  *** check with a network administrator or use http://www.whatismyproxy.com/\n')
270        sys.exit()
271print('\n'+75*'*')
272
273try:
274    import GSASIIpath
275    print('import of GSASIIpath completed')
276except Exception as err:
277    print('\n'+75*'=')
278    print('Failed with import of GSASIIpath. This is unexpected.')
279    print('GSAS-II will not run without correcting this. Contact toby@anl.gov')
280    print(err)
281    print(75*'=')
282    sys.exit()
283
284for a in sys.argv[1:]:
285    if 'allbin' in a.lower() or 'server' in a.lower():
286        print('Loading all binaries with command...')
287        if not GSASIIpath.svnSwitchDir('AllBinaries','',g2home+ 'Binaries/',None,True):
288            print('Binary load failed')
289            sys.exit()
290        break
291else:
292    GSASIIpath.DownloadG2Binaries(g2home)
293       
294#===========================================================================
295# test if the compiled files load correctly
296#===========================================================================
297
298script = """  # commands that test each module can at least be loaded & run something in pyspg
299try:
300    import GSASIIpath
301    GSASIIpath.SetBinaryPath()
302    import pyspg
303    import histogram2d
304    import polymask
305    import pypowder
306    import pytexture
307    pyspg.sgforpy('P -1')
308    print('==OK==')
309except:
310    pass
311"""
312p = subprocess.Popen([sys.executable,'-c',script],stdout=subprocess.PIPE,stderr=subprocess.PIPE,
313                     cwd=path2GSAS2)
314res,err = p.communicate()
315if '==OK==' not in res or p.returncode != 0:
316    print('\n'+75*'=')
317    print('Failed when testing the GSAS-II compiled files. GSAS-II will not run')
318    print('without correcting this.')
319    #print(res)
320    #print(err)
321    #print('\nAttempting to open a web page on compiling GSAS-II...')
322    print('Please see web page\nhttps://subversion.xray.aps.anl.gov/trac/pyGSAS/wiki/CompileGSASII')
323    #import webbrowser
324    #webbrowser.open_new('https://subversion.xray.aps.anl.gov/trac/pyGSAS/wiki/CompileGSASII')
325    print(75*'=')
326    if '86' in platform.machine() and (sys.platform.startswith('linux')
327                                        or sys.platform == "darwin"
328                                        or sys.platform.startswith('win')):
329        print('Platform '+sys.platform+' with processor type '+platform.machine()+' is supported')
330    else:
331        print('Platform '+sys.platform+' with processor type '+platform.machine()+' not is supported')
332    sys.exit()
333else:
334    print 'Successfully tested compiled routines'
335#===========================================================================
336# import all .py files so that .pyc files get created
337print 'Byte-compiling all .py files...',
338import compileall
339compileall.compile_dir(path2GSAS2,quiet=True)
340print 'done'
341#===========================================================================
342# platform-dependent stuff
343#===========================================================================
344# on Windows, make a batch file with Python and GSAS-II location hard-coded
345if sys.platform.startswith('win') and os.path.exists(
346    os.path.join(path2GSAS2,"makeBat.py")):
347    execfile(os.path.join(path2GSAS2,"makeBat.py"))
348#===========================================================================
349# on a Mac, make an applescript
350elif sys.platform.startswith('darwin') and os.path.exists(
351    os.path.join(path2GSAS2,"makeMacApp.py")):
352    sys.argv = [os.path.join(path2GSAS2,"makeMacApp.py")]
353    print(u'running '+sys.argv[0])
354    execfile(sys.argv[0])
355#===========================================================================
356# On linux, make desktop icon
357elif sys.platform.startswith('linux'):
358    desktop_template = """
359[Desktop Entry]
360Version=1.0
361Type=Application
362Terminal=false
363Exec=xterm -hold -e bash -c "{} {}"
364Name=GSAS-II
365Icon={}
366Categories=Science;
367"""
368    loc = os.path.expanduser('~/Desktop/')
369    if "XDG_DATA_HOME" in os.environ and os.path.exists(os.path.join(os.environ.get("XDG_DATA_HOME"),"applications")):
370        loc = os.path.join(os.environ.get("XDG_DATA_HOME"),"applications")
371    elif "HOME" in os.environ and os.path.exists(os.path.join(os.environ.get("HOME"),".local/share/applications")):
372        loc = os.path.join(os.environ.get("HOME"),".local/share/applications")
373    elif not os.path.exists(loc):
374        loc = os.path.expanduser('~/')
375    dfile = os.path.join(loc,'GSASII.desktop')
376    icon = os.path.join(path2GSAS2, 'gsas2.png')
377    script = os.path.join(path2GSAS2, 'GSASII.py')
378    os.chmod(script, # make the .py file executable and readable
379             stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IXOTH)
380    try:
381        open(dfile,'w').write(desktop_template.format(sys.executable,script,icon))
382        os.chmod(
383            dfile,
384            stat.S_IWUSR | stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IXOTH)
385        print("created GNOME/KDE desktop shortcut "+dfile)
386    except:
387        print("creation of file failed: "+dfile)
388
Note: See TracBrowser for help on using the repository browser.