PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/env/lib/python3.3/site-packages/setuptools/command/sdist.py

https://github.com/wantsomechocolate/MosaicMaker
Python | 304 lines | 228 code | 60 blank | 16 comment | 54 complexity | 0c439eca83b628035531153bd6825bd6 MD5 | raw file
  1. from distutils.command.sdist import sdist as _sdist
  2. from distutils.util import convert_path
  3. from distutils import log
  4. from glob import glob
  5. import os, re, sys, pkg_resources
  6. from glob import glob
  7. READMES = ('README', 'README.rst', 'README.txt')
  8. entities = [
  9. ("&lt;","<"), ("&gt;", ">"), ("&quot;", '"'), ("&apos;", "'"),
  10. ("&amp;", "&")
  11. ]
  12. def unescape(data):
  13. for old,new in entities:
  14. data = data.replace(old,new)
  15. return data
  16. def re_finder(pattern, postproc=None):
  17. def find(dirname, filename):
  18. f = open(filename,'rU')
  19. data = f.read()
  20. f.close()
  21. for match in pattern.finditer(data):
  22. path = match.group(1)
  23. if postproc:
  24. path = postproc(path)
  25. yield joinpath(dirname,path)
  26. return find
  27. def joinpath(prefix,suffix):
  28. if not prefix:
  29. return suffix
  30. return os.path.join(prefix,suffix)
  31. def walk_revctrl(dirname=''):
  32. """Find all files under revision control"""
  33. for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
  34. for item in ep.load()(dirname):
  35. yield item
  36. def _default_revctrl(dirname=''):
  37. for path, finder in finders:
  38. path = joinpath(dirname,path)
  39. if os.path.isfile(path):
  40. for path in finder(dirname,path):
  41. if os.path.isfile(path):
  42. yield path
  43. elif os.path.isdir(path):
  44. for item in _default_revctrl(path):
  45. yield item
  46. def externals_finder(dirname, filename):
  47. """Find any 'svn:externals' directories"""
  48. found = False
  49. f = open(filename,'rt')
  50. for line in iter(f.readline, ''): # can't use direct iter!
  51. parts = line.split()
  52. if len(parts)==2:
  53. kind,length = parts
  54. data = f.read(int(length))
  55. if kind=='K' and data=='svn:externals':
  56. found = True
  57. elif kind=='V' and found:
  58. f.close()
  59. break
  60. else:
  61. f.close()
  62. return
  63. for line in data.splitlines():
  64. parts = line.split()
  65. if parts:
  66. yield joinpath(dirname, parts[0])
  67. entries_pattern = re.compile(r'name="([^"]+)"(?![^>]+deleted="true")', re.I)
  68. def entries_finder(dirname, filename):
  69. f = open(filename,'rU')
  70. data = f.read()
  71. f.close()
  72. if data.startswith('<?xml'):
  73. for match in entries_pattern.finditer(data):
  74. yield joinpath(dirname,unescape(match.group(1)))
  75. else:
  76. svnver=-1
  77. try: svnver = int(data.splitlines()[0])
  78. except: pass
  79. if svnver<8:
  80. log.warn("unrecognized .svn/entries format in %s", os.path.abspath(dirname))
  81. return
  82. for record in map(str.splitlines, data.split('\n\x0c\n')[1:]):
  83. # subversion 1.6/1.5/1.4
  84. if not record or len(record)>=6 and record[5]=="delete":
  85. continue # skip deleted
  86. yield joinpath(dirname, record[0])
  87. finders = [
  88. (convert_path('CVS/Entries'),
  89. re_finder(re.compile(r"^\w?/([^/]+)/", re.M))),
  90. (convert_path('.svn/entries'), entries_finder),
  91. (convert_path('.svn/dir-props'), externals_finder),
  92. (convert_path('.svn/dir-prop-base'), externals_finder), # svn 1.4
  93. ]
  94. class sdist(_sdist):
  95. """Smart sdist that finds anything supported by revision control"""
  96. user_options = [
  97. ('formats=', None,
  98. "formats for source distribution (comma-separated list)"),
  99. ('keep-temp', 'k',
  100. "keep the distribution tree around after creating " +
  101. "archive file(s)"),
  102. ('dist-dir=', 'd',
  103. "directory to put the source distribution archive(s) in "
  104. "[default: dist]"),
  105. ]
  106. negative_opt = {}
  107. def run(self):
  108. self.run_command('egg_info')
  109. ei_cmd = self.get_finalized_command('egg_info')
  110. self.filelist = ei_cmd.filelist
  111. self.filelist.append(os.path.join(ei_cmd.egg_info,'SOURCES.txt'))
  112. self.check_readme()
  113. # Run sub commands
  114. for cmd_name in self.get_sub_commands():
  115. self.run_command(cmd_name)
  116. # Call check_metadata only if no 'check' command
  117. # (distutils <= 2.6)
  118. import distutils.command
  119. if 'check' not in distutils.command.__all__:
  120. self.check_metadata()
  121. self.make_distribution()
  122. dist_files = getattr(self.distribution,'dist_files',[])
  123. for file in self.archive_files:
  124. data = ('sdist', '', file)
  125. if data not in dist_files:
  126. dist_files.append(data)
  127. def __read_template_hack(self):
  128. # This grody hack closes the template file (MANIFEST.in) if an
  129. # exception occurs during read_template.
  130. # Doing so prevents an error when easy_install attempts to delete the
  131. # file.
  132. try:
  133. _sdist.read_template(self)
  134. except:
  135. sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close()
  136. raise
  137. # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
  138. # has been fixed, so only override the method if we're using an earlier
  139. # Python.
  140. if (
  141. sys.version_info < (2,7,2)
  142. or (3,0) <= sys.version_info < (3,1,4)
  143. or (3,2) <= sys.version_info < (3,2,1)
  144. ):
  145. read_template = __read_template_hack
  146. def add_defaults(self):
  147. standards = [READMES,
  148. self.distribution.script_name]
  149. for fn in standards:
  150. if isinstance(fn, tuple):
  151. alts = fn
  152. got_it = 0
  153. for fn in alts:
  154. if os.path.exists(fn):
  155. got_it = 1
  156. self.filelist.append(fn)
  157. break
  158. if not got_it:
  159. self.warn("standard file not found: should have one of " +
  160. ', '.join(alts))
  161. else:
  162. if os.path.exists(fn):
  163. self.filelist.append(fn)
  164. else:
  165. self.warn("standard file '%s' not found" % fn)
  166. optional = ['test/test*.py', 'setup.cfg']
  167. for pattern in optional:
  168. files = list(filter(os.path.isfile, glob(pattern)))
  169. if files:
  170. self.filelist.extend(files)
  171. # getting python files
  172. if self.distribution.has_pure_modules():
  173. build_py = self.get_finalized_command('build_py')
  174. self.filelist.extend(build_py.get_source_files())
  175. # This functionality is incompatible with include_package_data, and
  176. # will in fact create an infinite recursion if include_package_data
  177. # is True. Use of include_package_data will imply that
  178. # distutils-style automatic handling of package_data is disabled
  179. if not self.distribution.include_package_data:
  180. for _, src_dir, _, filenames in build_py.data_files:
  181. self.filelist.extend([os.path.join(src_dir, filename)
  182. for filename in filenames])
  183. if self.distribution.has_ext_modules():
  184. build_ext = self.get_finalized_command('build_ext')
  185. self.filelist.extend(build_ext.get_source_files())
  186. if self.distribution.has_c_libraries():
  187. build_clib = self.get_finalized_command('build_clib')
  188. self.filelist.extend(build_clib.get_source_files())
  189. if self.distribution.has_scripts():
  190. build_scripts = self.get_finalized_command('build_scripts')
  191. self.filelist.extend(build_scripts.get_source_files())
  192. def check_readme(self):
  193. for f in READMES:
  194. if os.path.exists(f):
  195. return
  196. else:
  197. self.warn(
  198. "standard file not found: should have one of " +', '.join(READMES)
  199. )
  200. def make_release_tree(self, base_dir, files):
  201. _sdist.make_release_tree(self, base_dir, files)
  202. # Save any egg_info command line options used to create this sdist
  203. dest = os.path.join(base_dir, 'setup.cfg')
  204. if hasattr(os,'link') and os.path.exists(dest):
  205. # unlink and re-copy, since it might be hard-linked, and
  206. # we don't want to change the source version
  207. os.unlink(dest)
  208. self.copy_file('setup.cfg', dest)
  209. self.get_finalized_command('egg_info').save_version_info(dest)
  210. def _manifest_is_not_generated(self):
  211. # check for special comment used in 2.7.1 and higher
  212. if not os.path.isfile(self.manifest):
  213. return False
  214. fp = open(self.manifest, 'rbU')
  215. try:
  216. first_line = fp.readline()
  217. finally:
  218. fp.close()
  219. return first_line != '# file GENERATED by distutils, do NOT edit\n'.encode()
  220. def read_manifest(self):
  221. """Read the manifest file (named by 'self.manifest') and use it to
  222. fill in 'self.filelist', the list of files to include in the source
  223. distribution.
  224. """
  225. log.info("reading manifest file '%s'", self.manifest)
  226. manifest = open(self.manifest, 'rbU')
  227. for line in manifest:
  228. # The manifest must contain UTF-8. See #303.
  229. if sys.version_info >= (3,):
  230. try:
  231. line = line.decode('UTF-8')
  232. except UnicodeDecodeError:
  233. log.warn("%r not UTF-8 decodable -- skipping" % line)
  234. continue
  235. # ignore comments and blank lines
  236. line = line.strip()
  237. if line.startswith('#') or not line:
  238. continue
  239. self.filelist.append(line)
  240. manifest.close()
  241. #