Code

Added trigger
[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):
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         smarty_dir = join(core_dir, "include", "smarty")
73         for rfile in [f for f in os.listdir(join(smarty_dir, "plugins"))
74             if not f in ["block.render.php", "block.t.php", "function.msgPool.php",
75             "function.factory.php", "function.image.php"]]:
77             os.remove(join(smarty_dir, "plugins", rfile))
79         for rfile in [join(smarty_dir, f) for f in os.listdir(smarty_dir)]:
80             if os.path.basename(rfile) != "plugins":
81                 if os.path.isdir(rfile):
82                     shutil.rmtree(rfile)
83                 else:
84                     os.remove(rfile)
86         # Get target version number
87         version = None
88         with open(join(core_dir, "Changelog")) as f:
89             for line in f.readlines():
90                 if line.startswith("* gosa"):
91                     version = line.split(" ")[2].strip()
92                     break
94         # If we're in trunk or branches, add revision to version
95         if re.match(r"^(trunk|branches/)", release):
96             version = "%s+%s" % (version, rev)
97             os.chdir(target_dir)
98             subprocess.call(["dch", "--newversion=" + version + "-1",
99                 "--no-force-save-on-release", "Development snapshot"])
101         # Build gosa-core tar file
102         os.chdir(tmp_dir)
103         tar_create(join(target, "gosa_%s.orig.tar.gz" % version), "gosa")
105         # Clean up and build plugin archives
106         tars = []
107         os.chdir(join(tmp_dir, "gosa-plugins"))
108         for f in os.listdir(join(tmp_dir, "gosa-plugins")):
109             pth = join(target, "gosa_%s.orig-%s.tar.gz" % (version, f))
110             if os.path.exists(join(tmp_dir, "gosa-plugins", f, "plugin.dsc")):
111                 os.remove(join(tmp_dir, "gosa-plugins", f, "plugin.dsc"))
112             tar_create(pth, f)
113             tars.append(pth)
115         # Stage build directory
116         tar_extract(join(target, "gosa_%s.orig.tar.gz" % version), target)
117         for tar_file in tars:
118             tar_extract(tar_file, target_dir)
120         # Build packages
121         print("Building packages to %s" % target)
122         os.chdir(target_dir)
123         if key_id:
124             status = subprocess.call(["dpkg-buildpackage", "-k", key_id, "-rfakeroot"])
125         else:
126             status = subprocess.call(["dpkg-buildpackage", "-uc", "-us", "-rfakeroot"])
128         # Bail out?
129         if status:
130             raise Exception("Build failed: exit code %s" % status)
132     except Exception as detail:
133         print("Error:", str(detail))
135     # Cleanup
136     finally:
137         if cleanup:
138             if os.path.exists(tmp_dir):
139                 shutil.rmtree(tmp_dir)
140             if os.path.exists(target_dir):
141                 shutil.rmtree(target_dir)
143 def main():
144     # Sanity check
145     for cli, pkg in [("/usr/bin/dpkg-buildpackage", "dpkg-dev"),
146         ("/usr/bin/fakeroot", "fakeroot"),
147         ("/usr/bin/dch", "devscripts"),
148         ("/usr/bin/dh", "debhelper")]:
150         if not os.path.exists(cli):
151             print("Error: %s is missing, please install %s" % (cli, pkg))
152             exit(1)
154     # Methods available?
155     if not methods:
156         print("Error: no retrieval methods available, please install python-svn")
157         exit(1)
159     # Parse commandline options
160     op = OptionParser(usage="%prog - GOsa packaging aid",
161         version="%prog " + VERSION)
162     op.add_option("-s", "--source", dest="source",
163         default="https://oss.gonicus.de/repositories/gosa",
164         help="retrieval base path [%default]", metavar="URL")
165     op.add_option("-t", "--target", dest="target",
166         default=".",
167         help="target directory [%default]", metavar="PATH")
168     op.add_option("-m", "--method", dest="method",
169         default="svn",
170         help="retrieval method [%default]", metavar="METHOD")
171     op.add_option("-n", "--no-cleanup", action="store_false",
172         dest="cleanup", default=True,
173         help="don't clean up temporary files")
174     op.add_option("-k", "--key-id", dest="key_id",
175         default=None,
176         help="GPG key ID used for signing if applicable", metavar="KEY_ID")
178     (options, args) = op.parse_args()
179     if len(args) != 1:
180         op.print_help()
181         exit(1)
183     # Allow version shortcut, but prepend tags/
184     release = args[0]
185     if re.match(r"^[0-9]", release):
186         release = "tags/" + release
188     # Validate release
189     if not re.match(r"^(tags/.|branches/.|trunk$)", release):
190         print("Error: release must be in the format tags/x (or just x), branches/x or trunk")
191         exit(1)
193     # Start build
194     build(release, options.source, options.target,
195         options.method, options.key_id, options.cleanup)
198 """ Main GOsa packaging aid """
199 if __name__ == '__main__':
200     if not sys.stdout.encoding:
201         sys.stdout = codecs.getwriter('utf8')(sys.stdout)
202     if not sys.stderr.encoding:
203         sys.stderr = codecs.getwriter('utf8')(sys.stderr)
205     main()