示例#1
0
def ParsePkgInfo(contents, filename, valid_keys=None, required_keys=None):
    """Parse a string contains the contents of a pkg_info file.

  Args:
    contents: pkg_info contents as a string.
    filename: name of file to use in error messages.
    valid_keys: list of keys that are valid in the file.
    required_keys: list of keys that are required in the file.

  Returns:
    A dictionary of the key, value pairs contained in the pkg_info file.

  Raises:
    PkgFormatError: if file is malformed, contains invalid keys, or does not
      contain all required keys.
  """
    rtn = {}
    if valid_keys is None:
        valid_keys = VALID_KEYS
    if required_keys is None:
        required_keys = REQUIRED_KEYS

    def ParsePkgInfoLine(line, line_no):
        if '=' not in line:
            raise PkgFormatError('Invalid info line %s:%d' %
                                 (filename, line_no))
        key, value = line.split('=', 1)
        key = key.strip()
        if key not in valid_keys:
            raise PkgFormatError("Invalid key '%s' in info file %s:%d" %
                                 (key, filename, line_no))
        value = value.strip()
        if value[0] == '(':
            if value[-1] != ')':
                raise PkgFormatError('Error parsing %s:%d: %s (%s)' %
                                     (filename, line_no, key, value))
            value = value[1:-1].split()
        else:
            value = shlex.split(value)[0]
        return (key, value)

    def ExpandVars(value, substitutions):
        if type(value) == str:
            return string.Template(value).substitute(substitutions)
        else:
            return [
                string.Template(v).substitute(substitutions) for v in value
            ]

    for i, line in enumerate(contents.splitlines()):
        if not line or line[0] == '#':
            continue
        key, raw_value = ParsePkgInfoLine(line, i + 1)
        if key in rtn:
            raise PkgFormatError('Error parsing %s:%d: duplicate key (%s)' %
                                 (filename, i + 1, key))
        rtn[key] = ExpandVars(raw_value, rtn)

    for required_key in required_keys:
        if required_key not in rtn:
            raise PkgFormatError(
                "Required key '%s' missing from info file: '%s'" %
                (required_key, filename))

    return rtn