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.

80 lines
2.3 KiB

7 years ago
  1. """
  2. Archive tools for wheel.
  3. """
  4. import os
  5. import os.path
  6. import time
  7. import zipfile
  8. from distutils import log
  9. def archive_wheelfile(base_name, base_dir):
  10. """Archive all files under `base_dir` in a whl file and name it like
  11. `base_name`.
  12. """
  13. olddir = os.path.abspath(os.curdir)
  14. base_name = os.path.abspath(base_name)
  15. try:
  16. os.chdir(base_dir)
  17. return make_wheelfile_inner(base_name)
  18. finally:
  19. os.chdir(olddir)
  20. def make_wheelfile_inner(base_name, base_dir='.'):
  21. """Create a whl file from all the files under 'base_dir'.
  22. Places .dist-info at the end of the archive."""
  23. zip_filename = base_name + ".whl"
  24. log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir)
  25. # Some applications need reproducible .whl files, but they can't do this
  26. # without forcing the timestamp of the individual ZipInfo objects. See
  27. # issue #143.
  28. timestamp = os.environ.get('SOURCE_DATE_EPOCH')
  29. if timestamp is None:
  30. date_time = None
  31. else:
  32. date_time = time.gmtime(int(timestamp))[0:6]
  33. # XXX support bz2, xz when available
  34. zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_DEFLATED)
  35. score = {'WHEEL': 1, 'METADATA': 2, 'RECORD': 3}
  36. deferred = []
  37. def writefile(path, date_time):
  38. st = os.stat(path)
  39. if date_time is None:
  40. mtime = time.gmtime(st.st_mtime)
  41. date_time = mtime[0:6]
  42. zinfo = zipfile.ZipInfo(path, date_time)
  43. zinfo.external_attr = st.st_mode << 16
  44. zinfo.compress_type = zipfile.ZIP_DEFLATED
  45. with open(path, 'rb') as fp:
  46. zip.writestr(zinfo, fp.read())
  47. log.info("adding '%s'" % path)
  48. for dirpath, dirnames, filenames in os.walk(base_dir):
  49. # Sort the directory names so that `os.walk` will walk them in a
  50. # defined order on the next iteration.
  51. dirnames.sort()
  52. for name in sorted(filenames):
  53. path = os.path.normpath(os.path.join(dirpath, name))
  54. if os.path.isfile(path):
  55. if dirpath.endswith('.dist-info'):
  56. deferred.append((score.get(name, 0), path))
  57. else:
  58. writefile(path, date_time)
  59. deferred.sort()
  60. for score, path in deferred:
  61. writefile(path, date_time)
  62. zip.close()
  63. return zip_filename

Powered by TurnKey Linux.