ldb:tests: Extend api.py testsuite to show transaction_commit() blocks against the...
[Samba.git] / buildtools / wafsamba / samba_dist.py
blobdbcb02a74d73e910dd26359591e59737a0614840
1 # customised version of 'waf dist' for Samba tools
2 # uses git ls-files to get file lists
4 import os, sys, tarfile
5 import Utils, Scripting, Logs, Options
6 from Configure import conf
7 from samba_utils import os_path_relpath
9 dist_dirs = None
10 dist_files = None
11 dist_blacklist = ""
13 def add_symlink(tar, fname, abspath, basedir):
14 '''handle symlinks to directories that may move during packaging'''
15 if not os.path.islink(abspath):
16 return False
17 tinfo = tar.gettarinfo(name=abspath, arcname=fname)
18 tgt = os.readlink(abspath)
20 if dist_dirs:
21 # we need to find the target relative to the main directory
22 # this is here to cope with symlinks into the buildtools
23 # directory from within the standalone libraries in Samba. For example,
24 # a symlink to ../../builtools/scripts/autogen-waf.sh needs
25 # to be rewritten as a symlink to buildtools/scripts/autogen-waf.sh
26 # when the tarball for talloc is built
28 # the filename without the appname-version
29 rel_fname = '/'.join(fname.split('/')[1:])
31 # join this with the symlink target
32 tgt_full = os.path.join(os.path.dirname(rel_fname), tgt)
34 # join with the base directory
35 tgt_base = os.path.normpath(os.path.join(basedir, tgt_full))
37 # see if this is inside one of our dist_dirs
38 for dir in dist_dirs.split():
39 if dir.find(':') != -1:
40 destdir=dir.split(':')[1]
41 dir=dir.split(':')[0]
42 else:
43 destdir = '.'
44 if dir == basedir:
45 # internal links don't get rewritten
46 continue
47 if dir == tgt_base[0:len(dir)] and tgt_base[len(dir)] == '/':
48 new_tgt = destdir + tgt_base[len(dir):]
49 tinfo.linkname = new_tgt
50 break
52 tinfo.uid = 0
53 tinfo.gid = 0
54 tinfo.uname = 'root'
55 tinfo.gname = 'root'
56 tar.addfile(tinfo)
57 return True
59 def add_tarfile(tar, fname, abspath, basedir):
60 '''add a file to the tarball'''
61 if add_symlink(tar, fname, abspath, basedir):
62 return
63 try:
64 tinfo = tar.gettarinfo(name=abspath, arcname=fname)
65 except OSError:
66 Logs.error('Unable to find file %s - missing from git checkout?' % abspath)
67 sys.exit(1)
68 tinfo.uid = 0
69 tinfo.gid = 0
70 tinfo.uname = 'root'
71 tinfo.gname = 'root'
72 fh = open(abspath)
73 tar.addfile(tinfo, fileobj=fh)
74 fh.close()
77 def vcs_dir_contents(path):
78 """Return the versioned files under a path.
80 :return: List of paths relative to path
81 """
82 repo = path
83 while repo != "/":
84 if os.path.isdir(os.path.join(repo, ".git")):
85 ls_files_cmd = [ 'git', 'ls-files', '--full-name',
86 os_path_relpath(path, repo) ]
87 cwd = None
88 env = dict(os.environ)
89 env["GIT_DIR"] = os.path.join(repo, ".git")
90 break
91 repo = os.path.dirname(repo)
92 if repo == "/":
93 raise Exception("unsupported or no vcs for %s" % path)
94 return Utils.cmd_output(ls_files_cmd, cwd=cwd, env=env).split()
97 def dist(appname='', version=''):
99 def add_files_to_tarball(tar, srcdir, srcsubdir, dstdir, dstsubdir, blacklist, files):
100 if blacklist is None:
101 blacklist = []
102 for f in files:
103 abspath = os.path.join(srcdir, f)
105 if srcsubdir != '.':
106 f = f[len(srcsubdir)+1:]
108 # Remove files in the blacklist
109 if f in blacklist:
110 continue
111 blacklisted = False
112 # Remove directories in the blacklist
113 for d in blacklist:
114 if f.startswith(d):
115 blacklisted = True
116 if blacklisted:
117 continue
118 if os.path.isdir(abspath):
119 continue
120 if dstsubdir != '.':
121 f = dstsubdir + '/' + f
122 fname = dstdir + '/' + f
123 add_tarfile(tar, fname, abspath, srcsubdir)
126 def list_directory_files(path):
127 curdir = os.getcwd()
128 os.chdir(srcdir)
129 out_files = []
130 for root, dirs, files in os.walk(path):
131 for f in files:
132 out_files.append(os.path.join(root, f))
133 os.chdir(curdir)
134 return out_files
137 if not isinstance(appname, str) or not appname:
138 # this copes with a mismatch in the calling arguments for dist()
139 appname = Utils.g_module.APPNAME
140 version = Utils.g_module.VERSION
141 if not version:
142 version = Utils.g_module.VERSION
144 srcdir = os.path.normpath(os.path.join(os.path.dirname(Utils.g_module.root_path), Utils.g_module.srcdir))
146 if not dist_dirs:
147 Logs.error('You must use samba_dist.DIST_DIRS() to set which directories to package')
148 sys.exit(1)
150 dist_base = '%s-%s' % (appname, version)
152 if Options.options.SIGN_RELEASE:
153 dist_name = '%s.tar' % (dist_base)
154 tar = tarfile.open(dist_name, 'w')
155 else:
156 dist_name = '%s.tar.gz' % (dist_base)
157 tar = tarfile.open(dist_name, 'w:gz')
159 blacklist = dist_blacklist.split()
161 for dir in dist_dirs.split():
162 if dir.find(':') != -1:
163 destdir=dir.split(':')[1]
164 dir=dir.split(':')[0]
165 else:
166 destdir = '.'
167 absdir = os.path.join(srcdir, dir)
168 try:
169 files = vcs_dir_contents(absdir)
170 except Exception, e:
171 Logs.error('unable to get contents of %s: %s' % (absdir, e))
172 sys.exit(1)
173 add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files)
175 if dist_files:
176 for file in dist_files.split():
177 if file.find(':') != -1:
178 destfile = file.split(':')[1]
179 file = file.split(':')[0]
180 else:
181 destfile = file
183 absfile = os.path.join(srcdir, file)
185 if os.path.isdir(absfile):
186 destdir = destfile
187 dir = file
188 files = list_directory_files(dir)
189 add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files)
190 else:
191 fname = dist_base + '/' + destfile
192 add_tarfile(tar, fname, absfile, destfile)
194 tar.close()
196 if Options.options.SIGN_RELEASE:
197 import gzip
198 try:
199 os.unlink(dist_name + '.asc')
200 except OSError:
201 pass
203 cmd = "gpg --detach-sign --armor " + dist_name
204 os.system(cmd)
205 uncompressed_tar = open(dist_name, 'rb')
206 compressed_tar = gzip.open(dist_name + '.gz', 'wb')
207 while 1:
208 buffer = uncompressed_tar.read(1048576)
209 if buffer:
210 compressed_tar.write(buffer)
211 else:
212 break
213 uncompressed_tar.close()
214 compressed_tar.close()
215 os.unlink(dist_name)
216 Logs.info('Created %s.gz %s.asc' % (dist_name, dist_name))
217 dist_name = dist_name + '.gz'
218 else:
219 Logs.info('Created %s' % dist_name)
221 return dist_name
224 @conf
225 def DIST_DIRS(dirs):
226 '''set the directories to package, relative to top srcdir'''
227 global dist_dirs
228 if not dist_dirs:
229 dist_dirs = dirs
231 @conf
232 def DIST_FILES(files, extend=False):
233 '''set additional files for packaging, relative to top srcdir'''
234 global dist_files
235 if not dist_files:
236 dist_files = files
237 elif extend:
238 dist_files = dist_files + " " + files
240 @conf
241 def DIST_BLACKLIST(blacklist):
242 '''set the files to exclude from packaging, relative to top srcdir'''
243 global dist_blacklist
244 if not dist_blacklist:
245 dist_blacklist = blacklist
247 Scripting.dist = dist