archiver_3_4.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. def create_archive(self, scm_object, **kwargs):
  2. """Create a tarball of repodir in destination directory."""
  3. (workdir, topdir) = os.path.split(scm_object.arch_dir)
  4. args = kwargs['cli']
  5. outdir = args.outdir
  6. dstname = kwargs['dstname']
  7. extension = (args.extension or 'tar')
  8. exclude = args.exclude
  9. include = args.include
  10. package_metadata = args.package_meta
  11. timestamp = self.helpers.get_timestamp(
  12. scm_object,
  13. args,
  14. scm_object.clone_dir
  15. )
  16. incl_patterns = []
  17. excl_patterns = []
  18. for i in include:
  19. # for backward compatibility add a trailing '*' if i isn't a
  20. # pattern
  21. if fnmatch.translate(i) == fnmatch.translate(i + r''):
  22. i += r'*'
  23. pat = fnmatch.translate(os.path.join(topdir, i))
  24. incl_patterns.append(re.compile(pat))
  25. for exc in exclude:
  26. pat = fnmatch.translate(os.path.join(topdir, exc))
  27. excl_patterns.append(re.compile(pat))
  28. def tar_exclude(filename):
  29. """
  30. Exclude (return True) or add (return False) file to tar achive.
  31. """
  32. if not package_metadata and METADATA_PATTERN.match(filename):
  33. return True
  34. if incl_patterns:
  35. for pat in incl_patterns:
  36. if pat.match(filename):
  37. return False
  38. return True
  39. for pat in excl_patterns:
  40. if pat.match(filename):
  41. return True
  42. return False
  43. def reset(tarinfo):
  44. """Python 2.7 only: reset uid/gid to 0/0 (root)."""
  45. tarinfo.uid = tarinfo.gid = 0
  46. tarinfo.uname = tarinfo.gname = "root"
  47. if timestamp != 0:
  48. tarinfo.mtime = timestamp
  49. return tarinfo
  50. def tar_filter(tarinfo):
  51. if tar_exclude(tarinfo.name):
  52. return None
  53. return reset(tarinfo)
  54. cwd = os.getcwd()
  55. os.chdir(workdir)
  56. enc = locale.getpreferredencoding()
  57. out_file = os.path.join(outdir, dstname + '.' + extension)
  58. with tarfile.open(out_file, "w", encoding=enc) as tar:
  59. try:
  60. tar.add(topdir, recursive=False, filter=reset)
  61. except TypeError:
  62. # Python 2.6 compatibility
  63. tar.add(topdir, recursive=False)
  64. for entry in map(lambda x: os.path.join(topdir, x),
  65. sorted(os.listdir(topdir))):
  66. try:
  67. tar.add(entry, filter=tar_filter)
  68. except TypeError:
  69. # Python 2.6 compatibility
  70. tar.add(entry, exclude=tar_exclude)
  71. self.archivefile = tar.name
  72. os.chdir(cwd)