smbd: Remove unused [push_pull]_file_id_24
[samba.git] / buildtools / wafsamba / samba_dist.py
1 # customised version of 'waf dist' for Samba tools
2 # uses git ls-files to get file lists
3
4 import Utils, os, sys, tarfile, stat, Scripting, Logs, Options
5 from samba_utils import *
6
7 dist_dirs = None
8 dist_blacklist = ""
9
10 def add_symlink(tar, fname, abspath, basedir):
11     '''handle symlinks to directories that may move during packaging'''
12     if not os.path.islink(abspath):
13         return False
14     tinfo = tar.gettarinfo(name=abspath, arcname=fname)
15     tgt = os.readlink(abspath)
16
17     if dist_dirs:
18         # we need to find the target relative to the main directory
19         # this is here to cope with symlinks into the buildtools
20         # directory from within the standalone libraries in Samba. For example,
21         # a symlink to ../../builtools/scripts/autogen-waf.sh needs
22         # to be rewritten as a symlink to buildtools/scripts/autogen-waf.sh
23         # when the tarball for talloc is built
24
25         # the filename without the appname-version
26         rel_fname = '/'.join(fname.split('/')[1:])
27
28         # join this with the symlink target
29         tgt_full = os.path.join(os.path.dirname(rel_fname), tgt)
30
31         # join with the base directory
32         tgt_base = os.path.normpath(os.path.join(basedir, tgt_full))
33
34         # see if this is inside one of our dist_dirs
35         for dir in dist_dirs.split():
36             if dir.find(':') != -1:
37                 destdir=dir.split(':')[1]
38                 dir=dir.split(':')[0]
39             else:
40                 destdir = '.'
41             if dir == basedir:
42                 # internal links don't get rewritten
43                 continue
44             if dir == tgt_base[0:len(dir)] and tgt_base[len(dir)] == '/':
45                 new_tgt = destdir + tgt_base[len(dir):]
46                 tinfo.linkname = new_tgt
47                 break
48
49     tinfo.uid   = 0
50     tinfo.gid   = 0
51     tinfo.uname = 'root'
52     tinfo.gname = 'root'
53     tar.addfile(tinfo)
54     return True
55
56 def add_tarfile(tar, fname, abspath, basedir):
57     '''add a file to the tarball'''
58     if add_symlink(tar, fname, abspath, basedir):
59         return
60     try:
61         tinfo = tar.gettarinfo(name=abspath, arcname=fname)
62     except OSError:
63         Logs.error('Unable to find file %s - missing from git checkout?' % abspath)
64         sys.exit(1)
65     tinfo.uid   = 0
66     tinfo.gid   = 0
67     tinfo.uname = 'root'
68     tinfo.gname = 'root'
69     fh = open(abspath)
70     tar.addfile(tinfo, fileobj=fh)
71     fh.close()
72
73
74 def vcs_dir_contents(path):
75     """Return the versioned files under a path.
76
77     :return: List of paths relative to path
78     """
79     repo = path
80     while repo != "/":
81         if os.path.isdir(os.path.join(repo, ".git")):
82             ls_files_cmd = [ 'git', 'ls-files', '--full-name',
83                              os_path_relpath(path, repo) ]
84             cwd = None
85             env = dict(os.environ)
86             env["GIT_DIR"] = os.path.join(repo, ".git")
87             break
88         elif os.path.isdir(os.path.join(repo, ".bzr")):
89             ls_files_cmd = [ 'bzr', 'ls', '--recursive', '--versioned',
90                              os_path_relpath(path, repo)]
91             cwd = repo
92             env = None
93             break
94         repo = os.path.dirname(repo)
95     if repo == "/":
96         raise Exception("unsupported or no vcs for %s" % path)
97     return Utils.cmd_output(ls_files_cmd, cwd=cwd, env=env).split()
98
99
100 def dist(appname='',version=''):
101     if not isinstance(appname, str) or not appname:
102         # this copes with a mismatch in the calling arguments for dist()
103         appname = Utils.g_module.APPNAME
104         version = Utils.g_module.VERSION
105     if not version:
106         version = Utils.g_module.VERSION
107
108     srcdir = os.path.normpath(os.path.join(os.path.dirname(Utils.g_module.root_path), Utils.g_module.srcdir))
109
110     if not dist_dirs:
111         Logs.error('You must use samba_dist.DIST_DIRS() to set which directories to package')
112         sys.exit(1)
113
114     dist_base = '%s-%s' % (appname, version)
115
116     if Options.options.SIGN_RELEASE:
117         dist_name = '%s.tar' % (dist_base)
118         tar = tarfile.open(dist_name, 'w')
119     else:
120         dist_name = '%s.tar.gz' % (dist_base)
121         tar = tarfile.open(dist_name, 'w:gz')
122
123     blacklist = dist_blacklist.split()
124
125     for dir in dist_dirs.split():
126         if dir.find(':') != -1:
127             destdir=dir.split(':')[1]
128             dir=dir.split(':')[0]
129         else:
130             destdir = '.'
131         absdir = os.path.join(srcdir, dir)
132         try:
133             files = vcs_dir_contents(absdir)
134         except Exception, e:
135             Logs.error('unable to get contents of %s: %s' % (absdir, e))
136             sys.exit(1)
137         for f in files:
138             abspath = os.path.join(srcdir, f)
139
140             if dir != '.':
141                 f = f[len(dir)+1:]
142
143             # Remove files in the blacklist
144             if f in dist_blacklist:
145                 continue
146             blacklisted = False
147             # Remove directories in the blacklist
148             for d in blacklist:
149                 if f.startswith(d):
150                     blacklisted = True
151             if blacklisted:
152                 continue
153             if os.path.isdir(abspath):
154                 continue
155             if destdir != '.':
156                 f = destdir + '/' + f
157             fname = dist_base + '/' + f
158             add_tarfile(tar, fname, abspath, dir)
159
160     tar.close()
161
162     if Options.options.SIGN_RELEASE:
163         import gzip
164         try:
165             os.unlink(dist_name + '.asc')
166         except OSError:
167             pass
168
169         cmd = "gpg --detach-sign --armor " + dist_name
170         os.system(cmd)
171         uncompressed_tar = open(dist_name, 'rb')
172         compressed_tar = gzip.open(dist_name + '.gz', 'wb')
173         while 1:
174             buffer = uncompressed_tar.read(1048576)
175             if buffer:
176                 compressed_tar.write(buffer)
177             else:
178                 break
179         uncompressed_tar.close()
180         compressed_tar.close()
181         os.unlink(dist_name)
182         Logs.info('Created %s.gz %s.asc' % (dist_name, dist_name))
183         dist_name = dist_name + '.gz'
184     else:
185         Logs.info('Created %s' % dist_name)
186
187     return dist_name
188
189
190 @conf
191 def DIST_DIRS(dirs):
192     '''set the directories to package, relative to top srcdir'''
193     global dist_dirs
194     if not dist_dirs:
195         dist_dirs = dirs
196
197 @conf
198 def DIST_BLACKLIST(blacklist):
199     '''set the files to exclude from packaging, relative to top srcdir'''
200     global dist_blacklist
201     if not dist_blacklist:
202         dist_blacklist = blacklist
203
204 Scripting.dist = dist