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