Beispiel #1
0
class Profile(object):
    """A profile contains a set of setting (with values), environment variables
    and scopes"""

    def __init__(self):
        # Sections
        self.settings = OrderedDict()
        self.package_settings = defaultdict(OrderedDict)
        self.env_values = EnvValues()
        self.scopes = Scopes()
        self.options = OptionsValues()

    @property
    def settings_values(self):
        return Values.from_list(list(self.settings.items()))

    @property
    def package_settings_values(self):
        result = {}
        for pkg, settings in self.package_settings.items():
            result[pkg] = list(settings.items())
        return result

    @staticmethod
    def read_file(profile_name, cwd, default_folder):
        """ Will look for "profile_name" in disk if profile_name is absolute path,
        in current folder if path is relative or in the default folder otherwise.
        return: a Profile object
        """
        if not profile_name:
            return None

        if os.path.isabs(profile_name):
            profile_path = profile_name
            folder = os.path.dirname(profile_name)
        elif profile_name.startswith("."):  # relative path name
            profile_path = os.path.abspath(os.path.join(cwd, profile_name))
            folder = os.path.dirname(profile_path)
        else:
            folder = default_folder
            if not os.path.exists(folder):
                mkdir(folder)
            profile_path = os.path.join(folder, profile_name)

        try:
            text = load(profile_path)
        except IOError:
            if os.path.exists(folder):
                profiles = [name for name in os.listdir(folder) if not os.path.isdir(name)]
            else:
                profiles = []
            current_profiles = ", ".join(profiles) or "[]"
            raise ConanException("Specified profile '%s' doesn't exist.\nExisting profiles: "
                                 "%s" % (profile_name, current_profiles))

        try:
            text = text.replace("$PROFILE_DIR", os.path.abspath(folder))  # Allows PYTHONPATH=$PROFILE_DIR/pythontools
            return Profile.loads(text)
        except ConanException as exc:
            raise ConanException("Error reading '%s' profile: %s" % (profile_name, exc))

    @staticmethod
    def loads(text):
        """ Parse and return a Profile object from a text config like representation
        """
        def get_package_name_value(item):
            '''Parse items like package:name=value or name=value'''
            package_name = None
            if ":" in item:
                tmp = item.split(":", 1)
                package_name, item = tmp

            name, value = item.split("=", 1)
            name = name.strip()
            value = unquote(value)
            return package_name, name, value

        try:
            obj = Profile()
            doc = ConfigParser(text, allowed_fields=["settings", "env", "scopes", "options"])

            for setting in doc.settings.splitlines():
                setting = setting.strip()
                if setting and not setting.startswith("#"):
                    if "=" not in setting:
                        raise ConanException("Invalid setting line '%s'" % setting)
                    package_name, name, value = get_package_name_value(setting)
                    if package_name:
                        obj.package_settings[package_name][name] = value
                    else:
                        obj.settings[name] = value

            if doc.scopes:
                obj.scopes = Scopes.from_list(doc.scopes.splitlines())

            if doc.options:
                obj.options = OptionsValues.loads(doc.options)

            obj.env_values = EnvValues.loads(doc.env)

            return obj
        except ConanException:
            raise
        except Exception as exc:
            raise ConanException("Error parsing the profile text file: %s" % str(exc))

    def dumps(self):
        result = ["[settings]"]
        for name, value in self.settings.items():
            result.append("%s=%s" % (name, value))
        for package, values in self.package_settings.items():
            for name, value in values.items():
                result.append("%s:%s=%s" % (package, name, value))

        result.append("[options]")
        result.append(self.options.dumps())

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        result.append(self.env_values.dumps())

        return "\n".join(result).replace("\n\n", "\n")

    def update(self, other):
        self.update_settings(other.settings)
        self.update_package_settings(other.package_settings)
        self.update_scopes(other.scopes)
        # this is the opposite
        other.env_values.update(self.env_values)
        self.env_values = other.env_values
        self.options.update(other.options)

    def update_settings(self, new_settings):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_settings:
            self.settings.update(new_settings)

    def update_package_settings(self, package_settings):
        '''Mix the specified package settings with the specified profile.
        Specified package settings are prioritized to profile'''
        for package_name, settings in package_settings.items():
            self.package_settings[package_name].update(settings)

    def update_scopes(self, new_scopes):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
Beispiel #2
0
class Profile(object):
    '''A profile contains a set of setting (with values), environment variables
    and scopes'''
    def __init__(self):
        # Sections
        self._settings = OrderedDict()
        self._package_settings = defaultdict(OrderedDict)
        self._env = OrderedDict()
        self._package_env = defaultdict(OrderedDict)
        self.scopes = Scopes()

    @property
    def package_settings(self):
        return {
            package_name: list(settings.items())
            for package_name, settings in self._package_settings.items()
        }

    @property
    def settings(self):
        return list(self._settings.items())

    @property
    def package_env(self):
        return {
            package_name: list(env.items())
            for package_name, env in self._package_env.items()
        }

    @property
    def env(self):
        return list(self._env.items())

    @staticmethod
    def loads(text):
        def get_package_name_value(item):
            '''Parse items like package:name=value or name=value'''
            package_name = None
            if ":" in item:
                tmp = item.split(":", 1)
                package_name, item = tmp

            name, value = item.split("=", 1)
            name = name.strip()
            value = _clean_value(value)
            return package_name, name, value

        try:
            obj = Profile()
            doc = ConfigParser(text,
                               allowed_fields=["settings", "env", "scopes"])

            for setting in doc.settings.splitlines():
                setting = setting.strip()
                if setting and not setting.startswith("#"):
                    if "=" not in setting:
                        raise ConanException("Invalid setting line '%s'" %
                                             setting)
                    package_name, name, value = get_package_name_value(setting)
                    if package_name:
                        obj._package_settings[package_name][name] = value
                    else:
                        obj._settings[name] = value

            if doc.scopes:
                obj.scopes = Scopes.from_list(doc.scopes.splitlines())

            for env in doc.env.splitlines():
                env = env.strip()
                if env and not env.startswith("#"):
                    if "=" not in env:
                        raise ConanException("Invalid env line '%s'" % env)
                    package_name, name, value = get_package_name_value(env)
                    if package_name:
                        obj._package_env[package_name][name] = value
                    else:
                        obj._env[name] = value

            obj._order()
            return obj
        except ConanException:
            raise
        except Exception as exc:
            raise ConanException("Error parsing the profile text file: %s" %
                                 str(exc))

    def dumps(self):
        self._order()  # gets in order the settings

        def dump_simple_items(items, result):
            for name, value in items:
                result.append("%s=%s" % (name, value))

        def dump_package_items(items, result):
            for package, values in items:
                for name, value in values.items():
                    result.append("%s:%s=%s" % (package, name, value))

        result = ["[settings]"]
        dump_simple_items(self._settings.items(), result)
        dump_package_items(self._package_settings.items(), result)

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        dump_simple_items(self._env.items(), result)
        dump_package_items(self._package_env.items(), result)

        return "\n".join(result).replace("\n\n", "\n")

    def update_settings(self, new_settings):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_settings:
            self._settings.update(new_settings)
            self._order()

    def update_package_settings(self, package_settings):
        '''Mix the specified package settings with the specified profile.
        Specified package settings are prioritized to profile'''
        for package_name, settings in self._package_settings.items():
            if package_name in package_settings:
                settings.update(dict(package_settings[package_name]))

        # The rest of new packages settings
        for package_name, settings in package_settings.items():
            if package_name not in self._package_settings:
                self._package_settings[package_name].update(dict(settings))

        self._order()

    def _mix_env_with_new(self, env_dict, new_env):

        res_env = OrderedDict()
        for name, value in new_env:
            if name in env_dict:
                del env_dict[name]
            res_env[name] = value  # Insert first in the result

        for name, value in env_dict.items():
            res_env[name] = value  # Insert the rest of env vars at the end

        return res_env

    def update_env(self, new_env):
        '''Priorize new_env to override the current envs'''
        if not new_env:
            return
        self._env = self._mix_env_with_new(self._env, new_env)

    def update_packages_env(self, new_packages_env):
        '''Priorize new_packages_env to override the current package_env'''
        if not new_packages_env:
            return
        res_env = defaultdict(OrderedDict)

        # Mix the common packages env
        for package, env_vars in self._package_env.items():
            new_env = new_packages_env.get(package, [])
            res_env[package] = self._mix_env_with_new(env_vars, new_env)

        # The rest of new packages env variables
        for package, env_vars in new_packages_env.items():
            if package not in res_env:
                for name, value in env_vars:
                    res_env[package][
                        name] = value  # Insert the rest of env vars at the end

        self._package_env = res_env

    def update_scopes(self, new_scopes):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
            self._order()

    def _order(self):
        def order_single_settings(settings):
            ret = OrderedDict()
            # Insert in a good order
            for func in [
                    lambda x: "." not in x,  # First the principal settings
                    lambda x: "." in x
            ]:
                for name, value in settings.items():
                    if func(name):
                        ret[name] = value
            return ret

        # Order global settings
        self._settings = order_single_settings(self._settings)

        # Order package settings
        for package_name, settings in self._package_settings.items():
            self._package_settings[package_name] = order_single_settings(
                settings)

        tmp_env = copy.copy(self._env)
        self._env = OrderedDict()
        for ordered_key in sorted(tmp_env):
            self._env[ordered_key] = tmp_env[ordered_key]
Beispiel #3
0
class Profile(object):
    """A profile contains a set of setting (with values), environment variables
    and scopes"""

    def __init__(self):
        # Sections
        self.settings = OrderedDict()
        self.package_settings = defaultdict(OrderedDict)
        self.env_values = EnvValues()
        self.scopes = Scopes()
        self.options = OptionsValues()
        self.build_requires = OrderedDict()  # conan_ref Pattern: list of conan_ref

    @property
    def settings_values(self):
        return Values.from_list(list(self.settings.items()))

    @property
    def package_settings_values(self):
        result = {}
        for pkg, settings in self.package_settings.items():
            result[pkg] = list(settings.items())
        return result

    def dumps(self):
        result = ["[build_requires]"]
        for pattern, req_list in self.build_requires.items():
            result.append("%s: %s" % (pattern, ", ".join(str(r) for r in req_list)))
        result.append("[settings]")
        for name, value in self.settings.items():
            result.append("%s=%s" % (name, value))
        for package, values in self.package_settings.items():
            for name, value in values.items():
                result.append("%s:%s=%s" % (package, name, value))

        result.append("[options]")
        result.append(self.options.dumps())

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        result.append(self.env_values.dumps())

        return "\n".join(result).replace("\n\n", "\n")

    def update(self, other):
        self.update_settings(other.settings)
        self.update_package_settings(other.package_settings)
        self.update_scopes(other.scopes)
        # this is the opposite
        other.env_values.update(self.env_values)
        self.env_values = other.env_values
        self.options.update(other.options)
        for pattern, req_list in other.build_requires.items():
            self.build_requires.setdefault(pattern, []).extend(req_list)

    def update_settings(self, new_settings):
        """Mix the specified settings with the current profile.
        Specified settings are prioritized to profile"""

        assert(isinstance(new_settings, OrderedDict))

        # apply the current profile
        res = copy.copy(self.settings)
        if new_settings:
            # Invalidate the current subsettings if the parent setting changes
            # Example: new_settings declare a different "compiler", so invalidate the current "compiler.XXX"
            for name, value in new_settings.items():
                if "." not in name:
                    if name in self.settings and self.settings[name] != new_settings[name]:
                        for cur_name, _ in self.settings.items():
                            if cur_name.startswith(name):
                                del res[cur_name]
            # Now merge the new values
            res.update(new_settings)
            self.settings = res

    def update_package_settings(self, package_settings):
        """Mix the specified package settings with the specified profile.
        Specified package settings are prioritized to profile"""
        for package_name, settings in package_settings.items():
            self.package_settings[package_name].update(settings)

    def update_scopes(self, new_scopes):
        """Mix the specified settings with the current profile.
        Specified settings are prioritized to profile"""
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
Beispiel #4
0
class Profile(object):
    """A profile contains a set of setting (with values), environment variables
    and scopes"""
    def __init__(self):
        # Sections
        self.settings = OrderedDict()
        self.package_settings = defaultdict(OrderedDict)
        self.env_values = EnvValues()
        self.scopes = Scopes()
        self.options = OptionsValues()
        self.build_requires = OrderedDict(
        )  # conan_ref Pattern: list of conan_ref

    @property
    def settings_values(self):
        return Values.from_list(list(self.settings.items()))

    @property
    def package_settings_values(self):
        result = {}
        for pkg, settings in self.package_settings.items():
            result[pkg] = list(settings.items())
        return result

    def dumps(self):
        result = ["[build_requires]"]
        for pattern, req_list in self.build_requires.items():
            result.append("%s: %s" %
                          (pattern, ", ".join(str(r) for r in req_list)))
        result.append("[settings]")
        for name, value in self.settings.items():
            result.append("%s=%s" % (name, value))
        for package, values in self.package_settings.items():
            for name, value in values.items():
                result.append("%s:%s=%s" % (package, name, value))

        result.append("[options]")
        result.append(self.options.dumps())

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        result.append(self.env_values.dumps())

        return "\n".join(result).replace("\n\n", "\n")

    def update(self, other):
        self.update_settings(other.settings)
        self.update_package_settings(other.package_settings)
        self.update_scopes(other.scopes)
        # this is the opposite
        other.env_values.update(self.env_values)
        self.env_values = other.env_values
        self.options.update(other.options)
        for pattern, req_list in other.build_requires.items():
            self.build_requires.setdefault(pattern, []).extend(req_list)

    def update_settings(self, new_settings):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_settings:
            self.settings.update(new_settings)

    def update_package_settings(self, package_settings):
        '''Mix the specified package settings with the specified profile.
        Specified package settings are prioritized to profile'''
        for package_name, settings in package_settings.items():
            self.package_settings[package_name].update(settings)

    def update_scopes(self, new_scopes):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
Beispiel #5
0
class Profile(object):
    '''A profile contains a set of setting (with values), environment variables
    and scopes'''
    def __init__(self):
        # Sections
        self.settings = OrderedDict()
        self.env = OrderedDict()
        self.scopes = Scopes()

    @staticmethod
    def loads(text):
        obj = Profile()
        doc = ConfigParser(text, allowed_fields=["settings", "env", "scopes"])

        for setting in doc.settings.splitlines():
            setting = setting.strip()
            if setting and not setting.startswith("#"):
                if "=" not in setting:
                    raise ConanException("Invalid setting line '%s'" % setting)
                name, value = setting.split("=")
                obj.settings[name.strip()] = value.strip()

        if doc.scopes:
            obj.scopes = Scopes.from_list(doc.scopes.splitlines())

        for env in doc.env.splitlines():
            env = env.strip()
            if env and not env.startswith("#"):
                if "=" not in env:
                    raise ConanException("Invalid env line '%s'" % env)
                varname, value = env.split("=")
                obj.env[varname.strip()] = value.strip()

        obj._order()
        return obj

    def dumps(self):
        self._order()  # gets in order the settings

        result = ["[settings]"]
        for name, value in self.settings.items():
            result.append("%s=%s" % (name, value))

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        for name, value in self.env.items():
            result.append("%s=%s" % (name, value))

        return "\n".join(result).replace("\n\n", "\n")

    def update_settings(self, new_settings):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_settings:
            self.settings.update(new_settings)
            self._order()

    def update_scopes(self, new_scopes):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
            self._order()

    def _order(self):
        tmp_settings = copy.copy(self.settings)
        self.settings = OrderedDict()
        # Insert in a good order
        for func in [
                lambda x: "." not in x,  # First the principal settings
                lambda x: "." in x
        ]:
            for name, value in tmp_settings.items():
                if func(name):
                    self.settings[name] = value

        tmp_env = copy.copy(self.env)
        self.env = OrderedDict()
        for ordered_key in sorted(tmp_env):
            self.env[ordered_key] = tmp_env[ordered_key]
Beispiel #6
0
class Profile(object):
    """A profile contains a set of setting (with values), environment variables
    and scopes"""

    def __init__(self):
        # Sections
        self.settings = OrderedDict()
        self.package_settings = defaultdict(OrderedDict)
        self.env_values = EnvValues()
        self.scopes = Scopes()
        self.options = OptionsValues()
        self.build_requires = OrderedDict()  # conan_ref Pattern: list of conan_ref

    @property
    def settings_values(self):
        return Values.from_list(list(self.settings.items()))

    @property
    def package_settings_values(self):
        result = {}
        for pkg, settings in self.package_settings.items():
            result[pkg] = list(settings.items())
        return result

    def dumps(self):
        result = ["[build_requires]"]
        for pattern, req_list in self.build_requires.items():
            result.append("%s: %s" % (pattern, ", ".join(str(r) for r in req_list)))
        result.append("[settings]")
        for name, value in self.settings.items():
            result.append("%s=%s" % (name, value))
        for package, values in self.package_settings.items():
            for name, value in values.items():
                result.append("%s:%s=%s" % (package, name, value))

        result.append("[options]")
        result.append(self.options.dumps())

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        result.append(self.env_values.dumps())

        return "\n".join(result).replace("\n\n", "\n")

    def update(self, other):
        self.update_settings(other.settings)
        self.update_package_settings(other.package_settings)
        self.update_scopes(other.scopes)
        # this is the opposite
        other.env_values.update(self.env_values)
        self.env_values = other.env_values
        self.options.update(other.options)
        for pattern, req_list in other.build_requires.items():
            self.build_requires.setdefault(pattern, []).extend(req_list)

    def update_settings(self, new_settings):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_settings:
            self.settings.update(new_settings)

    def update_package_settings(self, package_settings):
        '''Mix the specified package settings with the specified profile.
        Specified package settings are prioritized to profile'''
        for package_name, settings in package_settings.items():
            self.package_settings[package_name].update(settings)

    def update_scopes(self, new_scopes):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
Beispiel #7
0
class Profile(object):
    """A profile contains a set of setting (with values), environment variables
    and scopes"""

    def __init__(self):
        # Sections
        self._settings = OrderedDict()
        self._package_settings = defaultdict(OrderedDict)
        self._env = OrderedDict()
        self._package_env = defaultdict(OrderedDict)
        self.scopes = Scopes()

    @property
    def package_settings(self):
        return {package_name: list(settings.items()) for package_name, settings in self._package_settings.items()}

    @property
    def settings(self):
        return list(self._settings.items())

    @property
    def package_env(self):
        return {package_name: list(env.items()) for package_name, env in self._package_env.items()}

    @property
    def env(self):
        return list(self._env.items())

    @staticmethod
    def loads(text):
        def get_package_name_value(item):
            """Parse items like package:name=value or name=value"""
            package_name = None
            if ":" in item:
                tmp = item.split(":", 1)
                package_name, item = tmp

            name, value = item.split("=", 1)
            name = name.strip()
            value = _clean_value(value)
            return package_name, name, value

        try:
            obj = Profile()
            doc = ConfigParser(text, allowed_fields=["settings", "env", "scopes"])

            for setting in doc.settings.splitlines():
                setting = setting.strip()
                if setting and not setting.startswith("#"):
                    if "=" not in setting:
                        raise ConanException("Invalid setting line '%s'" % setting)
                    package_name, name, value = get_package_name_value(setting)
                    if package_name:
                        obj._package_settings[package_name][name] = value
                    else:
                        obj._settings[name] = value

            if doc.scopes:
                obj.scopes = Scopes.from_list(doc.scopes.splitlines())

            for env in doc.env.splitlines():
                env = env.strip()
                if env and not env.startswith("#"):
                    if "=" not in env:
                        raise ConanException("Invalid env line '%s'" % env)
                    package_name, name, value = get_package_name_value(env)
                    if package_name:
                        obj._package_env[package_name][name] = value
                    else:
                        obj._env[name] = value

            obj._order()
            return obj
        except ConanException:
            raise
        except Exception as exc:
            raise ConanException("Error parsing the profile text file: %s" % str(exc))

    def dumps(self):
        self._order()  # gets in order the settings

        def dump_simple_items(items, result):
            for name, value in items:
                result.append("%s=%s" % (name, value))

        def dump_package_items(items, result):
            for package, values in items:
                for name, value in values.items():
                    result.append("%s:%s=%s" % (package, name, value))

        result = ["[settings]"]
        dump_simple_items(self._settings.items(), result)
        dump_package_items(self._package_settings.items(), result)

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        dump_simple_items(self._env.items(), result)
        dump_package_items(self._package_env.items(), result)

        return "\n".join(result).replace("\n\n", "\n")

    def update_settings(self, new_settings):
        """Mix the specified settings with the current profile.
        Specified settings are prioritized to profile"""
        # apply the current profile
        if new_settings:
            self._settings.update(new_settings)
            self._order()

    def update_package_settings(self, package_settings):
        """Mix the specified package settings with the specified profile.
        Specified package settings are prioritized to profile"""
        for package_name, settings in self._package_settings.items():
            if package_name in package_settings:
                settings.update(dict(package_settings[package_name]))

        # The rest of new packages settings
        for package_name, settings in package_settings.items():
            if package_name not in self._package_settings:
                self._package_settings[package_name].update(dict(settings))

        self._order()

    def _mix_env_with_new(self, env_dict, new_env):

        res_env = OrderedDict()
        for name, value in new_env:
            if name in env_dict:
                del env_dict[name]
            res_env[name] = value  # Insert first in the result

        for name, value in env_dict.items():
            res_env[name] = value  # Insert the rest of env vars at the end

        return res_env

    def update_env(self, new_env):
        """Priorize new_env to override the current envs"""
        if not new_env:
            return
        self._env = self._mix_env_with_new(self._env, new_env)

    def update_packages_env(self, new_packages_env):
        """Priorize new_packages_env to override the current package_env"""
        if not new_packages_env:
            return
        res_env = defaultdict(OrderedDict)

        # Mix the common packages env
        for package, env_vars in self._package_env.items():
            new_env = new_packages_env.get(package, [])
            res_env[package] = self._mix_env_with_new(env_vars, new_env)

        # The rest of new packages env variables
        for package, env_vars in new_packages_env.items():
            if package not in res_env:
                for name, value in env_vars:
                    res_env[package][name] = value  # Insert the rest of env vars at the end

        self._package_env = res_env

    def update_scopes(self, new_scopes):
        """Mix the specified settings with the current profile.
        Specified settings are prioritized to profile"""
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
            self._order()

    def _order(self):
        def order_single_settings(settings):
            ret = OrderedDict()
            # Insert in a good order
            for func in [lambda x: "." not in x, lambda x: "." in x]:  # First the principal settings
                for name, value in settings.items():
                    if func(name):
                        ret[name] = value
            return ret

        # Order global settings
        self._settings = order_single_settings(self._settings)

        # Order package settings
        for package_name, settings in self._package_settings.items():
            self._package_settings[package_name] = order_single_settings(settings)

        tmp_env = copy.copy(self._env)
        self._env = OrderedDict()
        for ordered_key in sorted(tmp_env):
            self._env[ordered_key] = tmp_env[ordered_key]
Beispiel #8
0
class Profile(object):
    '''A profile contains a set of setting (with values), environment variables
    and scopes'''

    def __init__(self):
        # Sections
        self.settings = OrderedDict()
        self.env = OrderedDict()
        self.scopes = Scopes()

    @staticmethod
    def loads(text):
        obj = Profile()
        doc = ConfigParser(text, allowed_fields=["settings", "env", "scopes"])

        for setting in doc.settings.splitlines():
            setting = setting.strip()
            if setting and not setting.startswith("#"):
                if "=" not in setting:
                    raise ConanException("Invalid setting line '%s'" % setting)
                name, value = setting.split("=")
                obj.settings[name.strip()] = value.strip()

        if doc.scopes:
            obj.scopes = Scopes.from_list(doc.scopes.splitlines())

        for env in doc.env.splitlines():
            env = env.strip()
            if env and not env.startswith("#"):
                if "=" not in env:
                    raise ConanException("Invalid env line '%s'" % env)
                varname, value = env.split("=")
                obj.env[varname.strip()] = value.strip()

        obj._order()
        return obj

    def dumps(self):
        self._order()  # gets in order the settings

        result = ["[settings]"]
        for name, value in self.settings.items():
            result.append("%s=%s" % (name, value))

        result.append("[scopes]")
        if self.scopes[_root].get("dev", None):
            # FIXME: Ugly _root import
            del self.scopes[_root]["dev"]  # Do not include dev
        scopes_txt = self.scopes.dumps()
        result.append(scopes_txt)

        result.append("[env]")
        for name, value in self.env.items():
            result.append("%s=%s" % (name, value))

        return "\n".join(result).replace("\n\n", "\n")

    def update_settings(self, new_settings):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_settings:
            self.settings.update(new_settings)
            self._order()

    def update_scopes(self, new_scopes):
        '''Mix the specified settings with the current profile.
        Specified settings are prioritized to profile'''
        # apply the current profile
        if new_scopes:
            self.scopes.update(new_scopes)
            self._order()

    def _order(self):
        tmp_settings = copy.copy(self.settings)
        self.settings = OrderedDict()
        # Insert in a good order
        for func in [lambda x: "." not in x,  # First the principal settings
                     lambda x: "." in x]:
            for name, value in tmp_settings.items():
                if func(name):
                    self.settings[name] = value

        tmp_env = copy.copy(self.env)
        self.env = OrderedDict()
        for ordered_key in sorted(tmp_env):
            self.env[ordered_key] = tmp_env[ordered_key]