Repository: dbt-labs/dbt-core

Issue:
[CT-217] add `--no-print` flag
### Is there an existing feature request for this?

- [X] I have searched the existing issues

### Describe the Feature

Add a flag to suppress `{{ print(msg) }}` messages coming out of macros.  Docs for `print` to be added [here](https://github.com/dbt-labs/docs.getdbt.com/blob/current/website/docs/reference/dbt-jinja-functions.md).

`print` functionality in macros was added in as part of #3451 but there is currently no way to keep the messages from being printed to stdout.  This can result in these messages interspersed with logs going to stdout.

The change will involve adding a flag to [`flags.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/flags.py) and [`main.py`](https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/main.py) called `--no-print`.   Copying the way `quiet` was implemented will get you where you need to go.

Logic also needs to be added to stop printing to stdout.  This can be accomplished by wrapping the `print` command with an if statement for when the `--no-print` flag is false.

https://github.com/dbt-labs/dbt-core/blob/41c6177ae2c85343426c5af53f9e23451e762619/core/dbt/context/base.py#L576-L588

Once this is all done, `docs.dbt.com` will also need top be updated.  Specifically, [this page](https://github.com/dbt-labs/docs.getdbt.com/blob/current/website/docs/reference/global-configs.md).  Open an issue over in that repo for that piece of this.

### Describe alternatives you've considered

Not doing this simply means that `{{ print(msg) }}` will always `print` to stdout.  

### Who will this benefit?

Right now, anything sent to stdout using `{{ print(msg) }}` will get printed to stdout all the time with no way to suppress it.  This will allow anyone using macros utilizing `print` to suppress those messages.

### Are you interested in contributing this feature?

_No response_

### Anything else?

_No response_


Discussion:
Hi @emmyoop 👋  Thanks for all of your help on https://github.com/dbt-labs/dbt-core/issues/3451 My coworker @poloaraujo and I are planning to take a crack at this! We'll get going next week.

Resolving patch:
diff --git a/core/dbt/context/base.py b/core/dbt/context/base.py
--- a/core/dbt/context/base.py
+++ b/core/dbt/context/base.py
@@ -569,7 +569,9 @@ def print(msg: str) -> str:
               {{ print("Running some_macro: " ~ arg1 ~ ", " ~ arg2) }}
             {% endmacro %}"
         """
-        print(msg)
+
+        if not flags.NO_PRINT:
+            print(msg)
         return ""
 
 
diff --git a/core/dbt/flags.py b/core/dbt/flags.py
--- a/core/dbt/flags.py
+++ b/core/dbt/flags.py
@@ -35,6 +35,7 @@
 LOG_CACHE_EVENTS = None
 EVENT_BUFFER_SIZE = 100000
 QUIET = None
+NO_PRINT = None
 
 # Global CLI defaults. These flags are set from three places:
 # CLI args, environment variables, and user_config (profiles.yml).
@@ -57,6 +58,7 @@
     "LOG_CACHE_EVENTS": False,
     "EVENT_BUFFER_SIZE": 100000,
     "QUIET": False,
+    "NO_PRINT": False,
 }
 
 
@@ -106,7 +108,7 @@ def set_from_args(args, user_config):
     global STRICT_MODE, FULL_REFRESH, WARN_ERROR, USE_EXPERIMENTAL_PARSER, STATIC_PARSER
     global WRITE_JSON, PARTIAL_PARSE, USE_COLORS, STORE_FAILURES, PROFILES_DIR, DEBUG, LOG_FORMAT
     global INDIRECT_SELECTION, VERSION_CHECK, FAIL_FAST, SEND_ANONYMOUS_USAGE_STATS
-    global PRINTER_WIDTH, WHICH, LOG_CACHE_EVENTS, EVENT_BUFFER_SIZE, QUIET
+    global PRINTER_WIDTH, WHICH, LOG_CACHE_EVENTS, EVENT_BUFFER_SIZE, QUIET, NO_PRINT
 
     STRICT_MODE = False  # backwards compatibility
     # cli args without user_config or env var option
@@ -132,6 +134,7 @@ def set_from_args(args, user_config):
     LOG_CACHE_EVENTS = get_flag_value("LOG_CACHE_EVENTS", args, user_config)
     EVENT_BUFFER_SIZE = get_flag_value("EVENT_BUFFER_SIZE", args, user_config)
     QUIET = get_flag_value("QUIET", args, user_config)
+    NO_PRINT = get_flag_value("NO_PRINT", args, user_config)
 
 
 def get_flag_value(flag, args, user_config):
@@ -185,4 +188,5 @@ def get_flag_dict():
         "log_cache_events": LOG_CACHE_EVENTS,
         "event_buffer_size": EVENT_BUFFER_SIZE,
         "quiet": QUIET,
+        "no_print": NO_PRINT,
     }
diff --git a/core/dbt/main.py b/core/dbt/main.py
--- a/core/dbt/main.py
+++ b/core/dbt/main.py
@@ -1088,6 +1088,15 @@ def parse_args(args, cls=DBTArgumentParser):
         """,
     )
 
+    p.add_argument(
+        "--no-print",
+        action="store_true",
+        default=None,
+        help="""
+        Suppress all {{ print() }} macro calls.
+        """,
+    )
+
     subs = p.add_subparsers(title="Available sub-commands")
 
     base_subparser = _build_base_subparser()


Test patch:
diff --git a/test/unit/test_flags.py b/test/unit/test_flags.py
--- a/test/unit/test_flags.py
+++ b/test/unit/test_flags.py
@@ -224,3 +224,10 @@ def test__flags(self):
         self.assertEqual(flags.QUIET, True)
         # cleanup
         self.user_config.quiet = None
+
+        # no_print
+        self.user_config.no_print = True
+        flags.set_from_args(self.args, self.user_config)
+        self.assertEqual(flags.NO_PRINT, True)
+        # cleanup
+        self.user_config.no_print = None