#!/usr/bin/python -u import sys import argparse from sets import Set from os.path import expanduser import re def re_section(name): return re.compile('[' + name + ']' '.*?' '(?=[)', re.DOTALL) # --------------------------------------------------------------------- helpers def proj_dir(name): return projs_root + '/' + name def strip_module_from_spec(mod): return re.sub(r'-devel$|-run$', '', re.split('([=><]+)', mod)[0].strip()) def get_section(path, section): r = '' file = open(path) pat = '[' + section + ']' in_section = False for line in file: if (line.rstrip() == pat): in_section = True continue if in_section: if len(line) and line[0] == '[': break r = r + line file.close() return r.rstrip() def get_value(name, section, key): proj_root = proj_dir(name) dirs = [] if topdir: dirs.append(topdir) dirs.append(projs_root + '/' + name) if section == 'version': for d in dirs: with open(d + '/VERSION', 'r') as file: r=file.read().replace('\n', '').replace('-dev', '') file.close() return r raise Exception("failed to find version of " + name) dirs = [] if topdir: dirs.append(topdir) dirs.append(projs_root + '/' + name) for conf in [ '/make/project.conf', '/doc/share/project.txt' ]: for d in dirs: path = d + conf r = () try: file = open(path) except: continue if not len(section): for line in file: r = re.findall('^ *' + key + ' *= *(.*)', line) if (len(r) > 0): break else: in_section = False pat = '[' + section + ']' for line in file: if (line.rstrip() == pat): in_section = True continue if in_section: if len(line) and line[0] == '[': break r = re.findall('^ *' + key + ' *= *(.*)', line) if (len(r) > 0): break file.close() if len(r): return r[0] return '' return None # scope 0: no children # scope 1: children # scope 2: recursive def add_modules_from_project_txt(buf, spec, section, key, add_self, scope, names_only): name = strip_module_from_spec(spec) if names_only: spec = name if spec in buf: return deps = get_value(name, section, key) if deps and scope > 0: if scope == 1: subscope = 0 else: subscope = 2 deps = deps.split(',') for dep in deps: add_modules_from_project_txt(buf, dep, section, key, add_self=True, scope=subscope, names_only=names_only) if add_self: buf.append(spec) def get_modules_from_project_txt(names, section, key, add_self, scope, names_only = True): #r = Set() r = [] for name in names: add_modules_from_project_txt(r, name, section, key, add_self, scope, names_only) return r def get_libname(names): vals = get_modules_from_project_txt(names, 'build', 'libname', scope = 1, add_self=False, names_only=True) if not vals: return ' '.join(names) if 'none' in vals: vals.remove('none') return ' '.join(reversed(vals)) def get_ldflags(names): deps = get_modules_from_project_txt(names, 'pkg.required', 'build', scope = 1, add_self=True, names_only=True) r = '' for m in reversed(deps): libname = get_libname([m]) if len(libname): r = r + ' -L' + proj_dir(m) + '/lib -l' + libname if len(r): return r[1::] return '' # --------------------------------------------------------------------- commands def cmd_test(args_): parser = argparse.ArgumentParser(description='Test') parser.add_argument('blah', default='', help='The blah argument') args=parser.parse_args(args_) print "blah = " + args.blah def cmd_ldlibpath(args_): parser = argparse.ArgumentParser(description='ldlibpath') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) deps = get_modules_from_project_txt(args.module, 'pkg.required', 'run', scope = 2, add_self=True, names_only=True) r = '' for m in deps: r = r + ':' + proj_dir(m) + '/lib' print r[1:] def cmd_libname(args_): parser = argparse.ArgumentParser(description='libname') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) print get_libname(args.module) def cmd_ldflags(args_): parser = argparse.ArgumentParser(description='ldlibpath') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) print get_ldflags(args.module) def cmd_cflags(args_): parser = argparse.ArgumentParser(description='ldlibpath') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) deps = get_modules_from_project_txt(args.module, 'pkg.required', 'build', scope = 1, add_self=True, names_only=True) r = '' for m in reversed(deps): r = r + ' -I' + proj_dir(m) + '/include' print r[1:] def cmd_path(args_): parser = argparse.ArgumentParser(description='path') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) deps = get_modules_from_project_txt(args.module, 'pkg.required', 'run', scope = 2, add_self=True, names_only=True) r = '' for m in deps: r = r + ':' + proj_dir(m) + '/bin' print r[1:] def cmd_pkg_requires(args_): parser = argparse.ArgumentParser(description='pkg-requires') parser.add_argument('flavour', help='Flavour') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) r = [] for m in args.module: deps = get_value(m, 'pkg.required', args.flavour).split(',') for spec in deps: dep = re.split('([=><]+)', spec) for i, item in enumerate(dep): dep[i] = item.strip() if len(dep) == 3: dep_project = re.sub(r'-devel$|-run$', '', dep[0]) version = get_value(dep_project, 'version', '') if dep[2] == 'VERSION': dep[2] = version.split('-')[0] elif dep[2] == 'VERSION-REVISION': dep[2] = version else: raise Exception("Unknown version specifier in " + spec) r.append(' '.join(dep)) print ', '.join(r) def cmd_proj_dir(args_): parser = argparse.ArgumentParser(description='proj-dir') parser.add_argument('module', nargs='*', help='Modules') args=parser.parse_args(args_) r = [] for m in args.module: r.append(proj_dir(m)) print ' '.join(r) # -------------------------------------------------------------------- here we go global_args = [] skip = 0 for a in sys.argv[1::]: global_args.append(a) if a in [ '--prefix', '-p', '--topdir', '-t' ]: skip = 1 continue if skip > 0: skip = skip -1 continue if a[0] != '-': break parser = argparse.ArgumentParser(description='Project metadata evaluation') parser.add_argument('cmd', default='', help='Command') parser.add_argument('--topdir', '-t', nargs='?', help='Project Path') parser.add_argument('--prefix', '-p', nargs='?', default = expanduser("~") + '/local/src/cvs.stable/proj', help='Projects Path Prefix') parser.add_argument('arg', nargs='*', help='Command arguments') args=parser.parse_args(global_args) projs_root = args.prefix topdir = args.topdir cmd = getattr(sys.modules[__name__], 'cmd_' + args.cmd.replace('-', '_')) cmd(sys.argv[(len(global_args) + 1)::])