Repository: dbt-labs/dbt-core

Issue:
Provide an interface to throw warnings
### Describe the feature
Currently, we have a jinja interface to throw a compilation error, [exceptions](https://docs.getdbt.com/docs/exceptions):
```
  {{ exceptions.raise_compiler_error("Invalid `number`. Got: " ~ number) }}
```
I want a similar interface to throw warnings. Preferably, these warnings should fail when the `--warn-error` flag is used.

My particular use case is to throw warnings for macros in dbt-utils that are being deprecated (see [here](https://github.com/fishtown-analytics/dbt-utils/pull/178/files#diff-5a934804d9d538a70a2455093e434399R26)).

### Describe alternatives you've considered
Here's how I currently do it:
```
    {% if execute %}
        {{ log("Warning: the `get_tables_by_prefix` macro is no longer supported and will be deprecated in a future release of dbt-utils. Use the `get_relations_by_prefix` macro instead", info=True) }}
    {% endif %}
```
Note that the warning is wrapped in an `execute` so that dbt doesn't log this when parsing the project (including macros).


### Who will this benefit?
Package maintainers.



Discussion:
From Drew:
> I think the easier path is to export the warn_or_error method (or something similar with maybe a clearer name): https://github.com/fishtown-analytics/dbt/blob/dev/0.15.1/core/dbt/exceptions.py#L740
The big difference between a Deprecation and just calling warn_or_error  is that a deprecation warning will only be shown once even if that deprecation is “warned” multiple times. If that’s beneficial for the macro use case then we can figure out how to make it happen. If it’s not necessary then there are other simpler options here too
I just prioritized this issue for the 0.15.1 release

Resolving patch:
diff --git a/core/dbt/exceptions.py b/core/dbt/exceptions.py
--- a/core/dbt/exceptions.py
+++ b/core/dbt/exceptions.py
@@ -756,12 +756,19 @@ def warn_or_raise(exc, log_fmt=None):
         logger.warning(msg)
 
 
+def warn(msg, node=None):
+    # there's no reason to expose log_fmt to macros - it's only useful for
+    # handling colors
+    return warn_or_error(msg, node=node)
+
+
 # Update this when a new function should be added to the
 # dbt context's `exceptions` key!
 CONTEXT_EXPORTS = {
     fn.__name__: fn
     for fn in
     [
+        warn,
         missing_config,
         missing_materialization,
         missing_relation,


Test patch:
diff --git a/test/integration/013_context_var_tests/emit-warning-models/warnings.sql b/test/integration/013_context_var_tests/emit-warning-models/warnings.sql
new file mode 100644
--- /dev/null
+++ b/test/integration/013_context_var_tests/emit-warning-models/warnings.sql
@@ -0,0 +1,2 @@
+{% do exceptions.warn('warning: everything is terrible but not that terrible') %}
+select 1 as id
diff --git a/test/integration/013_context_var_tests/test_context_vars.py b/test/integration/013_context_var_tests/test_context_vars.py
--- a/test/integration/013_context_var_tests/test_context_vars.py
+++ b/test/integration/013_context_var_tests/test_context_vars.py
@@ -2,6 +2,10 @@
 
 import os
 
+import pytest
+
+import dbt.exceptions
+
 
 class TestContextVars(DBTIntegrationTest):
 
@@ -133,3 +137,19 @@ def test_postgres_env_vars_prod(self):
         self.assertEqual(ctx['target.user'], 'root')
         self.assertEqual(ctx['target.pass'], '')
         self.assertEqual(ctx['env_var'], '1')
+
+
+class TestEmitWarning(DBTIntegrationTest):
+    @property
+    def schema(self):
+        return "context_vars_013"
+
+    @property
+    def models(self):
+        return "emit-warning-models"
+
+    @use_profile('postgres')
+    def test_postgres_warn(self):
+        with pytest.raises(dbt.exceptions.CompilationException):
+            self.run_dbt(['run'], strict=True)
+        self.run_dbt(['run'], strict=False, expect_pass=True)