<commit_before># cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2012 <NAME> <<EMAIL>>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os
import sys
import copy
import sysconfig
import itertools
from functools import lru_cache
from pathlib import PurePath, Path

from cerbero import enums
from cerbero.errors import FatalError, ConfigurationError
from cerbero.utils import _, system_info, validate_packager, to_unixpath,\
    shell, parse_file, detect_qt5
from cerbero.utils import messages as m
from cerbero.ide.vs.env import get_vs_version


CONFIG_DIR = os.path.expanduser('~/.cerbero')
CONFIG_EXT = 'cbc'
DEFAULT_CONFIG_FILENAME = 'cerbero.%s' % CONFIG_EXT
DEFAULT_CONFIG_FILE = os.path.join(CONFIG_DIR, DEFAULT_CONFIG_FILENAME)
DEFAULT_GIT_ROOT = 'https://gitlab.freedesktop.org/gstreamer'
DEFAULT_ALLOW_PARALLEL_BUILD = True
DEFAULT_PACKAGER = "Default <<EMAIL>>"
CERBERO_UNINSTALLED = 'CERBERO_UNINSTALLED'
CERBERO_PREFIX = 'CERBERO_PREFIX'


Platform = enums.Platform
Architecture = enums.Architecture
Distro = enums.Distro
DistroVersion = enums.DistroVersion
License = enums.License


class Variants(object):

    __disabled_variants = ['x11', 'alsa', 'pulse', 'cdparanoia', 'v4l2',
                           'gi', 'unwind', 'rpi', 'visualstudio', 'qt5',
                           'intelmsdk', 'nvcodec']
    __enabled_variants = ['debug', 'python', 'testspackage']
    __all_variants = __enabled_variants + __disabled_variants

    def __init__(self, variants):
        for v in self.__enabled_variants:
            setattr(self, v, True)
        for v in self.__disabled_variants:
            setattr(self, v, False)
        for v in variants:
            if v.startswith('no'):
                if v[2:] not in self.__all_variants:
                    m.warning('Variant {} is unknown or obsolete'.format(v[2:]))
                setattr(self, v[2:], False)
            else:
                if v not in self.__all_variants:
                    m.warning('Variant {} is unknown or obsolete'.format(v))
                setattr(self, v, True)

    def __getattr__(self, name):
        try:
            if name.startswith('no'):
                return not object.__getattribute__(self, name[2:])
            else:
                return object.__getattribute__(self, name)
        except Exception:
            raise AttributeError("%s is not a known variant" % name)

    def __repr__(self):
        return '<Variants: {}>'.format(self.__dict__)

    def all(self):
        return sorted(self.__all_variants)


class Config (object):

    _properties = ['platform', 'target_platform', 'arch', 'target_arch',
                   'prefix', 'recipes_dir', 'host', 'build', 'target',
                   'sources', 'local_sources', 'lib_suffix', 'git_root',
                   'distro', 'target_distro', 'environ_dir', 'cache_file',
                   'toolchain_prefix', 'toolchain_version', 'distro_version',
                   'target_distro_version', 'allow_system_libs',
                   'packages_dir', 'py_prefix', 'logs',
                   'install_dir', 'allow_parallel_build', 'num_of_cpus',
                   'use_configure_cache', 'packages_prefix', 'packager',
                   'data_dir', 'min_osx_sdk_version', 'external_recipes',
                   'external_packages', 'use_ccache', 'force_git_commit',
                   'universal_archs', 'osx_target_sdk_version', 'variants',
                   'build_tools_prefix', 'build_tools_sources',
                   'build_tools_cache', 'home_dir', 'recipes_commits',
                   'recipes_remotes', 'ios_platform', 'extra_build_tools',
                   'distro_packages_install', 'interactive',
                   'target_arch_flags', 'sysroot', 'isysroot',
                   'extra_lib_path', 'cached_sources', 'tools_prefix',
                   'ios_min_version', 'toolchain_path', 'mingw_perl_prefix',
                   'msvc_version', 'msvc_toolchain_env', 'mingw_toolchain_env',
                   'meson_cross_properties', 'manifest', 'extra_properties',
                   'qt5_qmake_path', 'qt5_pkgconfigdir', 'for_shell',
                   'msvc_export_for_shell']

    cookbook = None

    def __init__(self):
        self._check_uninstalled()
        self.python_exe = sys.executable

        for a in self._properties:
            setattr(self, a, None)

        self.arch_config = {self.target_arch: self}
        # Store raw os.environ data
        self._raw_environ = os.environ.copy()
        self._pre_environ = os.environ.copy()

    def _copy(self, arch):
        c = copy.deepcopy(self)
        c.target_arch = arch
        c._raw_environ = os.environ.copy()
        return c

    def load(self, filename=None, variants_override=None):
        if variants_override is None:
            variants_override = []

        # First load the default configuration
        self.load_defaults()

        # Ensure that config files know about these variants
        self.variants += variants_override

        # Next parse the main configuration file
        self._load_main_config()

        # Next, if a config file is provided use it to override the settings<commit_msg>cerbero: Load command-line variants after user config<commit_after># cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2012 <NAME> <<EMAIL>>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os
import sys
import copy
import sysconfig
import itertools
from functools import lru_cache
from pathlib import PurePath, Path

from cerbero import enums
from cerbero.errors import FatalError, ConfigurationError
from cerbero.utils import _, system_info, validate_packager, to_unixpath,\
    shell, parse_file, detect_qt5
from cerbero.utils import messages as m
from cerbero.ide.vs.env import get_vs_version


CONFIG_DIR = os.path.expanduser('~/.cerbero')
CONFIG_EXT = 'cbc'
DEFAULT_CONFIG_FILENAME = 'cerbero.%s' % CONFIG_EXT
DEFAULT_CONFIG_FILE = os.path.join(CONFIG_DIR, DEFAULT_CONFIG_FILENAME)
DEFAULT_GIT_ROOT = 'https://gitlab.freedesktop.org/gstreamer'
DEFAULT_ALLOW_PARALLEL_BUILD = True
DEFAULT_PACKAGER = "Default <<EMAIL>>"
CERBERO_UNINSTALLED = 'CERBERO_UNINSTALLED'
CERBERO_PREFIX = 'CERBERO_PREFIX'


Platform = enums.Platform
Architecture = enums.Architecture
Distro = enums.Distro
DistroVersion = enums.DistroVersion
License = enums.License


class Variants(object):

    __disabled_variants = ['x11', 'alsa', 'pulse', 'cdparanoia', 'v4l2',
                           'gi', 'unwind', 'rpi', 'visualstudio', 'qt5',
                           'intelmsdk', 'nvcodec']
    __enabled_variants = ['debug', 'python', 'testspackage']
    __all_variants = __enabled_variants + __disabled_variants

    def __init__(self, variants):
        for v in self.__enabled_variants:
            setattr(self, v, True)
        for v in self.__disabled_variants:
            setattr(self, v, False)
        for v in variants:
            if v.startswith('no'):
                if v[2:] not in self.__all_variants:
                    m.warning('Variant {} is unknown or obsolete'.format(v[2:]))
                setattr(self, v[2:], False)
            else:
                if v not in self.__all_variants:
                    m.warning('Variant {} is unknown or obsolete'.format(v))
                setattr(self, v, True)

    def __getattr__(self, name):
        try:
            if name.startswith('no'):
                return not object.__getattribute__(self, name[2:])
            else:
                return object.__getattribute__(self, name)
        except Exception:
            raise AttributeError("%s is not a known variant" % name)

    def __repr__(self):
        return '<Variants: {}>'.format(self.__dict__)

    def all(self):
        return sorted(self.__all_variants)


class Config (object):

    _properties = ['platform', 'target_platform', 'arch', 'target_arch',
                   'prefix', 'recipes_dir', 'host', 'build', 'target',
                   'sources', 'local_sources', 'lib_suffix', 'git_root',
                   'distro', 'target_distro', 'environ_dir', 'cache_file',
                   'toolchain_prefix', 'toolchain_version', 'distro_version',
                   'target_distro_version', 'allow_system_libs',
                   'packages_dir', 'py_prefix', 'logs',
                   'install_dir', 'allow_parallel_build', 'num_of_cpus',
                   'use_configure_cache', 'packages_prefix', 'packager',
                   'data_dir', 'min_osx_sdk_version', 'external_recipes',
                   'external_packages', 'use_ccache', 'force_git_commit',
                   'universal_archs', 'osx_target_sdk_version', 'variants',
                   'build_tools_prefix', 'build_tools_sources',
                   'build_tools_cache', 'home_dir', 'recipes_commits',
                   'recipes_remotes', 'ios_platform', 'extra_build_tools',
                   'distro_packages_install', 'interactive',
                   'target_arch_flags', 'sysroot', 'isysroot',
                   'extra_lib_path', 'cached_sources', 'tools_prefix',
                   'ios_min_version', 'toolchain_path', 'mingw_perl_prefix',
                   'msvc_version', 'msvc_toolchain_env', 'mingw_toolchain_env',
                   'meson_cross_properties', 'manifest', 'extra_properties',
                   'qt5_qmake_path', 'qt5_pkgconfigdir', 'for_shell',
                   'msvc_export_for_shell']

    cookbook = None

    def __init__(self):
        self._check_uninstalled()
        self.python_exe = sys.executable

        for a in self._properties:
            setattr(self, a, None)

        self.arch_config = {self.target_arch: self}
        # Store raw os.environ data
        self._raw_environ = os.environ.copy()
        self._pre_environ = os.environ.copy()

    def _copy(self, arch):
        c = copy.deepcopy(self)
        c.target_arch = arch
        c._raw_environ = os.environ.copy()
        return c

    def load(self, filename=None, variants_override=None):
        if variants_override is None:
            variants_override = []

        # First load the default configuration
        self.load_defaults()

        # Next parse the main configuration file
        self._load_main_config()

        # Ensure that Cerbero config files know about these variants, and that
        # they override the values from the user configuration file above
        self.variants += variants_override

        # Next, if a config file is provided use it to override the settings
{'fraction_non_alphanumeric': 0.09822028206850235, 'fraction_numerical': 0.0052048354600402955, 'mean_word_length': 2.6928084314941105, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '574274', 'n_tokens_mistral': 3548, 'n_tokens_neox': 3372, 'n_words': 954}