Commit c1112aa5 authored by PJ Eby's avatar PJ Eby

Add upload support to setuptools, and make default downloads of setuptools

come from PyPI/python.org rather than from telecommunity.com.  Bump to
version 0.5a7.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041090
parent 61d2fd1d
......@@ -23,13 +23,10 @@ Installing "Easy Install"
-------------------------
Windows users can just download and run the `setuptools binary installer for
Windows <http://peak.telecommunity.com/dist/setuptools-0.5a6.win32.exe>`_.
Windows <http://peak.telecommunity.com/dist/setuptools-0.5a7.win32.exe>`_.
All others should just download `ez_setup.py
<http://peak.telecommunity.com/dist/ez_setup.py>`_, and run it; this will
download and install the `Python 2.3 egg`_ or `Python 2.4 egg`_ for you.
.. _Python 2.3 egg: http://peak.telecommunity.com/dist/setuptools-0.5a6-py2.3.egg
.. _Python 2.4 egg: http://peak.telecommunity.com/dist/setuptools-0.5a6-py2.4.egg
download and install the appropriate egg for you.
You may receive a message telling you about an obsolete version of
setuptools being present; if so, you must be sure to delete it entirely, along
......@@ -66,7 +63,7 @@ version, and automatically downloading, building, and installing it::
**Example 2**. Install or upgrade a package by name and version by finding
links on a given "download page"::
easy_install -f http://peak.telecommunity.com/dist "setuptools>=0.5a6"
easy_install -f http://peak.telecommunity.com/dist "setuptools>=0.5a7"
**Example 3**. Download a source distribution from a specified URL,
automatically building and installing it::
......@@ -491,6 +488,11 @@ Known Issues
in Exemaker. So, don't use Exemaker to wrap ``easy_install.py``, or at any
rate don't expect it to work with all packages.
0.5a7
* Added "upload" support for egg and source distributions, including a bug
fix for "upload" and a temporary workaround for lack of .egg support in
PyPI.
0.5a6
* Beefed up the "sdist" command so that if you don't have a MANIFEST.in, it
will include all files under revision control (CVS or Subversion) in the
......
......@@ -14,8 +14,8 @@ the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
DEFAULT_VERSION = "0.5a6"
DEFAULT_URL = "http://peak.telecommunity.com/dist/"
DEFAULT_VERSION = "0.5a7"
DEFAULT_URL = "http://www.python.org/packages/source/s/setuptools/"
import sys, os
......@@ -91,7 +91,7 @@ def download_setuptools(
"""
import urllib2, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
url = download_base + egg_name + '.zip' # XXX
saveto = os.path.join(to_dir, egg_name)
src = dst = None
......
#!/usr/bin/env python
"""Distutils setup file, used to install or test 'setuptools'"""
VERSION = "0.5a6"
VERSION = "0.5a7"
from setuptools import setup, find_packages, Require
setup(
......@@ -26,8 +26,7 @@ setup(
"close. See the home page and download page for details and docs.",
keywords = "CPAN PyPI distutils eggs package management",
url = "http://peak.telecommunity.com/DevCenter/PythonEggs",
download_url = "http://peak.telecommunity.com/DevCenter/EasyInstall",
url = "http://peak.telecommunity.com/DevCenter/EasyInstall",
test_suite = 'setuptools.tests.test_suite',
requires = [
......@@ -39,6 +38,7 @@ setup(
packages = find_packages(),
py_modules = ['pkg_resources'],
scripts = ['easy_install.py'],
......
......@@ -8,7 +8,7 @@ from distutils.core import Command as _Command
from distutils.util import convert_path
import os.path
__version__ = '0.5a6'
__version__ = '0.5a7'
__all__ = [
'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
......
......@@ -63,8 +63,34 @@ def walk_revctrl(dirname='', memo=None):
for item in walk_revctrl(path, memo):
yield item
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
def run(self):
_sdist.run(self)
dist_files = getattr(self.distribution,'dist_files',[])
for file in self.archive_files:
data = ('sdist', '', file)
if data not in dist_files:
dist_files.append(data)
def finalize_options(self):
_sdist.finalize_options(self)
if not os.path.isfile(self.template):
......@@ -78,5 +104,20 @@ class sdist(_sdist):
"""distutils.command.upload
Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
from distutils.errors import *
from distutils.core import Command
from distutils.spawn import spawn
from distutils import log
from md5 import md5
import os
import socket
import platform
import ConfigParser
import httplib
import base64
import urlparse
import cStringIO as StringIO
class upload(Command):
description = "upload binary package to PyPI"
DEFAULT_REPOSITORY = 'http://www.python.org/pypi'
user_options = [
('repository=', 'r',
"url of repository [default: %s]" % DEFAULT_REPOSITORY),
('show-response', None,
'display full response text from server'),
('sign', 's',
'sign files to upload using gpg'),
]
boolean_options = ['show-response', 'sign']
def initialize_options(self):
self.username = ''
self.password = ''
self.repository = ''
self.show_response = 0
self.sign = False
def finalize_options(self):
if os.environ.has_key('HOME'):
rc = os.path.join(os.environ['HOME'], '.pypirc')
if os.path.exists(rc):
self.announce('Using PyPI login from %s' % rc)
config = ConfigParser.ConfigParser({
'username':'',
'password':'',
'repository':''})
config.read(rc)
if not self.repository:
self.repository = config.get('server-login', 'repository')
if not self.username:
self.username = config.get('server-login', 'username')
if not self.password:
self.password = config.get('server-login', 'password')
if not self.repository:
self.repository = self.DEFAULT_REPOSITORY
def run(self):
if not self.distribution.dist_files:
raise DistutilsOptionError("No dist file created in earlier command")
for command, pyversion, filename in self.distribution.dist_files:
self.upload_file(command, pyversion, filename)
def upload_file(self, command, pyversion, filename):
# Sign if requested
if self.sign:
spawn(("gpg", "--detach-sign", "-a", filename),
dry_run=self.dry_run)
# Fill in the data
content = open(filename,'rb').read()
basename = os.path.basename(filename)
if basename.endswith('.egg'):
basename += '.zip'
if command=='bdist_egg':
command='sdist'
data = {
':action':'file_upload',
'protcol_version':'1',
'name':self.distribution.get_name(),
'version':self.distribution.get_version(),
'content':(basename,content),
'filetype':command,
'pyversion':pyversion,
'md5_digest':md5(content).hexdigest(),
}
comment = ''
if command == 'bdist_rpm':
dist, version, id = platform.dist()
if dist:
comment = 'built for %s %s' % (dist, version)
elif command == 'bdist_dumb':
comment = 'built for %s' % platform.platform(terse=1)
data['comment'] = comment
if self.sign:
data['gpg_signature'] = (os.path.basename(filename) + ".asc",
open(filename+".asc").read())
# set up the authentication
auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip()
# Build up the MIME payload for the POST data
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
sep_boundary = '\n--' + boundary
end_boundary = sep_boundary + '--'
body = StringIO.StringIO()
for key, value in data.items():
# handle multiple entries for the same name
if type(value) != type([]):
value = [value]
for value in value:
if type(value) is tuple:
fn = ';filename="%s"' % value[0]
value = value[1]
else:
fn = ""
value = str(value)
body.write(sep_boundary)
body.write('\nContent-Disposition: form-data; name="%s"'%key)
body.write(fn)
body.write("\n\n")
body.write(value)
if value and value[-1] == '\r':
body.write('\n') # write an extra newline (lurve Macs)
body.write(end_boundary)
body.write("\n")
body = body.getvalue()
self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
# build the Request
# We can't use urllib2 since we need to send the Basic
# auth right with the first request
schema, netloc, url, params, query, fragments = \
urlparse.urlparse(self.repository)
assert not params and not query and not fragments
if schema == 'http':
http = httplib.HTTPConnection(netloc)
elif schema == 'https':
http = httplib.HTTPSConnection(netloc)
else:
raise AssertionError, "unsupported schema "+schema
data = ''
loglevel = log.INFO
try:
http.connect()
http.putrequest("POST", url)
http.putheader('Content-type',
'multipart/form-data; boundary=%s'%boundary)
http.putheader('Content-length', str(len(body)))
http.putheader('Authorization', auth)
http.endheaders()
http.send(body)
except socket.error, e:
self.announce(e.msg, log.ERROR)
return
r = http.getresponse()
if r.status == 200:
self.announce('Server response (%s): %s' % (r.status, r.reason),
log.INFO)
else:
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
print '-'*75, r.read(), '-'*75
......@@ -44,6 +44,8 @@ def distros_for_url(url, metadata=None):
path = urlparse.urlparse(url)[2]
base = urllib2.unquote(path.split('/')[-1])
if base.endswith('.egg.zip'):
base = base[:-4] # strip the .zip
if base.endswith('.egg'):
dist = Distribution.from_filename(base, metadata)
......@@ -78,8 +80,6 @@ def distros_for_url(url, metadata=None):
def interpret_distro_name(url, base, metadata,
py_version=None, distro_type=SOURCE_DIST, platform=None
):
......@@ -388,6 +388,9 @@ class PackageIndex(AvailableDistributions):
else:
name = "__downloaded__" # default if URL has no path contents
if name.endswith('.egg.zip'):
name = name[:-4] # strip the extra .zip before download
filename = os.path.join(tmpdir,name)
# Download the file
......@@ -405,9 +408,6 @@ class PackageIndex(AvailableDistributions):
self.process_url(url, True)
def _download_html(self, url, headers, filename, tmpdir):
# Check for a sourceforge URL
sf_url = url.startswith('http://prdownloads.')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment