123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- #!/usr/bin/env python3
- # 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'),
- info.name.startswith(prefix + 'doc/internal'),
- ))
- 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)
- try:
- with TarFile.open(outTarPath, 'w:gz') as outTar:
- # Copy entries from "git archive" into output tarball,
- # except for excluded entries.
- numIncluded = numExcluded = 0
- with TarFile.open(mode='r|', fileobj=proc.stdout) as inTar:
- 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))
- print('entries: %d included, %d excluded' % (
- numIncluded, numExcluded))
- except:
- # Clean up partial output file.
- remove(outTarPath)
- raise
- 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('-')
- tag = parts[0]
- if tag.startswith('RELEASE_'):
- tagParts = tag.split('_')[1 : ]
- i = 0
- while i < len(tagParts) and tagParts[i].isdigit():
- i += 1
- version = '-'.join(
- ['.'.join(tagParts[ : i])] +
- [s.lower() for s in tagParts[i : ]]
- )
- else:
- version = tag
- if len(parts) >= 2:
- parts[1] = 'dev' + parts[1]
- return '-'.join([version] + parts[1 : ])
- def getDescription(committish):
- args = ['git', 'describe', '--abbrev=9']
- if committish is not None:
- args.append(committish)
- try:
- data = check_output(args)
- except CalledProcessError as ex:
- print(
- '"%s" returned %d' % (' '.join(args), ex.returncode),
- file=sys.stderr
- )
- raise
- else:
- return data.decode('utf-8', 'replace').rstrip('\n')
- def main(committish = None):
- try:
- description = getDescription(committish)
- except CalledProcessError:
- sys.exit(1)
- version = niceVersionFromGitDescription(description)
- try:
- archiveFromGit('openmsx-%s' % version, description)
- except (OSError, TarError) as ex:
- print('ERROR: %s' % ex, file=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)
|