# Path: bento/utils/utils.py
# def subst_vars (s, local_vars):
#     """Perform shell/Perl-style variable substitution.
# 
#     Every occurrence of '$' followed by a name is considered a variable, and
#     variable is substituted by the value found in the `local_vars' dictionary.
#     Raise ValueError for any variables not found in `local_vars'.
# 
#     '$' may be escaped by using '$$'
# 
#     Parameters
#     ----------
#     s: str
#         variable to substitute
#     local_vars: dict
#         dict of variables
#     """
#     # Resolve variable substitution within the local_vars dict
#     local_vars = _simple_subst_vars(local_vars, local_vars)
# 
#     def _subst (match):
#         named = match.group("named")
#         if named is not None:
#             if named in local_vars:
#                 return str(local_vars[named])
#             else:
#                 raise ValueError("Invalid variable '%s'" % named)
#         if match.group("escaped") is not None:
#             return _DELIM
#         raise ValueError("This should not happen")
# 
#     def _do_subst(v):
#         pattern_s = r"""
#         %(delim)s(?:
#             (?P<escaped>%(delim)s) |
#             (?P<named>%(id)s)
#         )""" % {"delim": r"\%s" % _DELIM, "id": _IDPATTERN}
#         pattern = re.compile(pattern_s, re.VERBOSE)
#         return pattern.sub(_subst, v)
# 
#     try:
#         return _do_subst(s)
#     except KeyError:
#         raise ValueError("invalid variable '$%s'" % ex_stack())
# 
# def same_content(f1, f2):
#     """Return true if files in f1 and f2 has the same content."""
#     fid1 = open(f1, "rb")
#     try:
#         fid2 = open(f2, "rb")
#         try:
#             return md5(fid1.read()).digest() == md5(fid2.read()).digest()
#         finally:
#             fid2.close()
#     finally:
#         fid1.close()
# 
# def fix_kw(kw):
#     """Make sure the given dictionary may be used as a kw dict independently on
#     the python version and encoding of kw's keys."""
#     return dict([(str(k), v) for k, v in kw.items()])
# 
# def explode_path(path):
#     """Split a path into its components.
# 
#     If the path is absolute, the first value of the returned list will be '/',
#     or the drive letter for platforms where it is applicable.
# 
#     Example
#     -------
#     >>> explode_path("/Users/joe")
#     ["/", "Users", "joe"]
#     """
#     ret = []
#     d, p = op.splitdrive(path)
# 
#     while p:
#         head, tail = op.split(p)
#         if head == p:
#             ret.append(head)
#             break
#         if tail:
#             ret.append(tail)
#         p = head
#     if d:
#         ret.append(d)
#     return ret[::-1]
# 
# Path: bento/core/pkg_objects.py
# class Executable(object):
#     @classmethod
#     def from_parse_dict(cls, d):
#         return cls(**d)
# 
#     @classmethod
#     def from_representation(cls, s):
#         if not "=" in s:
#             raise ValueError("s should be of the form name=module:function")
#         name, value = [j.strip() for j in s.split("=")]
#         if not ":" in value:
#             raise ValueError(
#                 "string representation should be of the form module:function, not %s"
#                 % value)
#         module, function = value.split(":", 1)
#         return cls(name, module, function)
# 
#     def __init__(self, name, module, function):
#         # FIXME: check that module is a module name ?
#         self.name = name
#         self.module = module
#         self.function = function
# 
#     # FIXME: this function should not really be here...
#     def representation(self):
#         return ":".join([self.module, self.function])
# 
#     # FIXME: this function should not really be here...
#     def full_representation(self):
#         return "%s = %s" % (self.name, self.representation())
# 
#     def __repr__(self):
#         return repr({"name": self.name, "module": self.module, "function": self.function})


import os
import sys
import copy
import warnings
import bento.compat.api as compat
import bento.utils.path
from bento.compat.api import json
from bento.core.node \
    import \
        find_root
from bento.core.platforms \
    import \
        get_scheme
from bento.utils.utils import subst_vars, same_content, fix_kw, explode_path
from bento.core.pkg_objects \
    import \
        Executable
        try:
            data = json.loads(zid.read("EGG-INFO/build_manifest.info"))
            return cls.from_json_dict(data)
        finally:
            zid.close()

    @classmethod
    def from_json_dict(cls, d):
        return cls.__from_data(d)

    @classmethod
    def from_string(cls, s):
        return cls.__from_data(json.loads(s))

    @classmethod
    def from_file(cls, filename):
        fid = open(filename)
        try:
            return cls.__from_data(json.load(fid))
        finally:
            fid.close()

    @classmethod
    def __from_data(cls, data):
        meta_vars = fix_kw(data["meta"])
        #variables = data["variables"]
        install_paths = data.get("install_paths", None)

        executables = {}
        for name, executable in data["executables"].items():

# Path: bento/utils/utils.py
# def subst_vars (s, local_vars):
#     """Perform shell/Perl-style variable substitution.
# 
#     Every occurrence of '$' followed by a name is considered a variable, and
#     variable is substituted by the value found in the `local_vars' dictionary.
#     Raise ValueError for any variables not found in `local_vars'.
# 
#     '$' may be escaped by using '$$'
# 
#     Parameters
#     ----------
#     s: str
#         variable to substitute
#     local_vars: dict
#         dict of variables
#     """
#     # Resolve variable substitution within the local_vars dict
#     local_vars = _simple_subst_vars(local_vars, local_vars)
# 
#     def _subst (match):
#         named = match.group("named")
#         if named is not None:
#             if named in local_vars:
#                 return str(local_vars[named])
#             else:
#                 raise ValueError("Invalid variable '%s'" % named)
#         if match.group("escaped") is not None:
#             return _DELIM
#         raise ValueError("This should not happen")
# 
#     def _do_subst(v):
#         pattern_s = r"""
#         %(delim)s(?:
#             (?P<escaped>%(delim)s) |
#             (?P<named>%(id)s)
#         )""" % {"delim": r"\%s" % _DELIM, "id": _IDPATTERN}
#         pattern = re.compile(pattern_s, re.VERBOSE)
#         return pattern.sub(_subst, v)
# 
#     try:
#         return _do_subst(s)
#     except KeyError:
#         raise ValueError("invalid variable '$%s'" % ex_stack())
# 
# def same_content(f1, f2):
#     """Return true if files in f1 and f2 has the same content."""
#     fid1 = open(f1, "rb")
#     try:
#         fid2 = open(f2, "rb")
#         try:
#             return md5(fid1.read()).digest() == md5(fid2.read()).digest()
#         finally:
#             fid2.close()
#     finally:
#         fid1.close()
# 
# def fix_kw(kw):
#     """Make sure the given dictionary may be used as a kw dict independently on
#     the python version and encoding of kw's keys."""
#     return dict([(str(k), v) for k, v in kw.items()])
# 
# def explode_path(path):
#     """Split a path into its components.
# 
#     If the path is absolute, the first value of the returned list will be '/',
#     or the drive letter for platforms where it is applicable.
# 
#     Example
#     -------
#     >>> explode_path("/Users/joe")
#     ["/", "Users", "joe"]
#     """
#     ret = []
#     d, p = op.splitdrive(path)
# 
#     while p:
#         head, tail = op.split(p)
#         if head == p:
#             ret.append(head)
#             break
#         if tail:
#             ret.append(tail)
#         p = head
#     if d:
#         ret.append(d)
#     return ret[::-1]
# 
# Path: bento/core/pkg_objects.py
# class Executable(object):
#     @classmethod
#     def from_parse_dict(cls, d):
#         return cls(**d)
# 
#     @classmethod
#     def from_representation(cls, s):
#         if not "=" in s:
#             raise ValueError("s should be of the form name=module:function")
#         name, value = [j.strip() for j in s.split("=")]
#         if not ":" in value:
#             raise ValueError(
#                 "string representation should be of the form module:function, not %s"
#                 % value)
#         module, function = value.split(":", 1)
#         return cls(name, module, function)
# 
#     def __init__(self, name, module, function):
#         # FIXME: check that module is a module name ?
#         self.name = name
#         self.module = module
#         self.function = function
# 
#     # FIXME: this function should not really be here...
#     def representation(self):
#         return ":".join([self.module, self.function])
# 
#     # FIXME: this function should not really be here...
#     def full_representation(self):
#         return "%s = %s" % (self.name, self.representation())
# 
#     def __repr__(self):
#         return repr({"name": self.name, "module": self.module, "function": self.function})


# Path: bento/installed_package_description.py
import os
import sys
import copy
import warnings
import bento.compat.api as compat
import bento.utils.path
from bento.compat.api import json
from bento.core.node \
    import \
        find_root
from bento.core.platforms \
    import \
        get_scheme
from bento.utils.utils import subst_vars, same_content, fix_kw, explode_path
from bento.core.pkg_objects \
    import \
        Executable

        try:
            data = json.loads(zid.read("EGG-INFO/build_manifest.info"))
            return cls.from_json_dict(data)
        finally:
            zid.close()

    @classmethod
    def from_json_dict(cls, d):
        return cls.__from_data(d)

    @classmethod
    def from_string(cls, s):
        return cls.__from_data(json.loads(s))

    @classmethod
    def from_file(cls, filename):
        fid = open(filename)
        try:
            return cls.__from_data(json.load(fid))
        finally:
            fid.close()

    @classmethod
    def __from_data(cls, data):
        meta_vars = fix_kw(data["meta"])
        #variables = data["variables"]
        install_paths = data.get("install_paths", None)

        executables = {}
        for name, executable in data["executables"].items():

            executables[name] = Executable.from_parse_dict(fix_kw(executable))