Ticket #11602: trac_11602-install-scripts.v2.patch

File trac_11602-install-scripts.v2.patch, 8.2 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 f7b3c74e4b9304e8165d253e4f35d7d0580d8267
    # Parent  9dca3876f46be512d86d82dc0b43468f0ad2c8a4
    #11602: install_scripts should use "$@" instead of $*.
    Also generally clean up this function, including fixing a bug or two.
    
    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 run various software components included with
     11    Sage: 'gap', 'gp', 'singular', 'maxima', 'M2', 'kash', 'mwrank',
     12    '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 script even if another version of the program is in your
     28      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    .. note::
     41
     42       Running ``install_scripts(directory)`` will be most helpful if
     43       ``directory`` is in your path.
     44
    3845    AUTHORS:
    3946
    4047    - William Stein: code / design
    4148
    4249    - Arthur Gaer: design
    4350
     51    - John Palmieri: revision, 2011-07 (trac ticket #11602)
     52
    4453    EXAMPLES::
    4554
    46         sage: install_scripts(SAGE_TMP)
     55        sage: install_scripts(SAGE_TMP, ignore_existing=True)
    4756        Checking that Sage has the command 'gap' installed
    4857        Created script ...
    4958    """
    50     if bin_directory is None:
     59    if directory is None:
    5160        # We do this since the intended user of install_scripts
    5261        # will likely be pretty clueless about how to use Sage or
    5362        # its help system.
    def install_scripts(bin_directory=None): 
    5665        print "USAGE: install_scripts('bin directory name')"
    5766        return
    5867   
    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
     68    if not (os.path.exists(directory) and os.path.isdir(directory)):
     69        raise OSError, "'%s' must exist and be a directory"%directory
    6170
    62     for c in ['gap', 'gp', 'singular', 'maxima', 'M2', 'kash', \
     71    script_created = False
     72
     73    for cmd in ['gap', 'gp', 'singular', 'maxima', 'M2', 'kash', \
    6374              '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
     75        print "Checking that Sage has the command '%s' installed" % cmd
     76        from sage.misc.sage_ostools import have_program
     77        SAGE_ROOT = os.environ['SAGE_ROOT']
     78        SAGE_BIN = os.path.join(SAGE_ROOT, 'local', 'bin')
     79        # Check to see if Sage includes cmd.
     80        cmd_inside_sage = have_program(cmd, path=SAGE_BIN)
     81        # Remove SAGE_ROOT/local/bin from the path and check
     82        # whether cmd is still available:
     83        PATH = os.environ['PATH'].split(os.pathsep)
     84        PATH = os.pathsep.join([d for d in PATH if os.path.exists(d)
     85                         and not os.path.samefile(d, SAGE_BIN)])
     86        cmd_outside_sage = have_program(cmd, path=PATH)
     87        if not cmd_inside_sage:
     88            print "The command '%s' is not available as part " %cmd \
     89                  + "of Sage; not creating script."
     90            print
     91            continue
     92        if cmd_outside_sage:
     93            print "The command '%s' is installed outside of Sage;" % cmd,
     94            if not ignore_existing:
     95                print "not creating script."
     96                print
     97                continue
     98            print "trying to create script anyway..."
    7699        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)
     100            print "Creating script for '%s'..." % cmd
     101        # Install shortcut.
     102        target = os.path.join(directory, cmd)
     103        if os.path.exists(target):
     104            print "The file '%s' already exists; not adding script."%(target)
     105        else:
     106            o = open(target,'w')
     107            o.write('#!/bin/sh\n')
     108            o.write('sage -%s "$@"\n'%cmd)
     109            o.close()
     110            print "Created script '%s'"%target
     111            os.system('chmod a+rx %s'%target)
     112            script_created = True
    88113        print
    89            
    90     print "Finished creating scripts."
    91     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."
     114
     115    if script_created:
     116        print "Finished creating scripts."
     117        print
     118        print "You need not do this again even if you upgrade or move Sage."
     119        print "The only requirement is that your PATH contains both"
     120        print "'%s' and the directory containing the command 'sage'." % directory
     121    else:
     122        print "No scripts created."
  • 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