You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

198 lines
6.9 KiB

  1. from glob import glob
  2. from distutils import log
  3. import distutils.command.sdist as orig
  4. import os
  5. import sys
  6. from setuptools.compat import PY3
  7. from setuptools.utils import cs_path_exists
  8. import pkg_resources
  9. READMES = 'README', 'README.rst', 'README.txt'
  10. _default_revctrl = list
  11. def walk_revctrl(dirname=''):
  12. """Find all files under revision control"""
  13. for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
  14. for item in ep.load()(dirname):
  15. yield item
  16. class sdist(orig.sdist):
  17. """Smart sdist that finds anything supported by revision control"""
  18. user_options = [
  19. ('formats=', None,
  20. "formats for source distribution (comma-separated list)"),
  21. ('keep-temp', 'k',
  22. "keep the distribution tree around after creating " +
  23. "archive file(s)"),
  24. ('dist-dir=', 'd',
  25. "directory to put the source distribution archive(s) in "
  26. "[default: dist]"),
  27. ]
  28. negative_opt = {}
  29. def run(self):
  30. self.run_command('egg_info')
  31. ei_cmd = self.get_finalized_command('egg_info')
  32. self.filelist = ei_cmd.filelist
  33. self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))
  34. self.check_readme()
  35. # Run sub commands
  36. for cmd_name in self.get_sub_commands():
  37. self.run_command(cmd_name)
  38. # Call check_metadata only if no 'check' command
  39. # (distutils <= 2.6)
  40. import distutils.command
  41. if 'check' not in distutils.command.__all__:
  42. self.check_metadata()
  43. self.make_distribution()
  44. dist_files = getattr(self.distribution, 'dist_files', [])
  45. for file in self.archive_files:
  46. data = ('sdist', '', file)
  47. if data not in dist_files:
  48. dist_files.append(data)
  49. def __read_template_hack(self):
  50. # This grody hack closes the template file (MANIFEST.in) if an
  51. # exception occurs during read_template.
  52. # Doing so prevents an error when easy_install attempts to delete the
  53. # file.
  54. try:
  55. orig.sdist.read_template(self)
  56. except:
  57. _, _, tb = sys.exc_info()
  58. tb.tb_next.tb_frame.f_locals['template'].close()
  59. raise
  60. # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
  61. # has been fixed, so only override the method if we're using an earlier
  62. # Python.
  63. has_leaky_handle = (
  64. sys.version_info < (2, 7, 2)
  65. or (3, 0) <= sys.version_info < (3, 1, 4)
  66. or (3, 2) <= sys.version_info < (3, 2, 1)
  67. )
  68. if has_leaky_handle:
  69. read_template = __read_template_hack
  70. def add_defaults(self):
  71. standards = [READMES,
  72. self.distribution.script_name]
  73. for fn in standards:
  74. if isinstance(fn, tuple):
  75. alts = fn
  76. got_it = 0
  77. for fn in alts:
  78. if cs_path_exists(fn):
  79. got_it = 1
  80. self.filelist.append(fn)
  81. break
  82. if not got_it:
  83. self.warn("standard file not found: should have one of " +
  84. ', '.join(alts))
  85. else:
  86. if cs_path_exists(fn):
  87. self.filelist.append(fn)
  88. else:
  89. self.warn("standard file '%s' not found" % fn)
  90. optional = ['test/test*.py', 'setup.cfg']
  91. for pattern in optional:
  92. files = list(filter(cs_path_exists, glob(pattern)))
  93. if files:
  94. self.filelist.extend(files)
  95. # getting python files
  96. if self.distribution.has_pure_modules():
  97. build_py = self.get_finalized_command('build_py')
  98. self.filelist.extend(build_py.get_source_files())
  99. # This functionality is incompatible with include_package_data, and
  100. # will in fact create an infinite recursion if include_package_data
  101. # is True. Use of include_package_data will imply that
  102. # distutils-style automatic handling of package_data is disabled
  103. if not self.distribution.include_package_data:
  104. for _, src_dir, _, filenames in build_py.data_files:
  105. self.filelist.extend([os.path.join(src_dir, filename)
  106. for filename in filenames])
  107. if self.distribution.has_ext_modules():
  108. build_ext = self.get_finalized_command('build_ext')
  109. self.filelist.extend(build_ext.get_source_files())
  110. if self.distribution.has_c_libraries():
  111. build_clib = self.get_finalized_command('build_clib')
  112. self.filelist.extend(build_clib.get_source_files())
  113. if self.distribution.has_scripts():
  114. build_scripts = self.get_finalized_command('build_scripts')
  115. self.filelist.extend(build_scripts.get_source_files())
  116. def check_readme(self):
  117. for f in READMES:
  118. if os.path.exists(f):
  119. return
  120. else:
  121. self.warn(
  122. "standard file not found: should have one of " +
  123. ', '.join(READMES)
  124. )
  125. def make_release_tree(self, base_dir, files):
  126. orig.sdist.make_release_tree(self, base_dir, files)
  127. # Save any egg_info command line options used to create this sdist
  128. dest = os.path.join(base_dir, 'setup.cfg')
  129. if hasattr(os, 'link') and os.path.exists(dest):
  130. # unlink and re-copy, since it might be hard-linked, and
  131. # we don't want to change the source version
  132. os.unlink(dest)
  133. self.copy_file('setup.cfg', dest)
  134. self.get_finalized_command('egg_info').save_version_info(dest)
  135. def _manifest_is_not_generated(self):
  136. # check for special comment used in 2.7.1 and higher
  137. if not os.path.isfile(self.manifest):
  138. return False
  139. fp = open(self.manifest, 'rbU')
  140. try:
  141. first_line = fp.readline()
  142. finally:
  143. fp.close()
  144. return (first_line !=
  145. '# file GENERATED by distutils, do NOT edit\n'.encode())
  146. def read_manifest(self):
  147. """Read the manifest file (named by 'self.manifest') and use it to
  148. fill in 'self.filelist', the list of files to include in the source
  149. distribution.
  150. """
  151. log.info("reading manifest file '%s'", self.manifest)
  152. manifest = open(self.manifest, 'rbU')
  153. for line in manifest:
  154. # The manifest must contain UTF-8. See #303.
  155. if PY3:
  156. try:
  157. line = line.decode('UTF-8')
  158. except UnicodeDecodeError:
  159. log.warn("%r not UTF-8 decodable -- skipping" % line)
  160. continue
  161. # ignore comments and blank lines
  162. line = line.strip()
  163. if line.startswith('#') or not line:
  164. continue
  165. self.filelist.append(line)
  166. manifest.close()