Skip to content

Commit 8df5951

Browse files
committed
packaging bugfix: Make archive include MCAD
1 parent 7a74c62 commit 8df5951

File tree

2 files changed

+172
-1
lines changed

2 files changed

+172
-1
lines changed

doc/release-checklist.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ o Tag release
1212
git tag "openscad-2011.12"
1313

1414
o build source package
15-
git archive --format=tar openscad-2011.12 --prefix=openscad-2011.12/ | gzip > openscad-2011.12.src.tar.gz
15+
scripts/git-archive-all.py --prefix=openscad-2011.12/ openscad-2011.12.src.tar.gz
1616

1717
o build binaries
1818
tar xzf openscad-2011.12.src.tar.gz

scripts/git-archive-all.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#! /usr/bin/env python
2+
3+
import sys
4+
from os import path, chdir
5+
from subprocess import Popen, PIPE
6+
from sys import argv, stdout
7+
from fnmatch import fnmatch
8+
9+
10+
class GitArchiver(object):
11+
"""
12+
GitArchiver
13+
14+
Scan a git repository and export all tracked files, and submodules.
15+
Checks for .gitattributes files in each directory and uses 'export-ignore'
16+
pattern entries for ignore files in the archive.
17+
18+
Automatically detects output format extension: zip, tar, bz2, or gz
19+
"""
20+
21+
def __init__(self, prefix='', verbose=False, exclude=True, extra=[]):
22+
self.prefix = prefix
23+
self.verbose = verbose
24+
self.exclude = exclude
25+
self.extra = extra
26+
27+
self._excludes = []
28+
29+
30+
def create(self, output_file):
31+
"""
32+
create(str output_file) -> None
33+
34+
Creates the archive, written to the given output_file
35+
Filetype may be one of: gz, zip, bz2, tar
36+
"""
37+
#
38+
# determine the format
39+
#
40+
_, _, format = output_file.rpartition(".")
41+
42+
if format.lower() == 'zip':
43+
from zipfile import ZipFile, ZIP_DEFLATED
44+
output_archive = ZipFile(path.abspath(output_file), 'w')
45+
add = lambda name, arcname: output_archive.write(name, self.prefix + arcname, ZIP_DEFLATED)
46+
47+
elif format.lower() in ['tar', 'bz2', 'gz']:
48+
import tarfile
49+
t_mode = ('w:%s' % format) if format != 'tar' else 'w'
50+
51+
output_archive = tarfile.open(path.abspath(output_file), t_mode)
52+
add = lambda name, arcname: output_archive.add(name, self.prefix + arcname)
53+
else:
54+
raise RuntimeError("Unknown format: '%s'" % format)
55+
56+
#
57+
# compress
58+
#
59+
60+
# extra files first (we may change folder later)
61+
for name in self.extra:
62+
if self.verbose:
63+
toPath = '=> %s%s' % (self.prefix, name) if self.prefix else ""
64+
print 'Compressing %s %s ...' % (name, toPath)
65+
add(name, name)
66+
67+
self._excludes = []
68+
69+
for name, arcname in self.listFiles(path.abspath('')):
70+
if self.verbose:
71+
toPath = '=> %s%s' % (self.prefix, arcname) if self.prefix else ""
72+
print 'Compressing %s %s ...' % (arcname, toPath)
73+
add(name, arcname)
74+
75+
output_archive.close()
76+
77+
78+
def listFiles(self, git_repositary_path, baselevel=''):
79+
"""
80+
listFiles(str git_repository_path, str baselevel='') -> iterator
81+
82+
An iterator method that yields a tuple(filepath, fullpath)
83+
for each file that should be included in the archive.
84+
Skips those that match the exclusion patterns found in
85+
any discovered .gitattributes files along the way.
86+
87+
Recurses into submodules as well.
88+
"""
89+
for filepath in self.runShell('git ls-files --cached --full-name --no-empty-directory'):
90+
fullpath = path.join(baselevel, filepath)
91+
filename = path.basename(filepath)
92+
93+
if self.exclude and filename == '.gitattributes':
94+
self._excludes = []
95+
fh = open(filepath, 'r')
96+
for line in fh:
97+
if not line: break
98+
tokens = line.strip().split()
99+
if 'export-ignore' in tokens[1:]:
100+
self._excludes.append(tokens[0])
101+
fh.close()
102+
103+
if not filename.startswith('.git') and not path.isdir(filepath):
104+
105+
# check the patterns first
106+
ignore = False
107+
for pattern in self._excludes:
108+
if fnmatch(fullpath, pattern) or fnmatch(filename, pattern):
109+
if self.verbose: print 'Exclude pattern matched (%s): %s' % (pattern, fullpath)
110+
ignore = True
111+
break
112+
if ignore:
113+
continue
114+
115+
# baselevel is needed to tell the arhiver where it have to extract file
116+
yield filepath, fullpath
117+
118+
# get paths for every submodule
119+
for submodule in self.runShell("git submodule --quiet foreach 'pwd'"):
120+
chdir(submodule)
121+
# in order to get output path we need to exclude repository path from the submodule path
122+
submodule = submodule[len(git_repositary_path)+1:]
123+
# recursion allows us to process repositories with more than one level of submodules
124+
for git_file in self.listFiles(git_repositary_path, submodule):
125+
yield git_file
126+
127+
128+
129+
@staticmethod
130+
def runShell(cmd):
131+
return Popen(cmd, shell=True, stdout=PIPE).stdout.read().splitlines()
132+
133+
134+
135+
if __name__ == "__main__":
136+
from optparse import OptionParser
137+
138+
parser = OptionParser(usage="usage: %prog [-v] [--prefix PREFIX] [--no-exclude] OUTPUT_FILE", version="%prog 1.0")
139+
140+
parser.add_option('--prefix', type='string', dest='prefix',
141+
default='', help="prepend PREFIX to each filename in the archive")
142+
143+
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='enable verbose mode')
144+
145+
parser.add_option('--no-exclude', action='store_false', dest='exclude',
146+
default=True, help="Dont read .gitattributes files for patterns containing export-ignore attrib")
147+
148+
parser.add_option('--extra', action='append', dest='extra', default=[],
149+
help="Any additional files to include in the archive.")
150+
151+
options, args = parser.parse_args()
152+
153+
if len(args) != 1:
154+
parser.error('You must specify exactly one output file')
155+
156+
outFile = args[0]
157+
158+
if path.isdir(outFile):
159+
parser.error('You cannot use directory as output')
160+
161+
archiver = GitArchiver(options.prefix,
162+
options.verbose,
163+
options.exclude,
164+
options.extra)
165+
166+
try:
167+
archiver.create(outFile)
168+
except Exception, e:
169+
parser.exit(2, "%s\n" % e)
170+
171+
sys.exit(0)

0 commit comments

Comments
 (0)