720c96b73f259785176cc401d6830a090d5e44a0
[mass-build.git] / kdebuildpy.py
1 #!/usr/bin/python
2 import vcs, build_system, imp
3 import argparse, os, sys, subprocess
4 from collections import OrderedDict
5
6 # read command-line arguments
7 parser = argparse.ArgumentParser(description='Build KDE')
8 parser.add_argument("-c, --config",
9                     dest="config", default="config.py",
10                     help="kdebuildpy config file")
11 parser.add_argument("--reconfigure",
12                     action="store_true", dest="reconfigure",
13                     help="Force configuration to be run")
14 parser.add_argument("--phases", choices=["update", "configure", "compile"], nargs='*', metavar='PHASE',
15                     dest="phases", default=["update", "configure", "compile"],
16                     help="For each module, run the given phases in the given order. Possible phases are: update, configure, compile")
17 parser.add_argument("--resume-from", metavar='MODULE',
18                     dest="resume_from",
19                     help="Resume building from the given repository")
20 parser.add_argument("modules",  metavar='MODULE', nargs='*',
21                     help="Manually specify modules to be built")
22 args = parser.parse_args()
23
24 # load config
25 config = imp.load_source('config', args.config)
26
27 # template for a KDE project: combine git/svn with cmake
28 def sourceFolder(module):
29         return os.path.join(module['in-folder'], module['name'])
30 def buildFolder(module):
31         return os.path.join(config.buildDir, sourceFolder(module))
32
33 class KDEGitProject(vcs.Git, build_system.CMake):
34         def __init__(self, module):
35                 vcs.Git.__init__(self, sourceFolder(module),'kde:'+module['name'], module['version'])
36                 build_system.CMake.__init__(self, sourceFolder(module), buildFolder(module), config)
37                 self.name = module['name']
38
39 class KDESVNProject(vcs.SVN, build_system.CMake):
40         def __init__(self, module):
41                 vcs.SVN.__init__(self, sourceFolder(module), 'svn://svn.kde.org/home/kde/'+module['svn-path'])
42                 build_system.CMake.__init__(self, sourceFolder(module), buildFolder(module), config)
43                 self.name = module['name']
44
45 moduleTypes = {
46         'kde+git': KDEGitProject,
47         'kde+svn': KDESVNProject
48 }
49
50 # return the position of the given item in the list
51 def findInList(list, item):
52         for i in xrange(len(list)):
53                 if list[i] == item:
54                         return i
55         raise Exception("%s not found in list" % str(item))
56
57 # collect list of projects (separate run, since the actual compilation will change the working directory!)
58 projects = OrderedDict()
59 for module in config.modules:
60         if module['name'] in projects:
61                 raise Exception("Duplicate module name "+module['name'])
62         if not module['type'] in moduleTypes:
63                 raise Exception("Invalid module type "+module['type'])
64         projects[module['name']] = moduleTypes[module['type']](module) # create module of proper type
65
66 # now check what we have to do
67 workProjects = []
68 if args.modules:
69         if args.resume_from is not None:
70                 raise Exception("Can not use --resume-from and manually specify modules")
71         for module in args.modules:
72                 if not module in projects:
73                         raise Exception("Project %s does not exist" % module)
74                 workProjects.append(projects[module])
75 elif args.resume_from is None: workProjects = projects.values() # all the projects
76 else:
77         if not args.resume_from in projects:
78                 raise Exception("Project %s does not exist" % args.resume_from)
79         startWith = projects[args.resume_from]
80         startIndex = findInList(projects.values(), startWith)
81         workProjects = projects.values()[startIndex:]
82
83 # and do it!
84 for project in workProjects:
85         try:
86                 for phase in args.phases:
87                         if phase == 'update':
88                                 project.update()
89                         elif phase == 'configure':
90                                 project.configure(force=args.reconfigure)
91                         elif phase == 'compile':
92                                 project.build()
93                                 project.install()
94                         else:
95                                 raise Exception("Invalid phase "+phase)
96         except (subprocess.CalledProcessError, KeyboardInterrupt) as e:
97                 print >> sys.stderr
98                 print >> sys.stderr
99                 if isinstance(e, KeyboardInterrupt): # str(e) would be the empty string
100                         print >> sys.stderr, "Interruped by user while processing %s" % (project.name)
101                 else:
102                         print >> sys.stderr, "Error while processing %s: %s" % (project.name, str(e))
103                 print >> sys.stderr
104                 sys.exit(1)