2 import vcs, build_system, imp
3 import argparse, os, sys, subprocess
4 from collections import OrderedDict
6 # read command-line arguments
7 parser = argparse.ArgumentParser(description='Update and build a bunch of stuff')
8 parser.add_argument("-c, --config",
9 dest="config", default="mass-build.conf",
10 help="mass-build config file")
11 parser.add_argument("--reconfigure",
12 action="store_true", dest="reconfigure",
13 help="Force configuration to be run")
14 parser.add_argument("--no-update",
15 action="store_false", dest="update",
16 help="Do not update modules before compilation")
17 parser.add_argument("--resume-from", metavar='MODULE',
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()
25 config = imp.load_source('config', args.config).__dict__
26 os.remove(args.config+'c') # remove compiled python file
27 projects = OrderedDict() # all projects
28 workProjects = [] # projects we work on
32 def __init__(self, config, folder, module):
34 self.name = module['name']
36 vcsName = module['vcs']
38 self.vcs = vcs.Git(self.sourceFolder(), module['url'], module['version'])
39 elif vcsName == 'svn':
40 self.vcs = vcs.SVN(self.sourceFolder(), module['url'], module.get('versionName'))
42 raise Exception("Unknown VCS type "+vcsName)
44 if config.get('buildDeb', False):
45 self.buildSystem = build_system.AutoDebuild(self.sourceFolder(), self.buildFolder(), module, self.vcs, config)
47 buildSystemName = module['buildSystem']
48 if buildSystemName == 'cmake':
49 self.buildSystem = build_system.CMake(self.sourceFolder(), self.buildFolder(), module, config)
51 raise Exception("Unknown build system type "+buildSystemName)
53 def sourceFolder(self):
54 return os.path.join(self.folder, self.name)
56 def buildFolder(self):
57 return os.path.join(config['buildDir'], self.sourceFolder())
59 # return the position of the given item in the list
60 def findInList(list, item):
61 for i in xrange(len(list)):
64 raise Exception("%s not found in list" % str(item))
66 # populate list of projects
67 def loadProjects(config, modules, folder=''):
68 for module in modules:
69 if 'folder' in module: # a subpath
70 loadProjects(config, module['modules'], os.path.join(folder, module['folder']))
71 else: # a proper project
72 if module['name'] in projects:
73 raise Exception("Duplicate module name "+module['name'])
74 projects[module['name']] = Project(config, folder, module)
76 # now check what we have to do
77 loadProjects(config, config['modules'])
79 if args.resume_from is not None:
80 raise Exception("Can not use --resume-from and manually specify modules")
81 for module in args.modules:
82 if not module in projects:
83 raise Exception("Project %s does not exist" % module)
84 workProjects.append(projects[module])
85 elif args.resume_from is None:
86 workProjects = projects.values() # all the projects
88 if not args.resume_from in projects:
89 raise Exception("Project %s does not exist" % args.resume_from)
90 startWith = projects[args.resume_from]
91 startIndex = findInList(projects.values(), startWith)
92 workProjects = projects.values()[startIndex:]
95 for project in workProjects:
98 print "Updating module",project.sourceFolder()
100 print "Building module",project.sourceFolder()
101 project.buildSystem.build(reconfigure=args.reconfigure)
103 except (subprocess.CalledProcessError, KeyboardInterrupt) as e:
106 if isinstance(e, KeyboardInterrupt): # str(e) would be the empty string
107 print >> sys.stderr, "Interruped by user while processing %s" % (project.name)
109 print >> sys.stderr, "Error while processing %s: %s" % (project.name, str(e))