Ticket #11602: trac_11602-install-scripts.patch

File trac_11602-install-scripts.patch, 7.8 KB (added by John Palmieri, 11 years ago)
  • sage/misc/dist.py

    # HG changeset patch
    # User J. H. Palmieri <palmieri@math.washington.edu>
    # Date 1310765037 25200
    # Node ID 7ea847ab3a416b8b9c8d3b22be285c991d3b5e77
    # Parent  57e08f919b352054d47c864bdcdaab3bc33692f2
    [mq]: trac_11602
    
    diff --git a/sage/misc/dist.py b/sage/misc/dist.py
    a b Installing shortcut scripts 
    44
    55import os
    66
    7 from subprocess import Popen, PIPE
    8 
    9 def install_scripts(bin_directory=None):
     7def install_scripts(directory=None, ignore_existing=False):
    108    r"""
    11     Run this command as
    12     ``install_scripts(bin_directory)`` to create scripts
    13     in the given bin directory that, independently of Sage, run various
    14     software components included with Sage: ['gap', 'gp', 'singular',
    15     'maxima', 'M2', 'kash', 'mwrank', 'ipython', 'hg', 'R']
     9    Running ``install_scripts(directory)`` creates scripts in the
     10    given directory that, independently of Sage, run various software
     11    components included with Sage: 'gap', 'gp', 'singular', 'maxima',
     12    'M2', 'kash', 'mwrank', 'ipython', 'hg', 'R'.
    1613   
    1714    This command:
    1815   
    19     -  verbosely tell you which scripts it adds, and
     16    -  verbosely tells you which scripts it adds, and
    2017   
    2118    -  will *not* overwrite any scripts you already have in the given
    22        bin directory.
     19       directory.
    2320   
    2421    INPUT:
    25    
    26     -  ``bin_directory`` - string; the directory into
    27        which to put the scripts
    28    
     22
     23    - ``directory`` - string; the directory into which to put the
     24       scripts
     25
     26    - ``ignore_existing`` - bool (optional, default False): if True,
     27      install a shortcut to Sage's version of a program even if
     28      another version is in your path.
     29
    2930    OUTPUT: Verbosely prints what it is doing and creates files in
    30     bin_directory that are world executable and readable.
     31    ``directory`` that are world executable and readable.
    3132   
    3233    .. note::
    3334
    3435       You may need to run Sage as root in order to run
    3536       ``install_scripts`` successfully, since the user running Sage
    36        will need write permissions on ``bin_directory``.
    37    
     37       will need write permissions on ``directory``.  Note that
     38       one good candidate for ``directory`` is "/usr/local/bin".
     39
     40       Running ``install_scripts(directory)`` will be most helpful if
     41       ``directory`` is in your path.
     42
    3843    AUTHORS:
    3944
    4045    - William Stein: code / design
    def install_scripts(bin_directory=None): 
    4348
    4449    EXAMPLES::
    4550
    46         sage: install_scripts(SAGE_TMP)
     51        sage: install_scripts(SAGE_TMP, ignore_existing=True)
    4752        Checking that Sage has the command 'gap' installed
    4853        Created script ...
    4954    """
    50     if bin_directory is None:
     55    if directory is None:
    5156        # We do this since the intended user of install_scripts
    5257        # will likely be pretty clueless about how to use Sage or
    5358        # its help system.
    def install_scripts(bin_directory=None): 
    5661        print "USAGE: install_scripts('bin directory name')"
    5762        return
    5863   
    59     if not (os.path.exists(bin_directory) and os.path.isdir(bin_directory)):
    60         raise RuntimeError, "'%s' must exist and be a directory"%bin_directory
     64    if not (os.path.exists(directory) and os.path.isdir(directory)):
     65        raise RuntimeError, "'%s' must exist and be a directory"%directory
    6166
    62     for c in ['gap', 'gp', 'singular', 'maxima', 'M2', 'kash', \
     67    for cmd in ['gap', 'gp', 'singular', 'maxima', 'M2', 'kash', \
    6368              'mwrank', 'ipython', 'hg', 'R']:
    64         print "Checking that Sage has the command '%s' installed"%c
    65         p = Popen(['which', c], stdout=PIPE, stderr=PIPE)
    66         path = os.path.realpath(p.communicate()[0].rstrip("\n"))
    67         error = p.wait()
    68         if error:
    69             # the 'which' command came up empty:
    70             print "The command '%s' is not available; not adding shortcut"%c
    71         elif not path.startswith(os.path.realpath(os.environ['SAGE_ROOT'])):
    72             # 'which' returned a path outside of the Sage directory:
    73             # then the command is already installed, and we shouldn't
    74             # install the Sage version:
    75             print "The command '%s' is installed outside of Sage; not adding shortcut"%c
     69        print "Checking that Sage has the command '%s' installed" % cmd
     70        from sage.misc.sage_ostools import have_program
     71        SAGE_ROOT = os.environ['SAGE_ROOT']
     72        SAGE_BIN = os.path.join(SAGE_ROOT, 'local', 'bin')
     73        # Check to see if Sage includes cmd.
     74        cmd_inside_sage = have_program(cmd, path=SAGE_BIN)
     75        # Remove SAGE_ROOT/local/bin from the path and check
     76        # whether cmd is still available:
     77        PATH = os.environ['PATH'].split(os.pathsep)
     78        PATH = os.pathsep.join([d for d in PATH if os.path.exists(d)
     79                         and not os.path.samefile(d, SAGE_BIN)])
     80        cmd_outside_sage = have_program(cmd, path=PATH)
     81        if not cmd_inside_sage:
     82            print "The command '%s' is not available as part of Sage; not adding shortcut." % cmd
     83            print
     84            continue
     85        if cmd_outside_sage:
     86            print "The command '%s' is installed outside of Sage;" % cmd,
     87            if not ignore_existing:
     88                print "not adding shortcut."
     89                print
     90                continue
     91            else:
     92                print "trying to add shortcut anyway."
     93        # Install shortcut.
     94        target = os.path.join(directory, cmd)
     95        if os.path.exists(target):
     96            print "The file '%s' already exists; not adding shortcut."%(target)
    7697        else:
    77             # 'which' returned SAGE_ROOT/local/bin/...: create the
    78             # shortcut if it doesn't exist already:
    79             target = os.path.join(bin_directory, c)
    80             if os.path.exists(target):
    81                 print "The file '%s' already exists; not adding shortcut"%(target)
    82             else:
    83                 o = open(target,'w')
    84                 o.write('#!/bin/sh\n')
    85                 o.write('sage -%s $*\n'%c)
    86                 print "Created script '%s'"%target
    87                 os.system('chmod a+rx %s'%target)
     98            o = open(target,'w')
     99            o.write('#!/bin/sh\n')
     100            o.write('sage -%s "$@"\n'%cmd)
     101            o.close()
     102            print "Created script '%s'"%target
     103            os.system('chmod a+rx %s'%target)
    88104        print
    89105           
    90106    print "Finished creating scripts."
     107    print
    91108    print "You need not do this again even if you upgrade or move Sage."
    92     print "The only requirement is that the command 'sage' is in the PATH."
     109    print "The only requirement is that your PATH contains both"
     110    print "%s and the directory containing the command 'sage'." % directory
  • sage/misc/sage_ostools.py

    diff --git a/sage/misc/sage_ostools.py b/sage/misc/sage_ostools.py
    a b  
    22Miscellaneous operating system functions
    33"""
    44
    5 def have_program(program):
     5def have_program(program, path=None):
    66    """
    77    Return ``True`` if ``program`` is found in the path.
    88
    99    INPUT:
    1010
    11     - ``program`` - a string, the name of the program to check
     11    - ``program`` - a string, the name of the program to check.
     12    - ``path`` - string or None.  If a nonempty string, use this as
     13      the setting for the PATH environment variable.
    1214
    1315    OUTPUT: bool
    1416
    def have_program(program): 
    2931        False
    3032    """
    3133    from subprocess import call, PIPE
     34    import os
    3235    try:
    33         return not call('command -v ' + program, shell=True, stdout=PIPE, stderr=PIPE)
     36        if path:
     37            return not call('command -v %s' % program, shell=True,
     38                            stdout=PIPE, env = {'PATH': path})
     39        else:
     40            return not call('command -v %s' % program, shell=True,
     41                            stdout=PIPE)
    3442    except OSError:
    3543        return False
    36