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