diff --git a/.changes/unreleased/Fixes-20240516-153913.yaml b/.changes/unreleased/Fixes-20240516-153913.yaml new file mode 100644 index 00000000000..b96f45e2c37 --- /dev/null +++ b/.changes/unreleased/Fixes-20240516-153913.yaml @@ -0,0 +1,7 @@ +kind: Fixes +body: Fix json format log and --quiet for ls and jinja print by converting print call + to fire events +time: 2024-05-16T15:39:13.896723-07:00 +custom: + Author: ChenyuLInx + Issue: "8756" diff --git a/core/dbt/context/base.py b/core/dbt/context/base.py index b989afd2078..5b8fd45e350 100644 --- a/core/dbt/context/base.py +++ b/core/dbt/context/base.py @@ -38,6 +38,7 @@ from dbt_common.context import get_invocation_context from dbt_common.events.contextvars import get_node_info from dbt_common.events.functions import fire_event, get_invocation_id +from dbt_common.events.types import PrintEvent from dbt_common.exceptions.macros import MacroReturn # See the `contexts` module README for more information on how contexts work @@ -683,7 +684,8 @@ def print(msg: str) -> str: """ if get_flags().PRINT: - print(msg) + # No formatting, still get to stdout when --quiet is used + fire_event(PrintEvent(msg=msg)) return "" @contextmember() diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index 224030893aa..6a00a237b90 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -1982,6 +1982,7 @@ def message(self) -> str: class ListCmdOut(InfoLevel): + # No longer in use, switching to Z051 PrintEvent in dbt-common def code(self) -> str: return "Z049" diff --git a/core/dbt/task/list.py b/core/dbt/task/list.py index 11d1ed1049e..09358df4ffe 100644 --- a/core/dbt/task/list.py +++ b/core/dbt/task/list.py @@ -11,8 +11,7 @@ SourceDefinition, UnitTestDefinition, ) -from dbt.events.types import ListCmdOut, NoNodesSelected -from dbt.flags import get_flags +from dbt.events.types import NoNodesSelected from dbt.graph import ResourceTypeSelector from dbt.node_types import NodeType from dbt.task.base import resource_types_from_args @@ -20,6 +19,7 @@ from dbt.task.test import TestSelector from dbt_common.events.contextvars import task_contextvars from dbt_common.events.functions import fire_event, warn_or_error +from dbt_common.events.types import PrintEvent from dbt_common.exceptions import DbtInternalError, DbtRuntimeError @@ -172,11 +172,8 @@ def output_results(self, results): """Log, or output a plain, newline-delimited, and ready-to-pipe list of nodes found.""" for result in results: self.node_results.append(result) - if get_flags().LOG_FORMAT == "json": - fire_event(ListCmdOut(msg=result)) - else: - # Cleaner to leave as print than to mutate the logger not to print timestamps. - print(result) + # No formatting, still get to stdout when --quiet is used + fire_event(PrintEvent(msg=result)) return self.node_results @property diff --git a/core/setup.py b/core/setup.py index 052a45285ce..e133b946fa4 100644 --- a/core/setup.py +++ b/core/setup.py @@ -71,7 +71,7 @@ "minimal-snowplow-tracker>=0.0.2,<0.1", "dbt-semantic-interfaces>=0.5.1,<0.6", # Minor versions for these are expected to be backwards-compatible - "dbt-common>=1.0.4,<2.0", + "dbt-common>=1.1.0,<2.0", "dbt-adapters>=1.1.1,<2.0", # ---- # Expect compatibility with all new versions of these packages, so lower bounds only. diff --git a/tests/unit/task/test_list.py b/tests/unit/task/test_list.py new file mode 100644 index 00000000000..da701fe2fcf --- /dev/null +++ b/tests/unit/task/test_list.py @@ -0,0 +1,22 @@ +from argparse import Namespace +from unittest.mock import patch + +from dbt.flags import get_flags, set_from_args +from dbt.task.list import ListTask +from dbt_common.events.types import PrintEvent + + +def test_list_output_results(): + set_from_args(Namespace(models=None), {}) + task = ListTask(get_flags(), None, None) + results = ["node1", "node2", "node3"] + expected_node_results = ["node1", "node2", "node3"] + + with patch("dbt.task.list.fire_event") as mock_fire_event: + node_results = task.output_results(results) + + assert node_results == expected_node_results + # assert called with PrintEvent type object and message 'node1', 'node2', 'node3' + for call_args in mock_fire_event.call_args_list: + assert isinstance(call_args[0][0], PrintEvent) + assert call_args[0][0].msg in expected_node_results