Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
24 changes: 5 additions & 19 deletions core/dbt/cli/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from dbt.config.profile import read_user_config
from dbt.contracts.project import UserConfig
from dbt.helper_types import WarnErrorOptions
from dbt.config.project import PartialProject
from dbt.exceptions import DbtProjectError
from dbt.cli.resolvers import default_project_dir, default_log_path


if os.name != "nt":
# https://bugs.python.org/issue41567
Expand Down Expand Up @@ -132,23 +132,9 @@ def assign_params(ctx, params_assigned_from_default):

# Default LOG_PATH from PROJECT_DIR, if available.
if getattr(self, "LOG_PATH", None) is None:
log_path = "logs"
project_dir = getattr(self, "PROJECT_DIR", None)
# If available, set LOG_PATH from log-path in dbt_project.yml
# Known limitations:
# 1. Using PartialProject here, so no jinja rendering of log-path.
# 2. Programmatic invocations of the cli via dbtRunner may pass a Project object directly,
# which is not being used here to extract log-path.
if project_dir:
try:
partial = PartialProject.from_project_root(
project_dir, verify_version=getattr(self, "VERSION_CHECK", True)
)
log_path = str(partial.project_dict.get("log-path", log_path))
except DbtProjectError:
pass

object.__setattr__(self, "LOG_PATH", log_path)
project_dir = getattr(self, "PROJECT_DIR", default_project_dir())
version_check = getattr(self, "VERSION_CHECK", True)
object.__setattr__(self, "LOG_PATH", default_log_path(project_dir, version_check))

# Support console DO NOT TRACK initiave
if os.getenv("DO_NOT_TRACK", "").lower() in ("1", "t", "true", "y", "yes"):
Expand Down
24 changes: 22 additions & 2 deletions core/dbt/cli/resolvers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
from pathlib import Path
from dbt.config.project import PartialProject
from dbt.exceptions import DbtProjectError


def default_project_dir():
def default_project_dir() -> Path:
paths = list(Path.cwd().parents)
paths.insert(0, Path.cwd())
return next((x for x in paths if (x / "dbt_project.yml").exists()), Path.cwd())


def default_profiles_dir():
def default_profiles_dir() -> Path:
return Path.cwd() if (Path.cwd() / "profiles.yml").exists() else Path.home() / ".dbt"


def default_log_path(project_dir: Path, verify_version: bool = False) -> Path:
"""If available, derive a default log path from dbt_project.yml. Otherwise, default to "logs".
Known limitations:
1. Using PartialProject here, so no jinja rendering of log-path.
2. Programmatic invocations of the cli via dbtRunner may pass a Project object directly,
which is not being taken into consideration here to extract a log-path.
"""
default_log_path = Path("logs")
try:
partial = PartialProject.from_project_root(str(project_dir), verify_version=verify_version)
partial_log_path = partial.project_dict.get("log-path") or default_log_path
default_log_path = Path(project_dir) / partial_log_path
except DbtProjectError:
pass

return default_log_path
Binary file modified core/dbt/docs/build/doctrees/environment.pickle
Binary file not shown.
35 changes: 35 additions & 0 deletions tests/functional/cli/test_resolvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import pytest
from dbt.cli.resolvers import default_log_path
from pathlib import Path


class TestDefaultLogPathNoProject:
def test_default_log_path_no_project(self):
expected_log_path = Path("logs")
actual_log_path = default_log_path("nonexistent_project_dir")

assert actual_log_path == expected_log_path


class TestDefaultLogPathWithProject:
@pytest.fixture(scope="class")
def project_config_update(self):
return {"log-path": "test_default_log_path"}

def test_default_log_path_with_project(self, project, project_config_update):
expected_log_path = Path(project.project_root) / "test_default_log_path"
actual_log_path = default_log_path(project.project_root)

assert actual_log_path == expected_log_path


class TestDefaultLogPathWithProjectNoConfiguredLogPath:
@pytest.fixture(scope="class")
def project_config_update(self):
return {"log-path": None}

def test_default_log_path_with_project(self, project, project_config_update):
expected_log_path = Path(project.project_root) / "logs"
actual_log_path = default_log_path(project.project_root)

assert actual_log_path == expected_log_path
3 changes: 2 additions & 1 deletion tests/unit/test_cli_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import click
from multiprocessing import get_context
from pathlib import Path
from typing import List

from dbt.cli.main import cli
Expand Down Expand Up @@ -42,7 +43,7 @@ def test_cli_group_flags_from_params(self, run_context, param):
def test_log_path_default(self, run_context):
flags = Flags(run_context)
assert hasattr(flags, "LOG_PATH")
assert getattr(flags, "LOG_PATH") == "logs"
assert getattr(flags, "LOG_PATH") == Path("logs")

@pytest.mark.parametrize(
"set_stats_param,do_not_track,expected_anonymous_usage_stats",
Expand Down