<commit_before>import os.path
import pprint
import copy
import hashlib
import re

import dbt.deprecations
import dbt.contracts.connection
import dbt.clients.yaml_helper
import dbt.clients.jinja
import dbt.compat
import dbt.context.common
import dbt.clients.system
import dbt.ui.printer
import dbt.links

from dbt.api.object import APIObject
from dbt.utils import deep_merge
from dbt.logger import GLOBAL_LOGGER as logger  # noqa

default_project_cfg = {
    'source-paths': ['models'],
    'macro-paths': ['macros'],
    'data-paths': ['data'],
    'test-paths': ['test'],
    'target-path': 'target',
    'clean-targets': ['target'],
    'outputs': {'default': {}},
    'target': 'default',
    'models': {},
    'quoting': {},
    'profile': None,
    'packages': [],
    'modules-path': 'dbt_modules'
}

default_profiles = {}

default_profiles_dir = os.path.join(os.path.expanduser('~'), '.dbt')

NO_SUPPLIED_PROFILE_ERROR = """\
dbt cannot run because no profile was specified for this dbt project.
To specify a profile for this project, add a line like the this to
your dbt_project.yml file:

profile: [profile name]

Here, [profile name] should be replaced with a profile name
defined in your profiles.yml file. You can find profiles.yml here:

{profiles_file}/profiles.yml
""".format(profiles_file=default_profiles_dir)


class DbtProjectError(Exception):
    def __init__(self, message, project):
        self.project = project
        super(DbtProjectError, self).__init__(message)


class DbtProfileError(Exception):
    def __init__(self, message, project):
        super(DbtProfileError, self).__init__(message)


class Project(object):

    def __init__(self, cfg, profiles, profiles_dir, profile_to_load=None,
                 args=None):

        self.cfg = default_project_cfg.copy()
        self.cfg.update(cfg)
        self.profiles = default_profiles.copy()
        self.profiles.update(profiles)
        self.profiles_dir = profiles_dir
        self.profile_to_load = profile_to_load
        self.args = args

        # load profile from dbt_config.yml if cli arg isn't supplied
        if self.profile_to_load is None and self.cfg['profile'] is not None:
            self.profile_to_load = self.cfg['profile']

        if self.profile_to_load is None:
            raise DbtProjectError(NO_SUPPLIED_PROFILE_ERROR, self)

        if self.profile_to_load in self.profiles:
            self.cfg.update(self.profiles[self.profile_to_load])
            self.compile_and_update_target()

        else:
            raise DbtProjectError(
                "Could not find profile named '{}'"
                .format(self.profile_to_load), self)

        if self.cfg.get('models') is None:
            self.cfg['models'] = {}

        if self.cfg.get('quoting') is None:
            self.cfg['quoting'] = {}

        if self.cfg['models'].get('vars') is None:
            self.cfg['models']['vars'] = {}

        global_vars = dbt.utils.parse_cli_vars(getattr(args, 'vars', '{}'))
        self.cfg['cli_vars'] = global_vars

    def __str__(self):
        return pprint.pformat({'project': self.cfg, 'profiles': self.profiles})

    def __repr__(self):
        return self.__str__()

    def __getitem__(self, key):
        return self.cfg.__getitem__(key)

    def __contains__(self, key):
        return self.cfg.__contains__(key)

    def __setitem__(self, key, value):
        return self.cfg.__setitem__(key, value)

    def get(self, key, default=None):
        return self.cfg.get(key, default)

    def handle_deprecations(self):
        pass

    def is_valid_package_name(self):
        if re.match(r"^[^\d\W]\w*\Z", self['name']):
            return True
        else:
            return False

    def compile_target(self, target_cfg):
        ctx = self.base_context()

        compiled = {}
        for (key, value) in target_cfg.items():
            is_str = isinstance(value, dbt.compat.basestring)

            if is_str:
                compiled_val = dbt.clients.jinja.get_rendered(value, ctx)
            else:
                compiled_val = value

            compiled[key] = compiled_val

        if self.args and hasattr(self.args, 'threads') and self.args.threads:
            compiled['threads'] = self.args.threads

        return compiled

    def compile_and_update_target(self):
        target = self.cfg['target']
        self.cfg['outputs'][target].update(self.run_environment())

    def run_environment(self):
        target_name = self.cfg['target']
        if target_name in self.cfg['outputs']:
            target_cfg = self.cfg['outputs'][target_name]
            return self.compile_target(target_cfg)
        else:
            raise DbtProfileError(
                    "'target' config was not found in profile entry for "
                    "'{}'".format(target_name), self)

    def get_target(self):
        ctx = self.context().get('env').copy()
        ctx['name'] = self.cfg['target']
        return ctx

    def base_context(self):
        return {
            'env_var': dbt.context.common._env_var
        }

    def context(self):
        target_cfg = self.run_environment()
        filtered_target = copy.deepcopy(target_cfg)
        filtered_target.pop('pass', None)

        ctx = self.base_context()
        ctx.update({
            'env': filtered_target
        })

        return ctx

    def validate(self):<commit_msg>(fixes #890) Show more helpful error for misconfigured profile<commit_after>import os.path
import pprint
import copy
import hashlib
import re

import dbt.deprecations
import dbt.contracts.connection
import dbt.clients.yaml_helper
import dbt.clients.jinja
import dbt.compat
import dbt.context.common
import dbt.clients.system
import dbt.ui.printer
import dbt.links

from dbt.api.object import APIObject
from dbt.utils import deep_merge
from dbt.logger import GLOBAL_LOGGER as logger  # noqa

default_project_cfg = {
    'source-paths': ['models'],
    'macro-paths': ['macros'],
    'data-paths': ['data'],
    'test-paths': ['test'],
    'target-path': 'target',
    'clean-targets': ['target'],
    'outputs': {'default': {}},
    'target': 'default',
    'models': {},
    'quoting': {},
    'profile': None,
    'packages': [],
    'modules-path': 'dbt_modules'
}

default_profiles = {}

default_profiles_dir = os.path.join(os.path.expanduser('~'), '.dbt')

NO_SUPPLIED_PROFILE_ERROR = """\
dbt cannot run because no profile was specified for this dbt project.
To specify a profile for this project, add a line like the this to
your dbt_project.yml file:

profile: [profile name]

Here, [profile name] should be replaced with a profile name
defined in your profiles.yml file. You can find profiles.yml here:

{profiles_file}/profiles.yml
""".format(profiles_file=default_profiles_dir)


class DbtProjectError(Exception):
    def __init__(self, message, project):
        self.project = project
        super(DbtProjectError, self).__init__(message)


class DbtProfileError(Exception):
    def __init__(self, message, project):
        super(DbtProfileError, self).__init__(message)


class Project(object):

    def __init__(self, cfg, profiles, profiles_dir, profile_to_load=None,
                 args=None):

        self.cfg = default_project_cfg.copy()
        self.cfg.update(cfg)
        self.profiles = default_profiles.copy()
        self.profiles.update(profiles)
        self.profiles_dir = profiles_dir
        self.profile_to_load = profile_to_load
        self.args = args

        # load profile from dbt_config.yml if cli arg isn't supplied
        if self.profile_to_load is None and self.cfg['profile'] is not None:
            self.profile_to_load = self.cfg['profile']

        if self.profile_to_load is None:
            raise DbtProjectError(NO_SUPPLIED_PROFILE_ERROR, self)

        if self.profile_to_load in self.profiles:
            self.cfg.update(self.profiles[self.profile_to_load])
            self.compile_and_update_target()

        else:
            raise DbtProjectError(
                "Could not find profile named '{}'"
                .format(self.profile_to_load), self)

        if self.cfg.get('models') is None:
            self.cfg['models'] = {}

        if self.cfg.get('quoting') is None:
            self.cfg['quoting'] = {}

        if self.cfg['models'].get('vars') is None:
            self.cfg['models']['vars'] = {}

        global_vars = dbt.utils.parse_cli_vars(getattr(args, 'vars', '{}'))
        self.cfg['cli_vars'] = global_vars

    def __str__(self):
        return pprint.pformat({'project': self.cfg, 'profiles': self.profiles})

    def __repr__(self):
        return self.__str__()

    def __getitem__(self, key):
        return self.cfg.__getitem__(key)

    def __contains__(self, key):
        return self.cfg.__contains__(key)

    def __setitem__(self, key, value):
        return self.cfg.__setitem__(key, value)

    def get(self, key, default=None):
        return self.cfg.get(key, default)

    def handle_deprecations(self):
        pass

    def is_valid_package_name(self):
        if re.match(r"^[^\d\W]\w*\Z", self['name']):
            return True
        else:
            return False

    def compile_target(self, target_cfg):
        ctx = self.base_context()

        compiled = {}
        for (key, value) in target_cfg.items():
            is_str = isinstance(value, dbt.compat.basestring)

            if is_str:
                compiled_val = dbt.clients.jinja.get_rendered(value, ctx)
            else:
                compiled_val = value

            compiled[key] = compiled_val

        if self.args and hasattr(self.args, 'threads') and self.args.threads:
            compiled['threads'] = self.args.threads

        return compiled

    def compile_and_update_target(self):
        target = self.cfg['target']
        run_env = self.run_environment()
        self.cfg['outputs'][target].update(run_env)

    def run_environment(self):
        target_name = self.cfg['target']
        if target_name in self.cfg['outputs']:
            target_cfg = self.cfg['outputs'][target_name]
            return self.compile_target(target_cfg)
        else:

            outputs = self.cfg.get('outputs', {}).keys()
            output_names = [" - {}".format(output) for output in outputs]

            msg = ("The profile '{}' does not have a target named '{}'. The "
                   "valid target names for this profile are:\n{}".format(
                        self.profile_to_load,
                        target_name,
                        "\n".join(output_names)))

            raise DbtProfileError(msg, self)

    def get_target(self):
        ctx = self.context().get('env').copy()
        ctx['name'] = self.cfg['target']
        return ctx

    def base_context(self):
        return {
            'env_var': dbt.context.common._env_var
        }

    def context(self):
        target_cfg = self.run_environment()
        filtered_target = copy.deepcopy(target_cfg)
        filtered_target.pop('pass', None)

        ctx = self.base_context()
        ctx.update({
            'env': filtered_target
        })

        return ctx

    def validate(self):
{'fraction_non_alphanumeric': 0.11863342898134864, 'fraction_numerical': 0.0002690100430416069, 'mean_word_length': 2.554174633524538, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '5165878', 'n_tokens_mistral': 3420, 'n_tokens_neox': 3311, 'n_words': 774}