+#!/usr/bin/python
+import vcs, build_system, imp
+import argparse, os, sys, subprocess
+from collections import OrderedDict
+
+# read command-line arguments
+parser = argparse.ArgumentParser(description='Build KDE')
+parser.add_argument("-c, --config",
+ dest="config", default="config.py",
+ help="kdebuildpy config file")
+parser.add_argument("--reconfigure",
+ action="store_true", dest="reconfigure",
+ help="Force configuration to be run")
+parser.add_argument("--phases", choices=["update", "configure", "compile"], nargs='*', metavar='PHASE',
+ dest="phases", default=["update", "configure", "compile"],
+ help="For each module, run the given phases in the given order. Possible phases are: update, configure, compile")
+parser.add_argument("--resume-from", metavar='MODULE',
+ dest="resume_from",
+ help="Resume building from the given repository")
+parser.add_argument("modules", metavar='MODULE', nargs='*',
+ help="Manually specify modules to be built")
+args = parser.parse_args()
+
+# load config
+config = imp.load_source('config', args.config)
+
+# template for a KDE project: combine git/svn with cmake
+def sourceFolder(module):
+ return os.path.join(module['in-folder'], module['name'])
+def buildFolder(module):
+ return os.path.join(config.buildDir, sourceFolder(module))
+
+class KDEGitProject(vcs.Git, build_system.CMake):
+ def __init__(self, module):
+ vcs.Git.__init__(self, sourceFolder(module),'kde:'+module['name'], module['version'])
+ build_system.CMake.__init__(self, sourceFolder(module), buildFolder(module), config)
+ self.name = module['name']
+
+class KDESVNProject(vcs.SVN, build_system.CMake):
+ def __init__(self, module):
+ vcs.SVN.__init__(self, sourceFolder(module), 'svn://svn.kde.org/home/kde/'+module['svn-path'])
+ build_system.CMake.__init__(self, sourceFolder(module), buildFolder(module), config)
+ self.name = module['name']
+
+moduleTypes = {
+ 'kde+git': KDEGitProject,
+ 'kde+svn': KDESVNProject
+}
+
+# return the position of the given item in the list
+def findInList(list, item):
+ for i in xrange(len(list)):
+ if list[i] == item:
+ return i
+ raise Exception("%s not found in list" % str(item))
+
+# collect list of projects (separate run, since the actual compilation will change the working directory!)
+projects = OrderedDict()
+for module in config.modules:
+ if module['name'] in projects:
+ raise Exception("Duplicate module name "+module['name'])
+ if not module['type'] in moduleTypes:
+ raise Exception("Invalid module type "+module['type'])
+ projects[module['name']] = moduleTypes[module['type']](module) # create module of proper type
+
+# now check what we have to do
+workProjects = []
+if args.modules:
+ if args.resume_from is not None:
+ raise Exception("Can not use --resume-from and manually specify modules")
+ for module in args.modules:
+ if not module in projects:
+ raise Exception("Project %s does not exist" % module)
+ workProjects.append(projects[module])
+elif args.resume_from is None: workProjects = projects.values() # all the projects
+else:
+ if not args.resume_from in projects:
+ raise Exception("Project %s does not exist" % args.resume_from)
+ startWith = projects[args.resume_from]
+ startIndex = findInList(projects.values(), startWith)
+ workProjects = projects.values()[startIndex:]
+
+# and do it!
+for project in workProjects:
+ try:
+ for phase in args.phases:
+ if phase == 'update':
+ project.update()
+ elif phase == 'configure':
+ project.configure(force=args.reconfigure)
+ elif phase == 'compile':
+ project.build()
+ project.install()
+ else:
+ raise Exception("Invalid phase "+phase)
+ except (subprocess.CalledProcessError, KeyboardInterrupt) as e:
+ print >> sys.stderr
+ print >> sys.stderr
+ if isinstance(e, KeyboardInterrupt): # str(e) would be the empty string
+ print >> sys.stderr, "Interruped by user while processing %s" % (project.name)
+ else:
+ print >> sys.stderr, "Error while processing %s: %s" % (project.name, str(e))
+ print >> sys.stderr
+ sys.exit(1)