Code

Fixed msg string
[gosa.git] / gosa-core / contrib / build-gosa
1 #!/usr/bin/env python
2 #-*- coding: utf-8 -*-
3 import os
4 import re
5 import sys
6 import shutil
7 import tarfile
8 import subprocess
9 import logging
10 from optparse import OptionParser
11 from os.path import join
12 from tempfile import mkdtemp
14 # Version setter
15 VERSION = "1.0"
16 methods = {}
19 # Check if pysvn is installed
20 try:
21     import pysvn
23     def load_svn(base_url, release, tmp_dir):
24         source = base_url + "/" + release
25         svn = pysvn.Client()
27         for part in ["gosa-core", "gosa-plugins"]:
28             print("Retrieving %s from SVN..." % part)
29             rev = svn.export(source + "/" + part, join(tmp_dir, part))
31         return "svn" + str(rev.number)
33     methods["svn"] = load_svn
34 except:
35     pass
38 def tar_extract(name, target):
39     tar = tarfile.open(name, "r:gz")
40     tar.extractall(target)
41     tar.close()
43 def tar_create(name, source):
44     tar = tarfile.open(name, "w:gz")
45     tar.add(source)
46     tar.close()
48 def build(release, base_url, target="/tmp", method="svn", key_id=None, cleanup=True, smarty=False):
50     # Absolutize target
51     target = os.path.abspath(target)
53     # Create target and temporary directory
54     try:
55         tmp_dir = mkdtemp()
56         target_dir = join(target, "gosa")
57         os.makedirs(target_dir)
59         # Get data
60         if method in methods:
61             rev = methods[method](base_url, release, tmp_dir)
62         else:
63             print("Error: method '%s' is notavailable" % method)
65         # Prepare gosa-core for archiving
66         core_dir = join(tmp_dir, "gosa", "gosa-core")
67         os.makedirs(join(tmp_dir, "gosa"))
68         shutil.move(join(tmp_dir, "gosa-core"), join(tmp_dir, "gosa"))
69         shutil.move(join(core_dir, "debian"), target_dir)
71         # Remove all but .php files provided by GOsa
72         if not smarty:
73             smarty_dir = join(core_dir, "include", "smarty")
74             for rfile in [f for f in os.listdir(join(smarty_dir, "plugins"))
75                 if not f in ["block.render.php", "block.t.php", "function.msgPool.php",
76                 "function.factory.php", "function.image.php"]]:
78                 os.remove(join(smarty_dir, "plugins", rfile))
80             for rfile in [join(smarty_dir, f) for f in os.listdir(smarty_dir)]:
81                 if os.path.basename(rfile) != "plugins":
82                     if os.path.isdir(rfile):
83                         shutil.rmtree(rfile)
84                     else:
85                         os.remove(rfile)
87             # Remove smarty3 package section
88             out = ""
89             control = join(tmp_dir, "debian", "control")
90             data = open(control, 'r')
91             remove = False
93             for line in data:
94                 line = line.strip()
95                 if line == "Package: smarty3":
96                     remove = True
97             
98                 if not remove:
99                     out += line + "\n"
101                 if remove and line == "":
102                     remove = False
104             of = open(control, 'w')
105             of.write(out)
106             of.close()
108         # Get target version number
109         version = None
110         with open(join(core_dir, "Changelog")) as f:
111             for line in f.readlines():
112                 if line.startswith("* gosa"):
113                     version = line.split(" ")[2].strip()
114                     break
116         # If we're in trunk or branches, add revision to version
117         if re.match(r"^(trunk|branches/)", release):
118             version = "%s+%s" % (version, rev)
119             os.chdir(target_dir)
120             subprocess.call(["dch", "--newversion=" + version + "-1",
121                 "--no-force-save-on-release", "Development snapshot"])
123         # Build gosa-core tar file
124         os.chdir(tmp_dir)
125         tar_create(join(target, "gosa_%s.orig.tar.gz" % version), "gosa")
127         # Clean up and build plugin archives
128         tars = []
129         os.chdir(join(tmp_dir, "gosa-plugins"))
130         for f in os.listdir(join(tmp_dir, "gosa-plugins")):
131             pth = join(target, "gosa_%s.orig-%s.tar.gz" % (version, f))
132             if os.path.exists(join(tmp_dir, "gosa-plugins", f, "plugin.dsc")):
133                 os.remove(join(tmp_dir, "gosa-plugins", f, "plugin.dsc"))
134             tar_create(pth, f)
135             tars.append(pth)
137         # Stage build directory
138         tar_extract(join(target, "gosa_%s.orig.tar.gz" % version), target)
139         for tar_file in tars:
140             tar_extract(tar_file, target_dir)
142         # Build packages
143         print("Building packages to %s" % target)
144         os.chdir(target_dir)
145         if key_id:
146             status = subprocess.call(["dpkg-buildpackage", "-k", key_id, "-rfakeroot"])
147         else:
148             status = subprocess.call(["dpkg-buildpackage", "-uc", "-us", "-rfakeroot"])
150         # Bail out?
151         if status:
152             raise Exception("Build failed: exit code %s" % status)
154     except Exception as detail:
155         print("Error:", str(detail))
157     # Cleanup
158     finally:
159         if cleanup:
160             if os.path.exists(tmp_dir):
161                 shutil.rmtree(tmp_dir)
162             if os.path.exists(target_dir):
163                 shutil.rmtree(target_dir)
165 def main():
166     # Sanity check
167     for cli, pkg in [("/usr/bin/dpkg-buildpackage", "dpkg-dev"),
168         ("/usr/bin/fakeroot", "fakeroot"),
169         ("/usr/bin/dch", "devscripts"),
170         ("/usr/bin/dh", "debhelper")]:
172         if not os.path.exists(cli):
173             print("Error: %s is missing, please install %s" % (cli, pkg))
174             exit(1)
176     # Methods available?
177     if not methods:
178         print("Error: no retrieval methods available, please install python-svn")
179         exit(1)
181     # Parse commandline options
182     op = OptionParser(usage="%prog - GOsa packaging aid",
183         version="%prog " + VERSION)
184     op.add_option("-s", "--source", dest="source",
185         default="https://oss.gonicus.de/repositories/gosa",
186         help="retrieval base path [%default]", metavar="URL")
187     op.add_option("-a", "--with-smarty", dest="smarty",
188         default=False, action="store_true",
189         help="build smarty3 packages from smarty provided by gosa source")
190     op.add_option("-t", "--target", dest="target",
191         default=".",
192         help="target directory [%default]", metavar="PATH")
193     op.add_option("-m", "--method", dest="method",
194         default="svn",
195         help="retrieval method [%default]", metavar="METHOD")
196     op.add_option("-n", "--no-cleanup", action="store_false",
197         dest="cleanup", default=True,
198         help="don't clean up temporary files")
199     op.add_option("-k", "--key-id", dest="key_id",
200         default=None,
201         help="GPG key ID used for signing if applicable", metavar="KEY_ID")
203     (options, args) = op.parse_args()
204     if len(args) != 1:
205         op.print_help()
206         exit(1)
208     # Allow version shortcut, but prepend tags/
209     release = args[0]
210     if re.match(r"^[0-9]", release):
211         release = "tags/" + release
213     # Validate release
214     if not re.match(r"^(tags/.|branches/.|trunk$)", release):
215         print("Error: release must be in the format tags/x (or just x), branches/x or trunk")
216         exit(1)
218     # Start build
219     build(release, options.source, options.target,
220         options.method, options.key_id, options.cleanup, options.smarty)
223 """ Main GOsa packaging aid """
224 if __name__ == '__main__':
225     if not sys.stdout.encoding:
226         sys.stdout = codecs.getwriter('utf8')(sys.stdout)
227     if not sys.stderr.encoding:
228         sys.stderr = codecs.getwriter('utf8')(sys.stderr)
230     main()