diff options
Diffstat (limited to 'setuptools/command/sdist.py')
-rwxr-xr-x | setuptools/command/sdist.py | 130 |
1 files changed, 119 insertions, 11 deletions
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 5bd5ebd4..b8c8495e 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -2,6 +2,9 @@ from distutils.command.sdist import sdist as _sdist from distutils.util import convert_path from distutils import log import os, re, sys, pkg_resources +from glob import glob + +READMES = ('README', 'README.rst', 'README.txt') entities = [ ("<","<"), (">", ">"), (""", '"'), ("'", "'"), @@ -59,7 +62,7 @@ def _default_revctrl(dirname=''): def externals_finder(dirname, filename): """Find any 'svn:externals' directories""" found = False - f = open(filename,'rb') + f = open(filename,'rt') for line in iter(f.readline, ''): # can't use direct iter! parts = line.split() if len(parts)==2: @@ -86,8 +89,9 @@ def entries_finder(dirname, filename): f = open(filename,'rU') data = f.read() f.close() - if data.startswith('9') or data.startswith('8'): # subversion 1.5/1.4 + if data.startswith('10') or data.startswith('9') or data.startswith('8'): for record in map(str.splitlines, data.split('\n\x0c\n')[1:]): + # subversion 1.6/1.5/1.4 if not record or len(record)>=6 and record[5]=="delete": continue # skip deleted yield joinpath(dirname, record[0]) @@ -95,7 +99,7 @@ def entries_finder(dirname, filename): for match in entries_pattern.finditer(data): yield joinpath(dirname,unescape(match.group(1))) else: - log.warn("unrecognized .svn/entries format in %s", dirname) + log.warn("unrecognized .svn/entries format in %s", os.path.abspath(dirname)) finders = [ @@ -143,7 +147,17 @@ class sdist(_sdist): self.filelist = ei_cmd.filelist self.filelist.append(os.path.join(ei_cmd.egg_info,'SOURCES.txt')) self.check_readme() - self.check_metadata() + + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + # Call check_metadata only if no 'check' command + # (distutils <= 2.6) + import distutils.command + if 'check' not in distutils.command.__all__: + self.check_metadata() + self.make_distribution() dist_files = getattr(self.distribution,'dist_files',[]) @@ -152,24 +166,86 @@ class sdist(_sdist): if data not in dist_files: dist_files.append(data) - def read_template(self): + def __read_template_hack(self): + # This grody hack closes the template file (MANIFEST.in) if an + # exception occurs during read_template. + # Doing so prevents an error when easy_install attempts to delete the + # file. try: _sdist.read_template(self) except: - # grody hack to close the template file (MANIFEST.in) - # this prevents easy_install's attempt at deleting the file from - # dying and thus masking the real error sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close() raise + # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle + # has been fixed, so only override the method if we're using an earlier + # Python. + if ( + sys.version_info < (2,7,2) + or (3,0) <= sys.version_info < (3,1,4) + or (3,2) <= sys.version_info < (3,2,1) + ): + read_template = __read_template_hack + + def add_defaults(self): + standards = [READMES, + self.distribution.script_name] + for fn in standards: + if isinstance(fn, tuple): + alts = fn + got_it = 0 + for fn in alts: + if os.path.exists(fn): + got_it = 1 + self.filelist.append(fn) + break + + if not got_it: + self.warn("standard file not found: should have one of " + + ', '.join(alts)) + else: + if os.path.exists(fn): + self.filelist.append(fn) + else: + self.warn("standard file '%s' not found" % fn) + + optional = ['test/test*.py', 'setup.cfg'] + for pattern in optional: + files = filter(os.path.isfile, glob(pattern)) + if files: + self.filelist.extend(files) + + # getting python files + if self.distribution.has_pure_modules(): + build_py = self.get_finalized_command('build_py') + self.filelist.extend(build_py.get_source_files()) + # This functionality is incompatible with include_package_data, and + # will in fact create an infinite recursion if include_package_data + # is True. Use of include_package_data will imply that + # distutils-style automatic handling of package_data is disabled + if not self.distribution.include_package_data: + for _, src_dir, _, filenames in build_py.data_files: + self.filelist.extend([os.path.join(src_dir, filename) + for filename in filenames]) + + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + self.filelist.extend(build_ext.get_source_files()) + + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.filelist.extend(build_clib.get_source_files()) + + if self.distribution.has_scripts(): + build_scripts = self.get_finalized_command('build_scripts') + self.filelist.extend(build_scripts.get_source_files()) def check_readme(self): - alts = ("README", "README.txt") - for f in alts: + for f in READMES: if os.path.exists(f): return else: self.warn( - "standard file not found: should have one of " +', '.join(alts) + "standard file not found: should have one of " +', '.join(READMES) ) @@ -186,7 +262,39 @@ class sdist(_sdist): self.get_finalized_command('egg_info').save_version_info(dest) + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + fp = open(self.manifest, 'rbU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n'.encode() + + def read_manifest(self): + """Read the manifest file (named by 'self.manifest') and use it to + fill in 'self.filelist', the list of files to include in the source + distribution. + """ + log.info("reading manifest file '%s'", self.manifest) + manifest = open(self.manifest, 'rbU') + for line in manifest: + # The manifest must contain UTF-8. See #303. + if sys.version_info >= (3,): + try: + line = line.decode('UTF-8') + except UnicodeDecodeError: + log.warn("%r not UTF-8 decodable -- skipping" % line) + continue + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue + self.filelist.append(line) + manifest.close() |