diff options
| author | Konrad Delong <konryd@gmail.com> | 2010-05-17 16:58:40 +0200 |
|---|---|---|
| committer | Konrad Delong <konryd@gmail.com> | 2010-05-17 16:58:40 +0200 |
| commit | 9fbe287c502d0e6acc376eaf7c21dfafd8129d6b (patch) | |
| tree | edd1e2b07756e4826ab176dab1f4b14f37820d44 | |
| parent | 6b9fd08e356f8c671fbdc59d9540326344791616 (diff) | |
| download | disutils2-9fbe287c502d0e6acc376eaf7c21dfafd8129d6b.tar.gz | |
other schemas support and informing about errors
| -rw-r--r-- | src/distutils2/command/upload_docs.py | 42 | ||||
| -rw-r--r-- | src/distutils2/tests/test_upload_docs.py | 84 |
2 files changed, 105 insertions, 21 deletions
diff --git a/src/distutils2/command/upload_docs.py b/src/distutils2/command/upload_docs.py index 8329968..a27f636 100644 --- a/src/distutils2/command/upload_docs.py +++ b/src/distutils2/command/upload_docs.py @@ -1,7 +1,8 @@ -import base64, httplib, os.path, tempfile, urlparse, zipfile +import base64, httplib, os.path, socket, tempfile, urlparse, zipfile from cStringIO import StringIO from distutils2 import log -from distutils2.core import Command +from distutils2.core import PyPIRCCommand +from distutils2.errors import DistutilsFileError def zip_dir(directory): """Compresses recursively contents of directory into a StringIO object""" @@ -46,7 +47,7 @@ def encode_multipart(fields, files, boundary=None): content_type = 'multipart/form-data; boundary=%s' % boundary return content_type, body -class upload_docs(Command): +class upload_docs(PyPIRCCommand): user_options = [ ('upload-dir=', None, 'directory to upload'), @@ -56,13 +57,28 @@ class upload_docs(Command): self.upload_dir = None def finalize_options(self): + PyPIRCCommand.finalize_options(self) if self.upload_dir == None: build = self.get_finalized_command('build') self.upload_dir = os.path.join(build.build_base, "docs") + config = self._read_pypirc() + if config != {}: + self.username = config['username'] + self.password = config['password'] + self.repository = config['repository'] + self.realm = config['realm'] + + def verify_upload_dir(self, upload_dir): + index_location = os.path.join(upload_dir, "index.html") + if not os.path.exists(index_location): + mesg = "No 'index.html found in docs directory (%s)" + raise DistutilsFileError(mesg % upload_dir) + def run(self): tmp_dir = tempfile.mkdtemp() name = self.distribution.metadata['Name'] + self.verify_upload_dir(self.upload_dir) zip_file = zip_dir(self.upload_dir) fields = {':action': 'doc_upload', 'name': name}.items() @@ -77,7 +93,12 @@ class upload_docs(Command): schema, netloc, url, params, query, fragments = \ urlparse.urlparse(self.repository) - conn = httplib.HTTPConnection(netloc) + if schema == "http": + conn = httplib.HTTPConnection(netloc) + elif schema == "https": + conn = httplib.HTTPSConnection(netloc) + else: + raise AssertionError("unsupported schema "+schema) try: conn.connect() @@ -92,3 +113,16 @@ class upload_docs(Command): return r = conn.getresponse() + + if r.status == 200: + self.announce('Server response (%s): %s' % (r.status, r.reason), + log.INFO) + elif r.status == 301: + location = r.getheader('Location') + if location is None: + location = 'http://packages.python.org/%s/' % meta.get_name() + self.announce('Upload successful. Visit %s' % location, + log.INFO) + else: + self.announce('Upload failed (%s): %s' % (r.status, r.reason), + log.ERROR) diff --git a/src/distutils2/tests/test_upload_docs.py b/src/distutils2/tests/test_upload_docs.py index 59eb603..0fc548c 100644 --- a/src/distutils2/tests/test_upload_docs.py +++ b/src/distutils2/tests/test_upload_docs.py @@ -1,15 +1,18 @@ """Tests for distutils.command.upload_docs.""" # -*- encoding: utf8 -*- -import os, os.path, tempfile, unittest2, zipfile +import httplib, os, os.path, tempfile, unittest2, zipfile from cStringIO import StringIO +from distutils2.command import upload_docs as upload_docs_mod from distutils2.command.upload_docs import (upload_docs, zip_dir, encode_multipart) from distutils2.core import Distribution +from distutils2.errors import DistutilsFileError + from distutils2.tests import support from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase -from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase +from distutils2.tests.test_config import PyPIRCCommandTestCase EXPECTED_MULTIPART_OUTPUT = "\r\n".join([ @@ -33,9 +36,17 @@ EXPECTED_MULTIPART_OUTPUT = "\r\n".join([ '', ]) -class UploadDocsTestCase(PyPIServerTestCase, - support.TempdirManager, - unittest2.TestCase): +PYPIRC = """\ +[distutils] +index-servers = server1 + +[server1] +repository = %s +username = real_slim_shady +password = long_island +""" + +class UploadDocsTestCase(PyPIServerTestCase, PyPIRCCommandTestCase): def setUp(self): super(UploadDocsTestCase, self).setUp() @@ -43,16 +54,16 @@ class UploadDocsTestCase(PyPIServerTestCase, self.dist.metadata['Name'] = "distr-name" self.cmd = upload_docs(self.dist) - def test_generates_uploaddir_name_not_given(self): + def test_generates_uploaddir_if_not_given(self): + self.assertEqual(self.cmd.upload_dir, None) self.cmd.ensure_finalized() self.assertEqual(self.cmd.upload_dir, os.path.join("build", "docs")) def prepare_sample_dir(self): sample_dir = tempfile.mkdtemp() os.mkdir(os.path.join(sample_dir, "some_dir")) - some_file = open(os.path.join(sample_dir, "some_dir", "some_file"), "w") - some_file.write("Ce mortel ennui") - some_file.close() + self.write_file(os.path.join(sample_dir, "some_dir", "index.html"), "Ce mortel ennui") + self.write_file(os.path.join(sample_dir, "index.html"), "Oh la la") return sample_dir def test_zip_dir(self): @@ -60,7 +71,7 @@ class UploadDocsTestCase(PyPIServerTestCase, compressed = zip_dir(source_dir) zip_f = zipfile.ZipFile(compressed) - self.assertEqual(zip_f.namelist(), ['some_dir/some_file']) + self.assertEqual(zip_f.namelist(), ['index.html', 'some_dir/index.html']) def test_encode_multipart(self): fields = [("a", "b"), ("c", "d")] @@ -69,12 +80,15 @@ class UploadDocsTestCase(PyPIServerTestCase, self.assertEqual(content_type, "multipart/form-data; boundary=-x") self.assertEqual(body, EXPECTED_MULTIPART_OUTPUT) - def test_upload(self): + def prepare_command(self): self.cmd.ensure_finalized() self.cmd.repository = self.pypi.full_address self.cmd.upload_dir = self.prepare_sample_dir() self.cmd.username = "username" self.cmd.password = "password" + + def test_upload(self): + self.prepare_command() self.cmd.run() self.assertEqual(len(self.pypi.requests), 1) @@ -95,20 +109,56 @@ class UploadDocsTestCase(PyPIServerTestCase, # check their contents self.assertIn("doc_upload", action) self.assertIn("distr-name", name) - self.assertIn("some_dir/some_file", content) + self.assertIn("some_dir/index.html", content) self.assertIn("Ce mortel ennui", content) def test_https_connection(self): - pass + https_called = False + orig_https = upload_docs_mod.httplib.HTTPSConnection + def https_conn_wrapper(*args): + https_called = True + return upload_docs_mod.httplib.HTTPConnection(*args) # the testing server is http + upload_docs_mod.httplib.HTTPSConnection = https_conn_wrapper + try: + self.prepare_command() + self.cmd.run() + self.assertFalse(https_called) + + self.cmd.repository = self.cmd.repository.replace("http", "https") + self.cmd.run() + self.assertFalse(https_called) + finally: + upload_docs_mod.httplib.HTTPSConnection = orig_https def test_handling_response(self): - pass + calls = [] + def aggr(*args): + calls.append(args) + self.pypi.default_response_status = '403 Forbidden' + self.prepare_command() + self.cmd.announce = aggr + self.cmd.run() + message, _ = calls[-1] + self.assertIn('Upload failed (403): Forbidden', message) - def test_honours_dry_run(self): - pass + calls = [] + self.pypi.default_response_status = '301 Moved Permanently' + self.pypi.default_response_headers.append(("Location", "brand_new_location")) + self.cmd.run() + message, _ = calls[-1] + self.assertIn('brand_new_location', message) def test_reads_pypirc_data(self): - pass + self.write_file(self.rc, PYPIRC % self.pypi.full_address) + self.cmd.repository = self.pypi.full_address + self.cmd.ensure_finalized() + self.assertEqual(self.cmd.username, "real_slim_shady") + self.assertEqual(self.cmd.password, "long_island") + + def test_checks_index_html_presence(self): + self.prepare_command() + os.remove(os.path.join(self.cmd.upload_dir, "index.html")) + self.assertRaises(DistutilsFileError, self.cmd.run) def test_suite(): return unittest2.makeSuite(UploadDocsTestCase) |
