-
Notifications
You must be signed in to change notification settings - Fork 100
/
source-archive
executable file
·97 lines (82 loc) · 4.05 KB
/
source-archive
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
#!/usr/bin/python
from __future__ import print_function
import os
from subprocess import call, Popen, PIPE
import sys
import zipfile
# Due to "git archive" not supporting archiving of submodules in
# addition to the base tree, this requires additional support in order
# to create a complete and functional source archive.
#
# This script archives the base tree, and then uses "git submodule
# foreach" to archive each submodule separately, setting the correct
# path prefix for each archive, so that they may all be unpacked in
# the same root to result in a complete and functional source tree.
# It then repacks each of these zip files into a single zip which is
# the source release, taking care to preserve timestamps and exectute
# permissions, etc. This is done via ZipInfo objects, and the
# repacking is done entirely in memory so that this should work on any
# platform irrespective of filesystem support for the archive
# attributes. It excludes .gitignore files at this point to avoid
# polluting the release with version control files.
if __name__ == "__main__":
if len(sys.argv) != 6:
raise Exception('Usage: %s releasename shortversion fullversion versionfile targetdir')
release = sys.argv[1]
shortversion = sys.argv[2]
version = sys.argv[3]
versionfile = sys.argv[4]
target = os.path.abspath(sys.argv[5])
release = "%s-%s" % (release,version)
if not os.path.isdir('.git'):
raise Exception('Releasing is only possible from a git repository')
print("Releasing %s" % (release))
sys.stdout.flush()
# Create base archive
base_archive_status = call(['git', 'archive', '--format', 'zip',
'--prefix', "%s/" % (release),
'--output', "%s/%s-base.zip" % (target, release),
'HEAD'])
if base_archive_status != 0:
raise Exception('Failed to create git base archive')
zips = list(["%s/%s-base.zip" % (target, release)])
# Create submodule archives
submodule_archive = Popen(['git', 'submodule', 'foreach', '--quiet', '--recursive',
"npath=\"$(echo \"$path\" | tr / _)\"; \
zip=\"%s/%s-submod-${npath}.zip\"; \
git archive --format zip --prefix \"%s/${path}/\" --output \"${zip}\" HEAD || exit 1; \
echo \"${zip}\"" % (target, release, release)],
stdout=PIPE)
submodule_zips = submodule_archive.communicate()[0]
if submodule_archive.returncode != 0:
raise Exception('Failed to create git submodule archives')
zips.extend(submodule_zips.splitlines())
# Create destination zip file
print(" - creating %s/%s.zip" % (target, release))
sys.stdout.flush()
basezip = zipfile.ZipFile("%s/%s.zip" % (target, release), 'w')
# Repack each of the separate zips into the destination zip
for name in zips:
subzip = zipfile.ZipFile(name, 'r')
print(" - repacking %s" % (name))
sys.stdout.flush()
# Iterate over the ZipInfo objects from the archive
for info in subzip.infolist():
# Skip unwanted git and travis files
if os.path.basename(info.filename) == '.gitignore' or os.path.basename(info.filename) == '.gitmodule' or os.path.basename(info.filename) == '.travis.yml':
continue
# Repack a single zip object; preserve the metadata
# directly via the ZipInfo object and rewrite the content
# (which unfortunately requires decompression and
# recompression rather than a direct copy)
basezip.writestr(info, subzip.open(info.filename).read())
# Remove repacked zip
os.remove(name)
# Embed release number
basezip.writestr("%s/%s" % (release, versionfile),
"""<?xml version="1.0" encoding="utf-8"?>
<project name="gitversion" basedir=".">
<property name="omero.shortversion" value="%s"/>
<property name="omero.plainversion" value="%s"/>
</project>
""" % (shortversion, version))