bh@234: # Copyright (C) 2007, 2008, 2009 by Intevation GmbH bh@0: # Authors: bh@0: # Bernhard Herzog bh@0: # bh@0: # This program is free software under the GPL (>=v2) bh@0: # Read the file COPYING coming with the software for details. bh@0: bh@0: """Reads the configuration file""" bh@0: bh@0: import sys bh@2: import shlex bh@0: from ConfigParser import SafeConfigParser, NoOptionError bh@0: bh@4: import util bh@114: import packager bh@4: bh@129: def convert_bool(s): bh@129: s = s.lower() bh@129: if s in ("true", "yes", "1"): bh@129: return True bh@129: if s in ("false", "no", "0"): bh@129: return False bh@129: raise ValueError("cannot determine boolean value of %r" % (s,)) bh@129: bh@0: bh@304: def convert_subversion_subset(raw): bh@304: """Converts the string representation an svn subset into internal form bh@304: The format in the config file is typically: bh@304: svn_url: svn://example.com/repository/trunk bh@304: svn_subset: -N . bh@304: subdir1 bh@304: subdir2 bh@304: bh@304: Each line of the svn_subset value consists of an optional flag bh@304: followed by a subdirectory. Empty lines are ignored. Each bh@304: non-empty line is split into words using shlex.split, so whitespace bh@304: characters can be included in filenames using e.g. quotes (see the bh@304: shlex documentation for details). The only flag supported is -N bh@304: which indicates that the subdirectory on that line is not to be bh@304: checked out recursively. If -N is given on a line, svn checkout bh@304: will be called with -N as parameter. bh@304: bh@304: The example above will be converted into the internal form [('.', bh@304: False), ('subdir1', True), ('subdir2', True)] used by the bh@304: treepkg.subversion module. bh@304: """ bh@304: subset = [] bh@304: for line in raw.splitlines(): bh@304: split = shlex.split(line) bh@304: if len(split) < 1: bh@304: # ignore empty lines bh@304: continue bh@304: subdir = split[-1] bh@304: recurse = True bh@304: flags = split[:-1] bh@304: if flags: bh@304: if flags == ["-N"]: bh@304: recurse = False bh@304: else: bh@304: raise ValueError("Only -N is supported as flag, but flags = %r" bh@304: % (flags,)) bh@304: subset.append((subdir, recurse)) bh@304: return subset bh@304: bh@304: bh@2: packager_desc = [ bh@304: "name", "base_dir", aheinecke@321: ("svn_url", str,""), aheinecke@321: ("svn_subset", convert_subversion_subset, ""), bh@306: ("svn_externals", shlex.split, ""), bh@304: ("rules_svn_url", str, ""), "packager_class", bricks@344: ("root_cmd", shlex.split, "sudo"), "builderconfig", bh@297: "deb_email", "deb_fullname", ("deb_build_options", str, ""), bh@305: ("version_template", str, "%(revision)s"), bh@299: "pkg_revision_template", ("pkg_basename", str, ""), bh@129: ("handle_dependencies", convert_bool), bh@258: ("signing_key_id", str, ""), aheinecke@340: ("changelog_msg_template", str, "Update to revision %(revision)s"), aheinecke@321: ("git_branch", str,""), aheinecke@321: ("git_url", str,"") bh@2: ] bh@2: bh@2: treepkg_desc = [ bh@2: ("check_interval", int), bh@91: "instructions_file", bh@2: ] bh@2: bh@2: bh@2: def read_config_section(parser, section, item_desc, defaults=None): bh@2: if defaults is None: bh@2: defaults = dict() bh@2: options = dict() bh@2: for item in item_desc: bh@258: has_default_value = False bh@2: if isinstance(item, tuple): bh@258: key, converter = item[:2] bh@258: if len(item) == 3: bh@258: default_value = item[-1] bh@258: has_default_value = True bh@2: else: bh@2: key = item bh@2: converter = str bh@2: try: bh@2: value = parser.get(section, key, vars=defaults) bh@2: except NoOptionError: bh@258: if has_default_value: bh@258: value = default_value bh@258: else: bh@258: print >>sys.stderr, "Missing option %r in section %r" \ bh@258: % (key, section) bh@258: sys.exit(1) bh@258: options[key] = converter(value) bh@2: return options bh@0: bh@0: bh@0: def read_config(filename): bh@2: """Reads the tree packager configuration from the file given by filename. bh@0: bh@115: The function returns a tuple with a dict ('treepkg') and a list of bh@115: dicts ('packagers'). The treepkg dict contains the main bh@115: configuration of the tree packager. The packagers list contains one bh@115: dict with the configuratiin for each packager. bh@0: """ bh@258: parser = SafeConfigParser() bh@0: parser.read([filename]) bh@2: bh@2: # extract packager configurations bh@2: packagers = [] bh@0: for section in parser.sections(): bh@0: if section.startswith("pkg_"): bh@114: vars = dict(name=section[4:]) bh@114: packager_class = parser.get(section, "packager_class", vars=vars) bh@114: module = packager.import_packager_module(packager_class) bh@52: desc = packager_desc + module.PackageTrack.extra_config_desc aheinecke@332: packager_options = (read_config_section(parser, section, desc, aheinecke@332: defaults=vars)) aheinecke@332: if not packager_options.get("svn_url") \ aheinecke@332: and not packager_options.get('git_url'): aheinecke@332: print >>sys.stderr, "Missing repository URL in section %r" \ aheinecke@332: % (section) aheinecke@332: sys.exit(1) aheinecke@332: elif packager_options.get("svn_url") \ aheinecke@332: and packager_options.get('git_url'): aheinecke@332: print >>sys.stderr, \ aheinecke@332: "Warning: git_url in section %r will be ignored" \ aheinecke@332: % (section) bh@4: packagers.append(read_config_section(parser, section, desc, bh@114: defaults=vars)) bh@0: bh@2: # main config bh@2: treepkg = read_config_section(parser, "treepkg", treepkg_desc) bh@0: bh@2: return treepkg, packagers bh@0: bh@0: bh@0: if __name__ == "__main__": bh@2: import pprint bh@2: print pprint.pprint(read_config(sys.argv[1]))