gitdist.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/usr/bin/env python2
  2. # Creates a source distribution package.
  3. from os import makedirs, remove
  4. from os.path import isdir
  5. from subprocess import CalledProcessError, PIPE, Popen, check_output
  6. from tarfile import TarError, TarFile
  7. import stat, sys
  8. verbose = False
  9. def archiveFromGit(versionedPackageName, committish):
  10. prefix = '%s/' % versionedPackageName
  11. distBase = 'derived/dist/'
  12. umask = (
  13. stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
  14. stat.S_IRGRP | stat.S_IXGRP |
  15. stat.S_IROTH | stat.S_IXOTH
  16. )
  17. def exclude(info):
  18. '''Returns True iff the given tar entry should be excluded.
  19. '''
  20. return any((
  21. info.name.endswith('/.gitignore'),
  22. ))
  23. proc = Popen(
  24. ('git', 'archive', '--prefix=' + prefix, '--format=tar', committish),
  25. bufsize = -1,
  26. stdin = None, stdout = PIPE, stderr = sys.stderr,
  27. )
  28. try:
  29. outTarPath = distBase + versionedPackageName + '.tar.gz'
  30. print 'archive:', outTarPath
  31. if not isdir(distBase):
  32. makedirs(distBase)
  33. outTar = TarFile.open(outTarPath, 'w:gz')
  34. try:
  35. # Copy entries from "git archive" into output tarball, except for
  36. # excluded entries.
  37. numIncluded = numExcluded = 0
  38. inTar = TarFile.open(mode = 'r|', fileobj = proc.stdout)
  39. try:
  40. for info in inTar:
  41. if exclude(info):
  42. if verbose:
  43. print 'EX', info.name
  44. numExcluded += 1
  45. else:
  46. if verbose:
  47. print 'IN', info.name
  48. numIncluded += 1
  49. info.uid = info.gid = 1000
  50. info.uname = info.gname = 'openmsx'
  51. info.mode = info.mode & umask
  52. outTar.addfile(info, inTar.extractfile(info))
  53. finally:
  54. inTar.close()
  55. print 'entries: %d included, %d excluded' % (
  56. numIncluded, numExcluded)
  57. except:
  58. # Clean up partial output file.
  59. outTar.close()
  60. remove(outTarPath)
  61. raise
  62. else:
  63. outTar.close()
  64. except:
  65. proc.terminate()
  66. raise
  67. else:
  68. data, _ = proc.communicate()
  69. if len(data) != 0:
  70. print >> sys.stderr, (
  71. 'WARNING: %d more bytes of data from "git archive" after '
  72. 'tar stream ended' % len(data))
  73. def niceVersionFromGitDescription(description):
  74. '''Our release tag names are still based on naming limitations from CVS;
  75. convert them to something more pleasing to the eyes.
  76. '''
  77. parts = description.split('-')
  78. if parts[0].startswith('RELEASE_'):
  79. tagParts = tag.split('_')[1 : ]
  80. i = 0
  81. while i < len(tagParts) and tagParts[i].isdigit():
  82. i += 1
  83. parts[0] = '-'.join(
  84. ['.'.join(tagParts[ : i])] +
  85. [s.lower() for s in tagParts[i : ]]
  86. )
  87. if len(parts) >= 2:
  88. parts[1] = 'dev' + parts[1]
  89. if parts[0] == 'INIT':
  90. del parts[0]
  91. return '-'.join(parts)
  92. def getDescription(committish):
  93. args = ['git', 'describe', '--abbrev=9']
  94. if committish is not None:
  95. args.append(committish)
  96. try:
  97. return check_output(args).rstrip('\n')
  98. except CalledProcessError as ex:
  99. print >> sys.stderr, '"%s" returned %d' % (
  100. ' '.join(args), ex.returncode
  101. )
  102. raise
  103. def main(committish = None):
  104. try:
  105. description = getDescription(committish)
  106. except CalledProcessError:
  107. sys.exit(1)
  108. version = niceVersionFromGitDescription(description)
  109. try:
  110. archiveFromGit('openmsx-debugger-%s' % version, description)
  111. except (OSError, TarError) as ex:
  112. print >> sys.stderr, 'ERROR: %s' % ex
  113. sys.exit(1)
  114. if __name__ == '__main__':
  115. if len(sys.argv) == 1:
  116. main()
  117. elif len(sys.argv) == 2:
  118. main(sys.argv[1])
  119. else:
  120. print >> sys.stderr, 'Usage: gitdist.py [branch | tag]'
  121. sys.exit(2)