From f23a4034680806e6ae9a4cbea39e07d37e47930a Mon Sep 17 00:00:00 2001 From: Stu Kilgore Date: Tue, 12 Apr 2022 14:36:55 -0500 Subject: [PATCH] Update version output and logic (#5029) Update version output and logic --- .../Under the Hood-20220411-154626.yaml | 7 + core/dbt/version.py | 256 ++++++++++----- tests/unit/test_version.py | 308 +++++++++++------- 3 files changed, 370 insertions(+), 201 deletions(-) create mode 100644 .changes/unreleased/Under the Hood-20220411-154626.yaml diff --git a/.changes/unreleased/Under the Hood-20220411-154626.yaml b/.changes/unreleased/Under the Hood-20220411-154626.yaml new file mode 100644 index 00000000000..6c81f97327a --- /dev/null +++ b/.changes/unreleased/Under the Hood-20220411-154626.yaml @@ -0,0 +1,7 @@ +kind: Under the Hood +body: Update --version output and logic +time: 2022-04-11T15:46:26.113705-05:00 +custom: + Author: stu-k + Issue: "4724" + PR: "5029" diff --git a/core/dbt/version.py b/core/dbt/version.py index 16f29873cd0..4baaaa0aa66 100644 --- a/core/dbt/version.py +++ b/core/dbt/version.py @@ -3,7 +3,7 @@ import os import glob import json -from typing import Iterator +from typing import Iterator, List, Optional, Tuple import requests @@ -16,7 +16,34 @@ PYPI_VERSION_URL = "https://pypi.org/pypi/dbt-core/json" -def get_latest_version(version_url: str = PYPI_VERSION_URL): +def get_version_information() -> str: + flags.USE_COLORS = True if not flags.USE_COLORS else None + + installed = get_installed_version() + latest = get_latest_version() + + core_msg_lines, core_info_msg = _get_core_msg_lines(installed, latest) + core_msg = _format_core_msg(core_msg_lines) + plugin_version_msg = _get_plugins_msg(installed) + + msg_lines = [core_msg] + + if core_info_msg != "": + msg_lines.append(core_info_msg) + + msg_lines.append(plugin_version_msg) + msg_lines.append("") + + return "\n\n".join(msg_lines) + + +def get_installed_version() -> dbt.semver.VersionSpecifier: + return dbt.semver.VersionSpecifier.from_version_string(__version__) + + +def get_latest_version( + version_url: str = PYPI_VERSION_URL, +) -> Optional[dbt.semver.VersionSpecifier]: try: resp = requests.get(version_url) data = resp.json() @@ -27,81 +54,168 @@ def get_latest_version(version_url: str = PYPI_VERSION_URL): return dbt.semver.VersionSpecifier.from_version_string(version_string) -def get_installed_version(): - return dbt.semver.VersionSpecifier.from_version_string(__version__) +def _get_core_msg_lines(installed, latest) -> Tuple[List[List[str]], str]: + installed_s = installed.to_version_string(skip_matcher=True) + installed_line = ["installed", installed_s, ""] + update_info = "" + if latest is None: + update_info = ( + " The latest version of dbt-core could not be determined!\n" + " Make sure that the following URL is accessible:\n" + f" {PYPI_VERSION_URL}" + ) + return [installed_line], update_info + + latest_s = latest.to_version_string(skip_matcher=True) + latest_line = ["latest", latest_s, green("Up to date!")] + + if installed > latest: + latest_line[2] = green("Ahead of latest version!") + elif installed < latest: + latest_line[2] = yellow("Update available!") + update_info = ( + " Your version of dbt-core is out of date!\n" + " You can find instructions for upgrading here:\n" + " https://docs.getdbt.com/docs/installation" + ) -def get_package_pypi_url(package_name: str) -> str: - return f"https://pypi.org/pypi/dbt-{package_name}/json" + return [ + installed_line, + latest_line, + ], update_info -def get_version_information(): - flags.USE_COLORS = True if not flags.USE_COLORS else None +def _format_core_msg(lines: List[List[str]]) -> str: + msg = "Core:\n" + msg_lines = [] - installed = get_installed_version() - latest = get_latest_version() + for name, version, update_msg in _pad_lines(lines, seperator=":"): + line_msg = f" - {name} {version}" + if update_msg != "": + line_msg += f" - {update_msg}" + msg_lines.append(line_msg) - installed_s = installed.to_version_string(skip_matcher=True) - if latest is None: - latest_s = "unknown" - else: - latest_s = latest.to_version_string(skip_matcher=True) - - version_msg = "installed version: {}\n" " latest version: {}\n\n".format( - installed_s, latest_s - ) - - plugin_version_msg = "Plugins:\n" - for plugin_name, version in _get_dbt_plugins_info(): - plugin_version = dbt.semver.VersionSpecifier.from_version_string(version) - latest_plugin_version = get_latest_version(version_url=get_package_pypi_url(plugin_name)) - plugin_update_msg = "" - if installed == plugin_version or ( - latest_plugin_version and plugin_version == latest_plugin_version - ): - compatibility_msg = green("Up to date!") - else: - if latest_plugin_version: - if installed.major == plugin_version.major: - compatibility_msg = yellow("Update available!") - else: - compatibility_msg = red("Out of date!") - plugin_update_msg = ( - " Your version of dbt-{} is out of date! " - "You can find instructions for upgrading here:\n" - " https://docs.getdbt.com/dbt-cli/install/overview\n\n" - ).format(plugin_name) - else: - compatibility_msg = yellow("No PYPI version available") - - plugin_version_msg += (" - {}: {} - {}\n" "{}").format( - plugin_name, version, compatibility_msg, plugin_update_msg - ) + return msg + "\n".join(msg_lines) - if latest is None: - return ( - "{}The latest version of dbt could not be determined!\n" - "Make sure that the following URL is accessible:\n{}\n\n{}".format( - version_msg, PYPI_VERSION_URL, plugin_version_msg - ) - ) - if installed == latest: - return f"{version_msg}{green('Up to date!')}\n\n{plugin_version_msg}" +def _get_plugins_msg(installed: dbt.semver.VersionSpecifier) -> str: + msg_lines = ["Plugins:"] - elif installed > latest: - return "{}Your version of dbt is ahead of the latest " "release!\n\n{}".format( - version_msg, plugin_version_msg + plugins = [] + display_update_msg = False + for name, version_s in _get_dbt_plugins_info(): + compatability_msg, needs_update = _get_plugin_msg_info(name, version_s, installed) + if needs_update: + display_update_msg = True + plugins.append([name, version_s, compatability_msg]) + + for plugin in _pad_lines(plugins, seperator=":"): + msg_lines.append(_format_single_plugin(plugin, "")) + + if display_update_msg: + update_msg = ( + " At least one plugin is out of date or incompatible with dbt-core.\n" + " You can find instructions for upgrading here:\n" + " https://docs.getdbt.com/docs/installation" ) + msg_lines += ["", update_msg] + + return "\n".join(msg_lines) + + +def _get_plugin_msg_info( + name: str, version_s: str, core: dbt.semver.VersionSpecifier +) -> Tuple[str, bool]: + plugin = dbt.semver.VersionSpecifier.from_version_string(version_s) + latest_plugin = get_latest_version(version_url=get_package_pypi_url(name)) + needs_update = False + + if plugin.major != core.major or plugin.minor != core.minor: + compatibility_msg = red("Not compatible!") + needs_update = True + return (compatibility_msg, needs_update) + + if not latest_plugin: + compatibility_msg = yellow("Could not determine latest version") + return (compatibility_msg, needs_update) + + if plugin < latest_plugin: + compatibility_msg = yellow("Update available!") + needs_update = True + elif plugin > latest_plugin: + compatibility_msg = green("Ahead of latest version!") else: - return ( - "{}Your version of dbt is out of date! " - "You can find instructions for upgrading here:\n" - "https://docs.getdbt.com/docs/installation\n\n{}".format( - version_msg, plugin_version_msg - ) - ) + compatibility_msg = green("Up to date!") + + return (compatibility_msg, needs_update) + + +def _format_single_plugin(plugin: List[str], update_msg: str) -> str: + name, version_s, compatability_msg = plugin + msg = f" - {name} {version_s} - {compatability_msg}" + if update_msg != "": + msg += f"\n{update_msg}\n" + return msg + + +def _pad_lines(lines: List[List[str]], seperator: str = "") -> List[List[str]]: + if len(lines) == 0: + return [] + + # count the max line length for each column in the line + counter = [0] * len(lines[0]) + for line in lines: + for i, item in enumerate(line): + counter[i] = max(counter[i], len(item)) + + result: List[List[str]] = [] + for i, line in enumerate(lines): + + # add another list to hold padded strings + if len(result) == i: + result.append([""] * len(line)) + + # iterate over columns in the line + for j, item in enumerate(line): + + # the last column does not need padding + if j == len(line) - 1: + result[i][j] = item + continue + + # if the following column has no length + # the string does not need padding + if counter[j + 1] == 0: + result[i][j] = item + continue + + # only add the seperator to the first column + offset = 0 + if j == 0 and seperator != "": + item += seperator + offset = len(seperator) + + result[i][j] = item.ljust(counter[j] + offset) + + return result + + +def get_package_pypi_url(package_name: str) -> str: + return f"https://pypi.org/pypi/dbt-{package_name}/json" + + +def _get_dbt_plugins_info() -> Iterator[Tuple[str, str]]: + for plugin_name in _get_adapter_plugin_names(): + if plugin_name == "core": + continue + try: + mod = importlib.import_module(f"dbt.adapters.{plugin_name}.__version__") + except ImportError: + # not an adapter + continue + yield plugin_name, mod.version # type: ignore def _get_adapter_plugin_names() -> Iterator[str]: @@ -120,17 +234,5 @@ def _get_adapter_plugin_names() -> Iterator[str]: yield plugin_name -def _get_dbt_plugins_info(): - for plugin_name in _get_adapter_plugin_names(): - if plugin_name == "core": - continue - try: - mod = importlib.import_module(f"dbt.adapters.{plugin_name}.__version__") - except ImportError: - # not an adapter - continue - yield plugin_name, mod.version - - __version__ = "1.1.0b1" installed = get_installed_version() diff --git a/tests/unit/test_version.py b/tests/unit/test_version.py index b926c42376c..6545891fc54 100644 --- a/tests/unit/test_version.py +++ b/tests/unit/test_version.py @@ -16,14 +16,14 @@ def test_all_versions_equal(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", f" - foobar: 1.0.0 - {green('Up to date!')}", "", + "", ] ) @@ -42,14 +42,14 @@ def test_core_ahead(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.1", - " latest version: 1.0.0", - "", - "Your version of dbt is ahead of the latest release!", + "Core:", + " - installed: 1.0.1", + f" - latest: 1.0.0 - {yellow('Ahead of latest version!')}", "", "Plugins:", f" - foobar: 1.0.0 - {green('Up to date!')}", "", + "", ] ) @@ -68,15 +68,18 @@ def test_core_behind(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.1", + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.1 - {yellow('Update available!')}", "", - "Your version of dbt is out of date! You can find instructions for upgrading here:", - "https://docs.getdbt.com/docs/installation", + " Your version of dbt-core is out of date!", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", "", "Plugins:", f" - foobar: 1.0.0 - {green('Up to date!')}", "", + "", ] ) @@ -94,16 +97,17 @@ def test_core_no_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: unknown", + "Core:", + " - installed: 1.0.0", "", - "The latest version of dbt could not be determined!", - "Make sure that the following URL is accessible:", - "https://pypi.org/pypi/dbt-core/json", + " The latest version of dbt-core could not be determined!", + " Make sure that the following URL is accessible:", + " https://pypi.org/pypi/dbt-core/json", "", "Plugins:", f" - foobar: 1.0.0 - {green('Up to date!')}", "", + "", ] ) @@ -119,13 +123,13 @@ def test_plugins_none(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", "", + "", ] ) @@ -147,17 +151,17 @@ def test_plugins_multiple(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {green('Up to date!')}", - f" - bazqux: 1.0.0 - {green('Up to date!')}", - f" - quuxcorge: 1.0.0 - {green('Up to date!')}", + f" - foobar: 1.0.0 - {green('Up to date!')}", + f" - bazqux: 1.0.0 - {green('Up to date!')}", + f" - quuxcorge: 1.0.0 - {green('Up to date!')}", f" - graultgarply: 1.0.0 - {green('Up to date!')}", "", + "", ] ) @@ -176,14 +180,14 @@ def test_plugin_match_core_match_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", f" - foobar: 1.0.0 - {green('Up to date!')}", "", + "", ] ) @@ -202,13 +206,13 @@ def test_plugin_match_core_no_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {green('Up to date!')}", + f" - foobar: 1.0.0 - {yellow('Could not determine latest version')}", + "", "", ] ) @@ -228,13 +232,17 @@ def test_plugin_match_core_behind_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {green('Up to date!')}", + f" - foobar: 1.0.0 - {yellow('Update available!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", "", ] ) @@ -254,13 +262,17 @@ def test_plugin_match_core_ahead_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {green('Up to date!')}", + f" - foobar: 1.0.0 - {yellow('Update available!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", "", ] ) @@ -280,13 +292,17 @@ def test_plugin_diff_core_major_match_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 2.0.0", - " latest version: 2.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 2.0.0", + f" - latest: 2.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {green('Up to date!')}", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", "", ] ) @@ -306,13 +322,17 @@ def test_plugin_diff_core_major_no_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 2.0.0", - " latest version: 2.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 2.0.0", + f" - latest: 2.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {yellow('No PYPI version available')}", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", "", ] ) @@ -332,15 +352,16 @@ def test_plugin_diff_core_major_ahead_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 2.0.0", - " latest version: 2.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 2.0.0", + f" - latest: 2.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {red('Out of date!')}", - " Your version of dbt-foobar is out of date! You can find instructions for upgrading here:", - " https://docs.getdbt.com/dbt-cli/install/overview", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", "", "", ] @@ -361,15 +382,16 @@ def test_plugin_diff_core_major_behind_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 2.0.0", - " latest version: 2.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 2.0.0", + f" - latest: 2.0.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {red('Out of date!')}", - " Your version of dbt-foobar is out of date! You can find instructions for upgrading here:", - " https://docs.getdbt.com/dbt-cli/install/overview", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", "", "", ] @@ -390,13 +412,17 @@ def test_plugin_diff_core_minor_match_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.1.0", - " latest version: 1.1.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.1.0", + f" - latest: 1.1.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {green('Up to date!')}", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", "", ] ) @@ -416,13 +442,17 @@ def test_plugin_diff_core_minor_no_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.1.0", - " latest version: 1.1.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.1.0", + f" - latest: 1.1.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {yellow('No PYPI version available')}", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", "", ] ) @@ -442,15 +472,16 @@ def test_plugin_diff_core_minor_ahead_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.1.0", - " latest version: 1.1.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.1.0", + f" - latest: 1.1.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {yellow('Update available!')}", - " Your version of dbt-foobar is out of date! You can find instructions for upgrading here:", - " https://docs.getdbt.com/dbt-cli/install/overview", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", "", "", ] @@ -471,15 +502,16 @@ def test_plugin_diff_core_minor_behind_latest(self, mocker): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.1.0", - " latest version: 1.1.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.1.0", + f" - latest: 1.1.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 1.0.0 - {yellow('Update available!')}", - " Your version of dbt-foobar is out of date! You can find instructions for upgrading here:", - " https://docs.getdbt.com/dbt-cli/install/overview", + f" - foobar: 1.0.0 - {red('Not compatible!')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", "", "", ] @@ -494,35 +526,63 @@ def test_plugins_various(self, mocker): latest="2.1.0", plugins={ "foobar": ("2.1.0", "2.1.0"), - "bazqux": ("1.0.0", None), - "quuux": ("1.1.0", "1.1.0"), - "corge": ("2.2.2", "2.2.3"), - "grault": ("1.1.0", "1.2.3"), - "garply": ("2.1.0", None), + "bazqux": ("2.1.0", None), + "quuux": ("2.1.0", "2.1.0"), + "corge": ("22.21.20", "22.21.21"), + "grault": ("2.1.0", "2.1.1"), + "garply": ("2.1.0-b1", None), }, ) actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 2.1.0", - " latest version: 2.1.0", - "", - green("Up to date!"), + "Core:", + " - installed: 2.1.0", + f" - latest: 2.1.0 - {green('Up to date!')}", "", "Plugins:", - f" - foobar: 2.1.0 - {green('Up to date!')}", - f" - bazqux: 1.0.0 - {yellow('No PYPI version available')}", - f" - quuux: 1.1.0 - {green('Up to date!')}", - f" - corge: 2.2.2 - {yellow('Update available!')}", - " Your version of dbt-corge is out of date! You can find instructions for upgrading here:", - " https://docs.getdbt.com/dbt-cli/install/overview", + f" - foobar: 2.1.0 - {green('Up to date!')}", + f" - bazqux: 2.1.0 - {yellow('Could not determine latest version')}", + f" - quuux: 2.1.0 - {green('Up to date!')}", + f" - corge: 22.21.20 - {red('Not compatible!')}", + f" - grault: 2.1.0 - {yellow('Update available!')}", + f" - garply: 2.1.0-b1 - {yellow('Could not determine latest version')}", + "", + " At least one plugin is out of date or incompatible with dbt-core.", + " You can find instructions for upgrading here:", + " https://docs.getdbt.com/docs/installation", + "", + "", + ] + ) + + assert expected == actual + + def test_plugins_alignment(self, mocker): + mock_versions( + mocker, + installed="1.1.1-b123", + latest="1.1.1-b123", + plugins={ + "foobar": ("1.1.0-b1", "1.1.0-b1"), + "bazqux": ("1.1.1-b123", "1.1.1-b123"), + "quuux": ("1.1.0", "1.1.0"), + }, + ) + + actual = dbt.version.get_version_information() + expected = "\n".join( + [ + "Core:", + " - installed: 1.1.1-b123", + f" - latest: 1.1.1-b123 - {green('Up to date!')}", "", - f" - grault: 1.1.0 - {red('Out of date!')}", - " Your version of dbt-grault is out of date! You can find instructions for upgrading here:", - " https://docs.getdbt.com/dbt-cli/install/overview", + "Plugins:", + f" - foobar: 1.1.0-b1 - {green('Up to date!')}", + f" - bazqux: 1.1.1-b123 - {green('Up to date!')}", + f" - quuux: 1.1.0 - {green('Up to date!')}", "", - f" - garply: 2.1.0 - {green('Up to date!')}", "", ] ) @@ -592,18 +652,18 @@ def mock_import(*args, **kwargs): actual = dbt.version.get_version_information() expected = "\n".join( [ - "installed version: 1.0.0", - " latest version: 1.0.0", - "", - green("Up to date!"), + "Core:", + " - installed: 1.0.0", + f" - latest: 1.0.0 - {green('Up to date!')}", "", "Plugins:", - " - foobar: 1.0.0 - Up to date!", - " - bazqux: 1.0.0 - Up to date!", - " - quuux: 1.0.0 - Up to date!", - " - corge: 1.0.0 - Up to date!", - " - grault: 1.0.0 - Up to date!", - " - garply: 1.0.0 - Up to date!", + f" - foobar: 1.0.0 - {yellow('Could not determine latest version')}", + f" - bazqux: 1.0.0 - {yellow('Could not determine latest version')}", + f" - quuux: 1.0.0 - {yellow('Could not determine latest version')}", + f" - corge: 1.0.0 - {yellow('Could not determine latest version')}", + f" - grault: 1.0.0 - {yellow('Could not determine latest version')}", + f" - garply: 1.0.0 - {yellow('Could not determine latest version')}", + "", "", ] )