s4:s3compat Don't load or compile auth modules from source3
[abartlet/samba.git/.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, gzip, 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 dist(appname='',version=''):
75     if not isinstance(appname, str) or not appname:
76         # this copes with a mismatch in the calling arguments for dist()
77         appname = Utils.g_module.APPNAME
78         version = Utils.g_module.VERSION
79     if not version:
80         version = Utils.g_module.VERSION
81
82     srcdir = os.path.normpath(os.path.join(os.path.dirname(Utils.g_module.root_path), Utils.g_module.srcdir))
83
84     if not dist_dirs:
85         Logs.error('You must use samba_dist.DIST_DIRS() to set which directories to package')
86         sys.exit(1)
87
88     dist_base = '%s-%s' % (appname, version)
89
90     if Options.options.SIGN_RELEASE:
91         dist_name = '%s.tar' % (dist_base)
92         tar = tarfile.open(dist_name, 'w')
93     else:
94         dist_name = '%s.tar.gz' % (dist_base)
95         tar = tarfile.open(dist_name, 'w:gz')
96
97     blacklist = dist_blacklist.split()
98
99     for dir in dist_dirs.split():
100         if dir.find(':') != -1:
101             destdir=dir.split(':')[1]
102             dir=dir.split(':')[0]
103         else:
104             destdir = '.'
105         absdir = os.path.join(srcdir, dir)
106         git_cmd = [ 'git', 'ls-files', '--full-name', absdir ]
107         try:
108             files = Utils.cmd_output(git_cmd).split()
109         except:
110             Logs.error('git command failed: %s' % ' '.join(git_cmd))
111             sys.exit(1)
112         for f in files:
113             abspath = os.path.join(srcdir, f)
114             if dir != '.':
115                 f = f[len(dir)+1:]
116
117             # Remove files in the blacklist
118             if f in dist_blacklist:
119                 continue
120             blacklisted = False
121             # Remove directories in the blacklist
122             for d in blacklist:
123                 if f.startswith(d):
124                     blacklisted = True
125             if blacklisted:
126                 continue
127             if destdir != '.':
128                 f = destdir + '/' + f
129             fname = dist_base + '/' + f
130             add_tarfile(tar, fname, abspath, dir)
131
132     tar.close()
133
134     if Options.options.SIGN_RELEASE:
135         try:
136             os.unlink(dist_name + '.asc')
137         except OSError:
138             pass
139
140         cmd = "gpg --detach-sign --armor " + dist_name
141         os.system(cmd)
142         uncompressed_tar = open(dist_name, 'rb')
143         compressed_tar = gzip.open(dist_name + '.gz', 'wb')
144         while 1:
145             buffer = uncompressed_tar.read(1048576)
146             if buffer:
147                 compressed_tar.write(buffer)
148             else:
149                 break
150         uncompressed_tar.close()
151         compressed_tar.close()
152         os.unlink(dist_name)
153         Logs.info('Created %s.gz %s.asc' % (dist_name, dist_name))
154         dist_name = dist_name + '.gz'
155     else:
156         Logs.info('Created %s' % dist_name)
157
158     return dist_name
159
160
161 @conf
162 def DIST_DIRS(dirs):
163     '''set the directories to package, relative to top srcdir'''
164     global dist_dirs
165     if not dist_dirs:
166         dist_dirs = dirs
167
168 @conf
169 def DIST_BLACKLIST(blacklist):
170     '''set the directories to package, relative to top srcdir'''
171     global dist_blacklist
172     if not dist_blacklist:
173         dist_blacklist = blacklist
174
175 Scripting.dist = dist