Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ and this project adheres to

## [Unreleased]

- **Breaking**: The rule `public_model_has_example_sql` has been renamed
`has_example_sql` and applies by default to all models.
- **Breaking**: Remove `dbt-core` from dependencies. Since it is not mandatory
for `dbt-score` to execute `dbt`, remove the dependency.

## [0.6.0] - 2024-08-23

- **Breaking**: Improve error handling in CLI. Log messages are written in
Expand Down
1,478 changes: 480 additions & 998 deletions pdm.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ classifiers = [
]

dependencies = [
"dbt-core>=1.5",
"click>=7.1.1, <9.0.0",
"tomli>=1.1.0; python_version<'3.11'",
]
Expand Down
12 changes: 9 additions & 3 deletions src/dbt_score/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@

import click
from click.core import ParameterSource
from dbt.cli.options import MultiOption

from dbt_score.config import Config
from dbt_score.dbt_utils import DbtParseException, dbt_parse, get_default_manifest_path
from dbt_score.dbt_utils import ( # type: ignore[attr-defined]
DBT_INSTALLED,
DbtParseException,
MultiOption,
dbt_parse,
get_default_manifest_path,
)
from dbt_score.lint import lint_dbt_project
from dbt_score.rule_catalog import display_catalog

Expand Down Expand Up @@ -48,9 +53,10 @@ def cli() -> None:
"--select",
"-s",
help="Specify the nodes to include.",
cls=MultiOption,
cls=MultiOption if DBT_INSTALLED else None,
type=tuple,
multiple=True,
hidden=not DBT_INSTALLED, # Only include if dbt is installed
)
@click.option(
"--namespace",
Expand Down
29 changes: 25 additions & 4 deletions src/dbt_score/dbt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@
from pathlib import Path
from typing import Iterable, Iterator, cast

from dbt.cli.main import dbtRunner, dbtRunnerResult
# Conditionally import dbt objects.
try:
DBT_INSTALLED = True
from dbt.cli.main import dbtRunner, dbtRunnerResult # type: ignore
from dbt.cli.options import MultiOption # type: ignore
except ImportError:
DBT_INSTALLED = False
MultiOption = None


class DbtNotInstalledException(Exception):
"""Raised when trying to run dbt when dbt is not installed."""


class DbtParseException(Exception):
Expand All @@ -22,7 +33,7 @@ def _disable_dbt_stdout() -> Iterator[None]:
yield


def dbt_parse() -> dbtRunnerResult:
def dbt_parse() -> "dbtRunnerResult":
"""Parse a dbt project.

Returns:
Expand All @@ -31,8 +42,13 @@ def dbt_parse() -> dbtRunnerResult:
Raises:
DbtParseException: dbt parse failed.
"""
if not DBT_INSTALLED:
raise DbtNotInstalledException(
"To execute dbt parse, install dbt-core in your environment."
)

with _disable_dbt_stdout():
result: dbtRunnerResult = dbtRunner().invoke(["parse"])
result: "dbtRunnerResult" = dbtRunner().invoke(["parse"])

if not result.success:
raise DbtParseException("dbt parse failed.") from result.exception
Expand All @@ -42,12 +58,17 @@ def dbt_parse() -> dbtRunnerResult:

def dbt_ls(select: Iterable[str] | None) -> Iterable[str]:
"""Run dbt ls."""
if not DBT_INSTALLED:
raise DbtNotInstalledException(
"To execute dbt ls, install dbt-core in your environment."
)

cmd = ["ls", "--resource-type", "model", "--output", "name"]
if select:
cmd += ["--select", *select]

with _disable_dbt_stdout():
result: dbtRunnerResult = dbtRunner().invoke(cmd)
result: "dbtRunnerResult" = dbtRunner().invoke(cmd)

if not result.success:
raise DbtLsException("dbt ls failed.") from result.exception
Expand Down
19 changes: 19 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,25 @@ def test_lint_dbt_parse_exception(caplog):
assert "dbt failed to parse project" in caplog.text


def test_lint_dbt_not_installed(caplog, manifest_path):
"""Test lint with a valid manifest when dbt is not installed."""
runner = CliRunner()

with patch("dbt_score.cli.DBT_INSTALLED", new=False):
result = runner.invoke(lint, ["-m", manifest_path], catch_exceptions=False)
assert result.exit_code == 0


def test_lint_dbt_not_installed_v(caplog):
"""Test lint with dbt parse when dbt is not installed."""
runner = CliRunner()

with patch("dbt_score.dbt_utils.DBT_INSTALLED", new=False):
result = runner.invoke(lint, ["-p"])
assert result.exit_code == 2
assert "DbtNotInstalledException" in caplog.text


def test_lint_other_exception(manifest_path, caplog):
"""Test lint with an unexpected error."""
runner = CliRunner()
Expand Down