Commit 86a2297c authored by Tarek Ziadé's avatar Tarek Ziadé

Merged revisions 72681 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r72681 | tarek.ziade | 2009-05-16 18:37:06 +0200 (Sat, 16 May 2009) | 1 line

  #6041: sdist and register now use the check command. No more duplicate code for metadata checking
........
parent fb1d44bd
...@@ -10,6 +10,7 @@ __revision__ = "$Id$" ...@@ -10,6 +10,7 @@ __revision__ = "$Id$"
import os, string, getpass import os, string, getpass
import io import io
import urllib.parse, urllib.request import urllib.parse, urllib.request
from warnings import warn
from distutils.core import PyPIRCCommand from distutils.core import PyPIRCCommand
from distutils.errors import * from distutils.errors import *
...@@ -21,18 +22,34 @@ class register(PyPIRCCommand): ...@@ -21,18 +22,34 @@ class register(PyPIRCCommand):
user_options = PyPIRCCommand.user_options + [ user_options = PyPIRCCommand.user_options + [
('list-classifiers', None, ('list-classifiers', None,
'list the valid Trove classifiers'), 'list the valid Trove classifiers'),
('strict', None ,
'Will stop the registering if the meta-data are not fully compliant')
] ]
boolean_options = PyPIRCCommand.boolean_options + [ boolean_options = PyPIRCCommand.boolean_options + [
'verify', 'list-classifiers'] 'verify', 'list-classifiers', 'strict']
sub_commands = [('check', lambda self: True)]
def initialize_options(self): def initialize_options(self):
PyPIRCCommand.initialize_options(self) PyPIRCCommand.initialize_options(self)
self.list_classifiers = 0 self.list_classifiers = 0
self.strict = 0
def finalize_options(self):
PyPIRCCommand.finalize_options(self)
# setting options for the `check` subcommand
check_options = {'strict': ('register', self.strict),
'restructuredtext': ('register', 1)}
self.distribution.command_options['check'] = check_options
def run(self): def run(self):
self.finalize_options() self.finalize_options()
self._set_config() self._set_config()
self.check_metadata()
# Run sub commands
for cmd_name in self.get_sub_commands():
self.run_command(cmd_name)
if self.dry_run: if self.dry_run:
self.verify_metadata() self.verify_metadata()
elif self.list_classifiers: elif self.list_classifiers:
...@@ -41,34 +58,14 @@ class register(PyPIRCCommand): ...@@ -41,34 +58,14 @@ class register(PyPIRCCommand):
self.send_metadata() self.send_metadata()
def check_metadata(self): def check_metadata(self):
"""Ensure that all required elements of meta-data (name, version, """Deprecated API."""
URL, (author and author_email) or (maintainer and warn("distutils.command.register.check_metadata is deprecated, \
maintainer_email)) are supplied by the Distribution object; warn if use the check command instead", PendingDeprecationWarning)
any are missing. check = self.distribution.get_command_obj('check')
""" check.ensure_finalized()
metadata = self.distribution.metadata check.strict = self.strict
check.restructuredtext = 1
missing = [] check.run()
for attr in ('name', 'version', 'url'):
if not (hasattr(metadata, attr) and getattr(metadata, attr)):
missing.append(attr)
if missing:
self.warn("missing required meta-data: " +
", ".join(missing))
if metadata.author:
if not metadata.author_email:
self.warn("missing meta-data: if 'author' supplied, " +
"'author_email' must be supplied too")
elif metadata.maintainer:
if not metadata.maintainer_email:
self.warn("missing meta-data: if 'maintainer' supplied, " +
"'maintainer_email' must be supplied too")
else:
self.warn("missing meta-data: either (author and author_email) " +
"or (maintainer and maintainer_email) " +
"must be supplied")
def _set_config(self): def _set_config(self):
''' Reads the configuration file and set attributes. ''' Reads the configuration file and set attributes.
......
...@@ -9,6 +9,8 @@ import string ...@@ -9,6 +9,8 @@ import string
import sys import sys
from types import * from types import *
from glob import glob from glob import glob
from warnings import warn
from distutils.core import Command from distutils.core import Command
from distutils import dir_util, dep_util, file_util, archive_util from distutils import dir_util, dep_util, file_util, archive_util
from distutils.text_file import TextFile from distutils.text_file import TextFile
...@@ -35,6 +37,12 @@ class sdist(Command): ...@@ -35,6 +37,12 @@ class sdist(Command):
description = "create a source distribution (tarball, zip file, etc.)" description = "create a source distribution (tarball, zip file, etc.)"
def checking_metadata(self):
"""Callable used for the check sub-command.
Placed here so user_options can view it"""
return self.metadata_check
user_options = [ user_options = [
('template=', 't', ('template=', 't',
"name of manifest template file [default: MANIFEST.in]"), "name of manifest template file [default: MANIFEST.in]"),
...@@ -64,11 +72,14 @@ class sdist(Command): ...@@ -64,11 +72,14 @@ class sdist(Command):
('dist-dir=', 'd', ('dist-dir=', 'd',
"directory to put the source distribution archive(s) in " "directory to put the source distribution archive(s) in "
"[default: dist]"), "[default: dist]"),
('medata-check', None,
"Ensure that all required elements of meta-data "
"are supplied. Warn if any missing. [default]"),
] ]
boolean_options = ['use-defaults', 'prune', boolean_options = ['use-defaults', 'prune',
'manifest-only', 'force-manifest', 'manifest-only', 'force-manifest',
'keep-temp'] 'keep-temp', 'metadata-check']
help_options = [ help_options = [
('help-formats', None, ('help-formats', None,
...@@ -81,6 +92,8 @@ class sdist(Command): ...@@ -81,6 +92,8 @@ class sdist(Command):
default_format = {'posix': 'gztar', default_format = {'posix': 'gztar',
'nt': 'zip' } 'nt': 'zip' }
sub_commands = [('check', checking_metadata)]
def initialize_options(self): def initialize_options(self):
# 'template' and 'manifest' are, respectively, the names of # 'template' and 'manifest' are, respectively, the names of
# the manifest template and manifest file. # the manifest template and manifest file.
...@@ -100,6 +113,7 @@ class sdist(Command): ...@@ -100,6 +113,7 @@ class sdist(Command):
self.dist_dir = None self.dist_dir = None
self.archive_files = None self.archive_files = None
self.metadata_check = 1
def finalize_options(self): def finalize_options(self):
if self.manifest is None: if self.manifest is None:
...@@ -129,9 +143,9 @@ class sdist(Command): ...@@ -129,9 +143,9 @@ class sdist(Command):
# manifest # manifest
self.filelist = FileList() self.filelist = FileList()
# Ensure that all required meta-data is given; warn if not (but # Run sub commands
# don't die, it's not *that* serious!) for cmd_name in self.get_sub_commands():
self.check_metadata() self.run_command(cmd_name)
# Do whatever it takes to get the list of files to process # Do whatever it takes to get the list of files to process
# (process the manifest template, read an existing manifest, # (process the manifest template, read an existing manifest,
...@@ -147,34 +161,12 @@ class sdist(Command): ...@@ -147,34 +161,12 @@ class sdist(Command):
self.make_distribution() self.make_distribution()
def check_metadata(self): def check_metadata(self):
"""Ensure that all required elements of meta-data (name, version, """Deprecated API."""
URL, (author and author_email) or (maintainer and warn("distutils.command.sdist.check_metadata is deprecated, \
maintainer_email)) are supplied by the Distribution object; warn if use the check command instead", PendingDeprecationWarning)
any are missing. check = self.distribution.get_command_obj('check')
""" check.ensure_finalized()
metadata = self.distribution.metadata check.run()
missing = []
for attr in ('name', 'version', 'url'):
if not (hasattr(metadata, attr) and getattr(metadata, attr)):
missing.append(attr)
if missing:
self.warn("missing required meta-data: " +
", ".join(missing))
if metadata.author:
if not metadata.author_email:
self.warn("missing meta-data: if 'author' supplied, " +
"'author_email' must be supplied too")
elif metadata.maintainer:
if not metadata.maintainer_email:
self.warn("missing meta-data: if 'maintainer' supplied, " +
"'maintainer_email' must be supplied too")
else:
self.warn("missing meta-data: either (author and author_email) " +
"or (maintainer and maintainer_email) " +
"must be supplied")
def get_file_list(self): def get_file_list(self):
"""Figure out the list of files to include in the source """Figure out the list of files to include in the source
......
...@@ -12,11 +12,31 @@ class LoggingSilencer(object): ...@@ -12,11 +12,31 @@ class LoggingSilencer(object):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.threshold = log.set_threshold(log.FATAL) self.threshold = log.set_threshold(log.FATAL)
# catching warnings
# when log will be replaced by logging
# we won't need such monkey-patch anymore
self._old_log = log.Log._log
log.Log._log = self._log
self.logs = []
def tearDown(self): def tearDown(self):
log.set_threshold(self.threshold) log.set_threshold(self.threshold)
log.Log._log = self._old_log
super().tearDown() super().tearDown()
def _log(self, level, msg, args):
self.logs.append((level, msg, args))
def get_logs(self, *levels):
def _format(msg, args):
if len(args) == 0:
return msg
return msg % args
return [_format(msg, args) for level, msg, args
in self.logs if level in levels]
def clear_logs(self):
self.logs = []
class TempdirManager(object): class TempdirManager(object):
"""Mix-in class that handles temporary directories for test cases. """Mix-in class that handles temporary directories for test cases.
......
...@@ -4,10 +4,14 @@ import os ...@@ -4,10 +4,14 @@ import os
import unittest import unittest
import getpass import getpass
import urllib import urllib
import warnings
from test.support import check_warnings
from distutils.command import register as register_module from distutils.command import register as register_module
from distutils.command.register import register from distutils.command.register import register
from distutils.core import Distribution from distutils.core import Distribution
from distutils.errors import DistutilsSetupError
from distutils.tests import support from distutils.tests import support
from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
...@@ -59,7 +63,7 @@ class FakeOpener(object): ...@@ -59,7 +63,7 @@ class FakeOpener(object):
def read(self): def read(self):
return 'xxx' return 'xxx'
class registerTestCase(PyPIRCCommandTestCase): class RegisterTestCase(PyPIRCCommandTestCase):
def setUp(self): def setUp(self):
PyPIRCCommandTestCase.setUp(self) PyPIRCCommandTestCase.setUp(self)
...@@ -76,7 +80,8 @@ class registerTestCase(PyPIRCCommandTestCase): ...@@ -76,7 +80,8 @@ class registerTestCase(PyPIRCCommandTestCase):
urllib.request.build_opener = self.old_opener urllib.request.build_opener = self.old_opener
PyPIRCCommandTestCase.tearDown(self) PyPIRCCommandTestCase.tearDown(self)
def _get_cmd(self): def _get_cmd(self, metadata=None):
if metadata is None:
metadata = {'url': 'xxx', 'author': 'xxx', metadata = {'url': 'xxx', 'author': 'xxx',
'author_email': 'xxx', 'author_email': 'xxx',
'name': 'xxx', 'version': 'xxx'} 'name': 'xxx', 'version': 'xxx'}
...@@ -184,8 +189,70 @@ class registerTestCase(PyPIRCCommandTestCase): ...@@ -184,8 +189,70 @@ class registerTestCase(PyPIRCCommandTestCase):
self.assertEquals(headers['Content-length'], '290') self.assertEquals(headers['Content-length'], '290')
self.assert_((b'tarek') in req.data) self.assert_((b'tarek') in req.data)
def test_strict(self):
# testing the script option
# when on, the register command stops if
# the metadata is incomplete or if
# long_description is not reSt compliant
# empty metadata
cmd = self._get_cmd({})
cmd.ensure_finalized()
cmd.strict = 1
self.assertRaises(DistutilsSetupError, cmd.run)
# we don't test the reSt feature if docutils
# is not installed
try:
import docutils
except ImportError:
return
# metadata are OK but long_description is broken
metadata = {'url': 'xxx', 'author': 'xxx',
'author_email': 'xxx',
'name': 'xxx', 'version': 'xxx',
'long_description': 'title\n==\n\ntext'}
cmd = self._get_cmd(metadata)
cmd.ensure_finalized()
cmd.strict = 1
self.assertRaises(DistutilsSetupError, cmd.run)
# now something that works
metadata['long_description'] = 'title\n=====\n\ntext'
cmd = self._get_cmd(metadata)
cmd.ensure_finalized()
cmd.strict = 1
inputs = RawInputs('1', 'tarek', 'y')
register_module.raw_input = inputs.__call__
# let's run the command
try:
cmd.run()
finally:
del register_module.raw_input
# strict is not by default
cmd = self._get_cmd()
cmd.ensure_finalized()
inputs = RawInputs('1', 'tarek', 'y')
register_module.raw_input = inputs.__call__
# let's run the command
try:
cmd.run()
finally:
del register_module.raw_input
def test_check_metadata_deprecated(self):
# makes sure make_metadata is deprecated
cmd = self._get_cmd()
with check_warnings() as w:
warnings.simplefilter("always")
cmd.check_metadata()
self.assertEquals(len(w.warnings), 1)
def test_suite(): def test_suite():
return unittest.makeSuite(registerTestCase) return unittest.makeSuite(RegisterTestCase)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main(defaultTest="test_suite") unittest.main(defaultTest="test_suite")
...@@ -6,7 +6,9 @@ import zipfile ...@@ -6,7 +6,9 @@ import zipfile
from os.path import join from os.path import join
import sys import sys
import tempfile import tempfile
import warnings
from test.support import check_warnings
from test.support import captured_stdout from test.support import captured_stdout
from distutils.command.sdist import sdist from distutils.command.sdist import sdist
...@@ -16,6 +18,7 @@ from distutils.tests.test_config import PyPIRCCommandTestCase ...@@ -16,6 +18,7 @@ from distutils.tests.test_config import PyPIRCCommandTestCase
from distutils.errors import DistutilsExecError, DistutilsOptionError from distutils.errors import DistutilsExecError, DistutilsOptionError
from distutils.spawn import find_executable from distutils.spawn import find_executable
from distutils.tests import support from distutils.tests import support
from distutils.log import WARN
from distutils.archive_util import ARCHIVE_FORMATS from distutils.archive_util import ARCHIVE_FORMATS
SETUP_PY = """ SETUP_PY = """
...@@ -38,12 +41,12 @@ somecode%(sep)sdoc.dat ...@@ -38,12 +41,12 @@ somecode%(sep)sdoc.dat
somecode%(sep)sdoc.txt somecode%(sep)sdoc.txt
""" """
class sdistTestCase(PyPIRCCommandTestCase): class SDistTestCase(PyPIRCCommandTestCase):
def setUp(self): def setUp(self):
# PyPIRCCommandTestCase creates a temp dir already # PyPIRCCommandTestCase creates a temp dir already
# and put it in self.tmp_dir # and put it in self.tmp_dir
super(sdistTestCase, self).setUp() super(SDistTestCase, self).setUp()
# setting up an environment # setting up an environment
self.old_path = os.getcwd() self.old_path = os.getcwd()
os.mkdir(join(self.tmp_dir, 'somecode')) os.mkdir(join(self.tmp_dir, 'somecode'))
...@@ -57,7 +60,7 @@ class sdistTestCase(PyPIRCCommandTestCase): ...@@ -57,7 +60,7 @@ class sdistTestCase(PyPIRCCommandTestCase):
def tearDown(self): def tearDown(self):
# back to normal # back to normal
os.chdir(self.old_path) os.chdir(self.old_path)
super(sdistTestCase, self).tearDown() super(SDistTestCase, self).tearDown()
def get_cmd(self, metadata=None): def get_cmd(self, metadata=None):
"""Returns a cmd""" """Returns a cmd"""
...@@ -214,6 +217,34 @@ class sdistTestCase(PyPIRCCommandTestCase): ...@@ -214,6 +217,34 @@ class sdistTestCase(PyPIRCCommandTestCase):
manifest = open(join(self.tmp_dir, 'MANIFEST')).read() manifest = open(join(self.tmp_dir, 'MANIFEST')).read()
self.assertEquals(manifest, MANIFEST % {'sep': os.sep}) self.assertEquals(manifest, MANIFEST % {'sep': os.sep})
def test_metadata_check_option(self):
# testing the `medata-check` option
dist, cmd = self.get_cmd(metadata={})
# this should raise some warnings !
# with the `check` subcommand
cmd.ensure_finalized()
cmd.run()
warnings = self.get_logs(WARN)
self.assertEquals(len(warnings), 2)
# trying with a complete set of metadata
self.clear_logs()
dist, cmd = self.get_cmd()
cmd.ensure_finalized()
cmd.metadata_check = 0
cmd.run()
warnings = self.get_logs(WARN)
self.assertEquals(len(warnings), 0)
def test_check_metadata_deprecated(self):
# makes sure make_metadata is deprecated
dist, cmd = self.get_cmd()
with check_warnings() as w:
warnings.simplefilter("always")
cmd.check_metadata()
self.assertEquals(len(w.warnings), 1)
def test_show_formats(self): def test_show_formats(self):
with captured_stdout() as stdout: with captured_stdout() as stdout:
show_formats() show_formats()
...@@ -247,7 +278,7 @@ class sdistTestCase(PyPIRCCommandTestCase): ...@@ -247,7 +278,7 @@ class sdistTestCase(PyPIRCCommandTestCase):
def test_suite(): def test_suite():
return unittest.makeSuite(sdistTestCase) return unittest.makeSuite(SDistTestCase)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main(defaultTest="test_suite") unittest.main(defaultTest="test_suite")
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