Changeset 2312

Show
Ignore:
Timestamp:
10/03/06 17:51:35 (2 years ago)
Author:
paul
Message:

New ez_setup.py. Untested, but appears to be what we want.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ez_setup.py

    r1483 r2312  
    1414This file can also be run as a script to install or upgrade setuptools. 
    1515""" 
    16  
    17 DEFAULT_VERSION = "0.5a13" 
    18 DEFAULT_URL     = "http://www.python.org/packages/source/s/setuptools/" 
     16import sys 
     17DEFAULT_VERSION = "0.6c3" 
     18DEFAULT_URL     = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3] 
     19 
     20md5_data = { 
     21    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 
     22    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 
     23    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 
     24    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 
     25    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 
     26    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 
     27    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 
     28    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 
     29    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 
     30    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 
     31    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 
     32    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 
     33    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 
     34    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 
     35    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 
     36
    1937 
    2038import sys, os 
    2139 
    22  
    23  
    24  
    25  
    26  
    27  
    28  
    29  
    30  
    31  
    32  
    33  
    34  
    35  
    36  
    37  
    38  
    39  
     40def _validate_md5(egg_name, data): 
     41    if egg_name in md5_data: 
     42        from md5 import md5 
     43        digest = md5(data).hexdigest() 
     44        if digest != md5_data[egg_name]: 
     45            print >>sys.stderr, ( 
     46                "md5 validation of %s failed!  (Possible download problem?)" 
     47                % egg_name 
     48            ) 
     49            sys.exit(2) 
     50    return data 
    4051 
    4152 
    4253def use_setuptools( 
    43         version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir 
     54    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, 
     55    download_delay=15 
    4456): 
    45     """Automatically find/download setuptools and make it available on sys.path 
    46  
    47     `version` should be a valid setuptools version number that is available 
    48     as an egg for download under the `download_base` URL (which should end with 
    49     a '/').  `to_dir` is the directory where setuptools will be downloaded, if 
    50     it is not already available. 
    51  
    52     If an older version of setuptools is installed, this will print a message 
    53     to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling 
    54     script. 
    55     """ 
    56     try: 
    57         import setuptools 
    58         if setuptools.__version__ == '0.0.1': 
    59             print >>sys.stderr, ( 
    60                     "You have an obsolete version of setuptools installed.  Please\n" 
    61                     "remove it from your system entirely before rerunning this script." 
    62             ) 
    63             sys.exit(2) 
    64  
    65     except ImportError: 
    66         egg = download_setuptools(version, download_base, to_dir) 
    67         sys.path.insert(0, egg) 
    68         import setuptools; setuptools.bootstrap_install_from = egg 
    69  
    70     import pkg_resources 
    71     try: 
    72         pkg_resources.require("setuptools>="+version) 
    73  
    74     except pkg_resources.VersionConflict: 
    75         # XXX could we install in a subprocess here? 
    76         print >>sys.stderr, ( 
    77                 "The required version of setuptools (>=%s) is not available, and\n" 
    78                 "can't be installed while this script is running. Please install\n" 
    79                 " a more recent version first." 
    80         ) % version 
    81         sys.exit(2) 
     57    """Automatically find/download setuptools and make it available on sys.path 
     58 
     59    `version` should be a valid setuptools version number that is available 
     60    as an egg for download under the `download_base` URL (which should end with 
     61    a '/').  `to_dir` is the directory where setuptools will be downloaded, if 
     62    it is not already available.  If `download_delay` is specified, it should 
     63    be the number of seconds that will be paused before initiating a download, 
     64    should one be required.  If an older version of setuptools is installed, 
     65    this routine will print a message to ``sys.stderr`` and raise SystemExit in 
     66    an attempt to abort the calling script. 
     67    """ 
     68    try: 
     69        import setuptools 
     70        if setuptools.__version__ == '0.0.1': 
     71            print >>sys.stderr, ( 
     72            "You have an obsolete version of setuptools installed.  Please\n" 
     73            "remove it from your system entirely before rerunning this script." 
     74            ) 
     75            sys.exit(2) 
     76    except ImportError: 
     77        egg = download_setuptools(version, download_base, to_dir, download_delay) 
     78        sys.path.insert(0, egg) 
     79        import setuptools; setuptools.bootstrap_install_from = egg 
     80 
     81    import pkg_resources 
     82    try: 
     83        pkg_resources.require("setuptools>="+version) 
     84 
     85    except pkg_resources.VersionConflict, e: 
     86        # XXX could we install in a subprocess here? 
     87        print >>sys.stderr, ( 
     88            "The required version of setuptools (>=%s) is not available, and\n" 
     89            "can't be installed while this script is running. Please install\n" 
     90            " a more recent version first.\n\n(Currently using %r)" 
     91        ) % (version, e.args[0]) 
     92        sys.exit(2) 
    8293 
    8394def download_setuptools( 
    84     version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir 
     95    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, 
     96    delay = 15 
    8597): 
    86     """Download setuptools from a specified location and return its filename 
    87  
    88     `version` should be a valid setuptools version number that is available 
    89     as an egg for download under the `download_base` URL (which should end 
    90     with a '/'). `to_dir` is the directory where the egg will be downloaded. 
    91     """ 
    92     import urllib2, shutil 
    93     egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) 
    94     url = download_base + egg_name + '.zip'  # XXX 
    95     saveto = os.path.join(to_dir, egg_name) 
    96     src = dst = None 
    97  
    98     if not os.path.exists(saveto):  # Avoid repeated downloads 
    99         try: 
    100             from distutils import log 
    101             log.warn("Downloading %s", url) 
    102             src = urllib2.urlopen(url) 
    103             # Read/write all in one block, so we don't create a corrupt file 
    104             # if the download is interrupted. 
    105             data = src.read() 
    106             dst = open(saveto,"wb") 
    107             dst.write(data) 
    108         finally: 
    109             if src: src.close() 
    110             if dst: dst.close() 
    111  
    112     return os.path.realpath(saveto) 
    113  
    114  
    115  
    116  
    117  
    118  
    119  
    120  
    121  
    122  
     98    """Download setuptools from a specified location and return its filename 
     99 
     100    `version` should be a valid setuptools version number that is available 
     101    as an egg for download under the `download_base` URL (which should end 
     102    with a '/'). `to_dir` is the directory where the egg will be downloaded. 
     103    `delay` is the number of seconds to pause before an actual download attempt. 
     104    """ 
     105    import urllib2, shutil 
     106    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) 
     107    url = download_base + egg_name 
     108    saveto = os.path.join(to_dir, egg_name) 
     109    src = dst = None 
     110    if not os.path.exists(saveto):  # Avoid repeated downloads 
     111        try: 
     112            from distutils import log 
     113            if delay: 
     114                log.warn(""" 
     115--------------------------------------------------------------------------- 
     116This script requires setuptools version %s to run (even to display 
     117help).  I will attempt to download it for you (from 
     118%s), but 
     119you may need to enable firewall access for this script first. 
     120I will start the download in %d seconds. 
     121 
     122(Note: if this machine does not have network access, please obtain the file 
     123 
     124   %s 
     125 
     126and place it in this directory before rerunning this script.) 
     127---------------------------------------------------------------------------""", 
     128                    version, download_base, delay, url 
     129                ); from time import sleep; sleep(delay) 
     130            log.warn("Downloading %s", url) 
     131            src = urllib2.urlopen(url) 
     132            # Read/write all in one block, so we don't create a corrupt file 
     133            # if the download is interrupted. 
     134            data = _validate_md5(egg_name, src.read()) 
     135            dst = open(saveto,"wb"); dst.write(data) 
     136        finally: 
     137            if src: src.close() 
     138            if dst: dst.close() 
     139    return os.path.realpath(saveto) 
    123140 
    124141def main(argv, version=DEFAULT_VERSION): 
    125     """Install or upgrade setuptools and EasyInstall""" 
    126  
    127     try: 
    128         import setuptools 
    129     except ImportError: 
    130         import tempfile, shutil 
    131         tmpdir = tempfile.mkdtemp(prefix="easy_install-") 
    132         try: 
    133             egg = download_setuptools(version, to_dir=tmpdir) 
    134             sys.path.insert(0,egg) 
    135             from setuptools.command.easy_install import main 
    136             main(list(argv)+[egg]) 
    137         finally: 
    138             shutil.rmtree(tmpdir) 
    139     else: 
    140         if setuptools.__version__ == '0.0.1': 
    141             # tell the user to uninstall obsolete version 
    142             use_setuptools(version) 
    143  
    144     req = "setuptools>="+version 
    145     import pkg_resources 
    146     try: 
    147         pkg_resources.require(req) 
    148     except pkg_resources.VersionConflict: 
    149         try: 
    150             from setuptools.command.easy_install import main 
    151         except ImportError: 
    152             from easy_install import main 
    153         main(list(argv)+[download_setuptools()]) 
    154         sys.exit(0) # try to force an exit 
    155     else: 
    156         if argv: 
    157             from setuptools.command.easy_install import main 
    158             main(argv) 
    159         else: 
    160             print "Setuptools version",version,"or greater has been installed." 
    161             print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' 
     142    """Install or upgrade setuptools and EasyInstall""" 
     143 
     144    try: 
     145        import setuptools 
     146    except ImportError: 
     147        egg = None 
     148        try: 
     149            egg = download_setuptools(version, delay=0) 
     150            sys.path.insert(0,egg) 
     151            from setuptools.command.easy_install import main 
     152            return main(list(argv)+[egg])   # we're done here 
     153        finally: 
     154            if egg and os.path.exists(egg): 
     155                os.unlink(egg) 
     156    else: 
     157        if setuptools.__version__ == '0.0.1': 
     158            # tell the user to uninstall obsolete version 
     159            use_setuptools(version) 
     160 
     161    req = "setuptools>="+version 
     162    import pkg_resources 
     163    try: 
     164        pkg_resources.require(req) 
     165    except pkg_resources.VersionConflict: 
     166        try: 
     167            from setuptools.command.easy_install import main 
     168        except ImportError: 
     169            from easy_install import main 
     170        main(list(argv)+[download_setuptools(delay=0)]) 
     171        sys.exit(0) # try to force an exit 
     172    else: 
     173        if argv: 
     174            from setuptools.command.easy_install import main 
     175            main(argv) 
     176        else: 
     177            print "Setuptools version",version,"or greater has been installed." 
     178            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' 
     179 
     180 
     181 
     182def update_md5(filenames): 
     183    """Update our built-in md5 registry""" 
     184 
     185    import re 
     186    from md5 import md5 
     187 
     188    for name in filenames: 
     189        base = os.path.basename(name) 
     190        f = open(name,'rb') 
     191        md5_data[base] = md5(f.read()).hexdigest() 
     192        f.close() 
     193 
     194    data = ["    %r: %r,\n" % it for it in md5_data.items()] 
     195    data.sort() 
     196    repl = "".join(data) 
     197 
     198    import inspect 
     199    srcfile = inspect.getsourcefile(sys.modules[__name__]) 
     200    f = open(srcfile, 'rb'); src = f.read(); f.close() 
     201 
     202    match = re.search("\nmd5_data = {\n([^}]+)}", src) 
     203    if not match: 
     204        print >>sys.stderr, "Internal error!" 
     205        sys.exit(2) 
     206 
     207    src = src[:match.start(1)] + repl + src[match.end(1):] 
     208    f = open(srcfile,'w') 
     209    f.write(src) 
     210    f.close() 
     211 
    162212 
    163213if __name__=='__main__': 
    164     main(sys.argv[1:]) 
    165  
     214    if len(sys.argv)>2 and sys.argv[1]=='--md5update': 
     215        update_md5(sys.argv[2:]) 
     216    else: 
     217        main(sys.argv[1:]) 
     218 
     219 
     220 
     221 
     222