dvt-core 1.11.0b4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dvt-core might be problematic. Click here for more details.
- dvt/__init__.py +7 -0
- dvt/_pydantic_shim.py +26 -0
- dvt/adapters/__init__.py +16 -0
- dvt/adapters/multi_adapter_manager.py +268 -0
- dvt/artifacts/__init__.py +0 -0
- dvt/artifacts/exceptions/__init__.py +1 -0
- dvt/artifacts/exceptions/schemas.py +31 -0
- dvt/artifacts/resources/__init__.py +116 -0
- dvt/artifacts/resources/base.py +68 -0
- dvt/artifacts/resources/types.py +93 -0
- dvt/artifacts/resources/v1/analysis.py +10 -0
- dvt/artifacts/resources/v1/catalog.py +23 -0
- dvt/artifacts/resources/v1/components.py +275 -0
- dvt/artifacts/resources/v1/config.py +282 -0
- dvt/artifacts/resources/v1/documentation.py +11 -0
- dvt/artifacts/resources/v1/exposure.py +52 -0
- dvt/artifacts/resources/v1/function.py +53 -0
- dvt/artifacts/resources/v1/generic_test.py +32 -0
- dvt/artifacts/resources/v1/group.py +22 -0
- dvt/artifacts/resources/v1/hook.py +11 -0
- dvt/artifacts/resources/v1/macro.py +30 -0
- dvt/artifacts/resources/v1/metric.py +173 -0
- dvt/artifacts/resources/v1/model.py +146 -0
- dvt/artifacts/resources/v1/owner.py +10 -0
- dvt/artifacts/resources/v1/saved_query.py +112 -0
- dvt/artifacts/resources/v1/seed.py +42 -0
- dvt/artifacts/resources/v1/semantic_layer_components.py +72 -0
- dvt/artifacts/resources/v1/semantic_model.py +315 -0
- dvt/artifacts/resources/v1/singular_test.py +14 -0
- dvt/artifacts/resources/v1/snapshot.py +92 -0
- dvt/artifacts/resources/v1/source_definition.py +85 -0
- dvt/artifacts/resources/v1/sql_operation.py +10 -0
- dvt/artifacts/resources/v1/unit_test_definition.py +78 -0
- dvt/artifacts/schemas/__init__.py +0 -0
- dvt/artifacts/schemas/base.py +191 -0
- dvt/artifacts/schemas/batch_results.py +24 -0
- dvt/artifacts/schemas/catalog/__init__.py +12 -0
- dvt/artifacts/schemas/catalog/v1/__init__.py +0 -0
- dvt/artifacts/schemas/catalog/v1/catalog.py +60 -0
- dvt/artifacts/schemas/freshness/__init__.py +1 -0
- dvt/artifacts/schemas/freshness/v3/__init__.py +0 -0
- dvt/artifacts/schemas/freshness/v3/freshness.py +159 -0
- dvt/artifacts/schemas/manifest/__init__.py +2 -0
- dvt/artifacts/schemas/manifest/v12/__init__.py +0 -0
- dvt/artifacts/schemas/manifest/v12/manifest.py +212 -0
- dvt/artifacts/schemas/results.py +148 -0
- dvt/artifacts/schemas/run/__init__.py +2 -0
- dvt/artifacts/schemas/run/v5/__init__.py +0 -0
- dvt/artifacts/schemas/run/v5/run.py +184 -0
- dvt/artifacts/schemas/upgrades/__init__.py +4 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
- dvt/artifacts/utils/validation.py +153 -0
- dvt/cli/__init__.py +1 -0
- dvt/cli/context.py +16 -0
- dvt/cli/exceptions.py +56 -0
- dvt/cli/flags.py +558 -0
- dvt/cli/main.py +971 -0
- dvt/cli/option_types.py +121 -0
- dvt/cli/options.py +79 -0
- dvt/cli/params.py +803 -0
- dvt/cli/requires.py +478 -0
- dvt/cli/resolvers.py +32 -0
- dvt/cli/types.py +40 -0
- dvt/clients/__init__.py +0 -0
- dvt/clients/checked_load.py +82 -0
- dvt/clients/git.py +164 -0
- dvt/clients/jinja.py +206 -0
- dvt/clients/jinja_static.py +245 -0
- dvt/clients/registry.py +192 -0
- dvt/clients/yaml_helper.py +68 -0
- dvt/compilation.py +833 -0
- dvt/compute/__init__.py +26 -0
- dvt/compute/base.py +288 -0
- dvt/compute/engines/__init__.py +13 -0
- dvt/compute/engines/duckdb_engine.py +368 -0
- dvt/compute/engines/spark_engine.py +273 -0
- dvt/compute/query_analyzer.py +212 -0
- dvt/compute/router.py +483 -0
- dvt/config/__init__.py +4 -0
- dvt/config/catalogs.py +95 -0
- dvt/config/compute_config.py +406 -0
- dvt/config/profile.py +411 -0
- dvt/config/profiles_v2.py +464 -0
- dvt/config/project.py +893 -0
- dvt/config/renderer.py +232 -0
- dvt/config/runtime.py +491 -0
- dvt/config/selectors.py +209 -0
- dvt/config/utils.py +78 -0
- dvt/connectors/.gitignore +6 -0
- dvt/connectors/README.md +306 -0
- dvt/connectors/catalog.yml +217 -0
- dvt/connectors/download_connectors.py +300 -0
- dvt/constants.py +29 -0
- dvt/context/__init__.py +0 -0
- dvt/context/base.py +746 -0
- dvt/context/configured.py +136 -0
- dvt/context/context_config.py +350 -0
- dvt/context/docs.py +82 -0
- dvt/context/exceptions_jinja.py +179 -0
- dvt/context/macro_resolver.py +195 -0
- dvt/context/macros.py +171 -0
- dvt/context/manifest.py +73 -0
- dvt/context/providers.py +2198 -0
- dvt/context/query_header.py +14 -0
- dvt/context/secret.py +59 -0
- dvt/context/target.py +74 -0
- dvt/contracts/__init__.py +0 -0
- dvt/contracts/files.py +413 -0
- dvt/contracts/graph/__init__.py +0 -0
- dvt/contracts/graph/manifest.py +1904 -0
- dvt/contracts/graph/metrics.py +98 -0
- dvt/contracts/graph/model_config.py +71 -0
- dvt/contracts/graph/node_args.py +42 -0
- dvt/contracts/graph/nodes.py +1806 -0
- dvt/contracts/graph/semantic_manifest.py +233 -0
- dvt/contracts/graph/unparsed.py +812 -0
- dvt/contracts/project.py +417 -0
- dvt/contracts/results.py +53 -0
- dvt/contracts/selection.py +23 -0
- dvt/contracts/sql.py +86 -0
- dvt/contracts/state.py +69 -0
- dvt/contracts/util.py +46 -0
- dvt/deprecations.py +347 -0
- dvt/deps/__init__.py +0 -0
- dvt/deps/base.py +153 -0
- dvt/deps/git.py +196 -0
- dvt/deps/local.py +80 -0
- dvt/deps/registry.py +131 -0
- dvt/deps/resolver.py +149 -0
- dvt/deps/tarball.py +121 -0
- dvt/docs/source/_ext/dbt_click.py +118 -0
- dvt/docs/source/conf.py +32 -0
- dvt/env_vars.py +64 -0
- dvt/event_time/event_time.py +40 -0
- dvt/event_time/sample_window.py +60 -0
- dvt/events/__init__.py +16 -0
- dvt/events/base_types.py +37 -0
- dvt/events/core_types_pb2.py +2 -0
- dvt/events/logging.py +109 -0
- dvt/events/types.py +2534 -0
- dvt/exceptions.py +1487 -0
- dvt/flags.py +89 -0
- dvt/graph/__init__.py +11 -0
- dvt/graph/cli.py +248 -0
- dvt/graph/graph.py +172 -0
- dvt/graph/queue.py +213 -0
- dvt/graph/selector.py +375 -0
- dvt/graph/selector_methods.py +976 -0
- dvt/graph/selector_spec.py +223 -0
- dvt/graph/thread_pool.py +18 -0
- dvt/hooks.py +21 -0
- dvt/include/README.md +49 -0
- dvt/include/__init__.py +3 -0
- dvt/include/global_project.py +4 -0
- dvt/include/starter_project/.gitignore +4 -0
- dvt/include/starter_project/README.md +15 -0
- dvt/include/starter_project/__init__.py +3 -0
- dvt/include/starter_project/analyses/.gitkeep +0 -0
- dvt/include/starter_project/dvt_project.yml +36 -0
- dvt/include/starter_project/macros/.gitkeep +0 -0
- dvt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
- dvt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
- dvt/include/starter_project/models/example/schema.yml +21 -0
- dvt/include/starter_project/seeds/.gitkeep +0 -0
- dvt/include/starter_project/snapshots/.gitkeep +0 -0
- dvt/include/starter_project/tests/.gitkeep +0 -0
- dvt/internal_deprecations.py +27 -0
- dvt/jsonschemas/__init__.py +3 -0
- dvt/jsonschemas/jsonschemas.py +309 -0
- dvt/jsonschemas/project/0.0.110.json +4717 -0
- dvt/jsonschemas/project/0.0.85.json +2015 -0
- dvt/jsonschemas/resources/0.0.110.json +2636 -0
- dvt/jsonschemas/resources/0.0.85.json +2536 -0
- dvt/jsonschemas/resources/latest.json +6773 -0
- dvt/links.py +4 -0
- dvt/materializations/__init__.py +0 -0
- dvt/materializations/incremental/__init__.py +0 -0
- dvt/materializations/incremental/microbatch.py +235 -0
- dvt/mp_context.py +8 -0
- dvt/node_types.py +37 -0
- dvt/parser/__init__.py +23 -0
- dvt/parser/analysis.py +21 -0
- dvt/parser/base.py +549 -0
- dvt/parser/common.py +267 -0
- dvt/parser/docs.py +52 -0
- dvt/parser/fixtures.py +51 -0
- dvt/parser/functions.py +30 -0
- dvt/parser/generic_test.py +100 -0
- dvt/parser/generic_test_builders.py +334 -0
- dvt/parser/hooks.py +119 -0
- dvt/parser/macros.py +137 -0
- dvt/parser/manifest.py +2204 -0
- dvt/parser/models.py +574 -0
- dvt/parser/partial.py +1179 -0
- dvt/parser/read_files.py +445 -0
- dvt/parser/schema_generic_tests.py +423 -0
- dvt/parser/schema_renderer.py +111 -0
- dvt/parser/schema_yaml_readers.py +936 -0
- dvt/parser/schemas.py +1467 -0
- dvt/parser/search.py +149 -0
- dvt/parser/seeds.py +28 -0
- dvt/parser/singular_test.py +20 -0
- dvt/parser/snapshots.py +44 -0
- dvt/parser/sources.py +557 -0
- dvt/parser/sql.py +63 -0
- dvt/parser/unit_tests.py +622 -0
- dvt/plugins/__init__.py +20 -0
- dvt/plugins/contracts.py +10 -0
- dvt/plugins/exceptions.py +2 -0
- dvt/plugins/manager.py +164 -0
- dvt/plugins/manifest.py +21 -0
- dvt/profiler.py +20 -0
- dvt/py.typed +1 -0
- dvt/runners/__init__.py +2 -0
- dvt/runners/exposure_runner.py +7 -0
- dvt/runners/no_op_runner.py +46 -0
- dvt/runners/saved_query_runner.py +7 -0
- dvt/selected_resources.py +8 -0
- dvt/task/__init__.py +0 -0
- dvt/task/base.py +504 -0
- dvt/task/build.py +197 -0
- dvt/task/clean.py +57 -0
- dvt/task/clone.py +162 -0
- dvt/task/compile.py +151 -0
- dvt/task/compute.py +366 -0
- dvt/task/debug.py +650 -0
- dvt/task/deps.py +280 -0
- dvt/task/docs/__init__.py +3 -0
- dvt/task/docs/generate.py +408 -0
- dvt/task/docs/index.html +250 -0
- dvt/task/docs/serve.py +28 -0
- dvt/task/freshness.py +323 -0
- dvt/task/function.py +122 -0
- dvt/task/group_lookup.py +46 -0
- dvt/task/init.py +374 -0
- dvt/task/list.py +237 -0
- dvt/task/printer.py +176 -0
- dvt/task/profiles.py +256 -0
- dvt/task/retry.py +175 -0
- dvt/task/run.py +1146 -0
- dvt/task/run_operation.py +142 -0
- dvt/task/runnable.py +802 -0
- dvt/task/seed.py +104 -0
- dvt/task/show.py +150 -0
- dvt/task/snapshot.py +57 -0
- dvt/task/sql.py +111 -0
- dvt/task/test.py +464 -0
- dvt/tests/fixtures/__init__.py +1 -0
- dvt/tests/fixtures/project.py +620 -0
- dvt/tests/util.py +651 -0
- dvt/tracking.py +529 -0
- dvt/utils/__init__.py +3 -0
- dvt/utils/artifact_upload.py +151 -0
- dvt/utils/utils.py +408 -0
- dvt/version.py +249 -0
- dvt_core-1.11.0b4.dist-info/METADATA +252 -0
- dvt_core-1.11.0b4.dist-info/RECORD +261 -0
- dvt_core-1.11.0b4.dist-info/WHEEL +5 -0
- dvt_core-1.11.0b4.dist-info/entry_points.txt +2 -0
- dvt_core-1.11.0b4.dist-info/top_level.txt +1 -0
dvt/cli/exceptions.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from typing import IO, List, Optional, Union
|
|
2
|
+
|
|
3
|
+
from click.exceptions import ClickException
|
|
4
|
+
from dvt.artifacts.schemas.catalog import CatalogArtifact
|
|
5
|
+
from dvt.contracts.graph.manifest import Manifest
|
|
6
|
+
from dvt.contracts.results import RunExecutionResult
|
|
7
|
+
from dvt.utils import ExitCodes
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DbtUsageException(Exception):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DbtInternalException(Exception):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CliException(ClickException):
|
|
19
|
+
"""The base exception class for our implementation of the click CLI.
|
|
20
|
+
The exit_code attribute is used by click to determine which exit code to produce
|
|
21
|
+
after an invocation."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, exit_code: ExitCodes) -> None:
|
|
24
|
+
self.exit_code = exit_code.value
|
|
25
|
+
|
|
26
|
+
# the typing of _file is to satisfy the signature of ClickException.show
|
|
27
|
+
# overriding this method prevents click from printing any exceptions to stdout
|
|
28
|
+
def show(self, _file: Optional[IO] = None) -> None: # type: ignore[type-arg]
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ResultExit(CliException):
|
|
33
|
+
"""This class wraps any exception that contains results while invoking dbt, or the
|
|
34
|
+
results of an invocation that did not succeed but did not throw any exceptions."""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
result: Union[
|
|
39
|
+
bool, # debug
|
|
40
|
+
CatalogArtifact, # docs generate
|
|
41
|
+
List[str], # list/ls
|
|
42
|
+
Manifest, # parse
|
|
43
|
+
None, # clean, deps, init, source
|
|
44
|
+
RunExecutionResult, # build, compile, run, seed, snapshot, test, run-operation
|
|
45
|
+
] = None,
|
|
46
|
+
) -> None:
|
|
47
|
+
super().__init__(ExitCodes.ModelError)
|
|
48
|
+
self.result = result
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ExceptionExit(CliException):
|
|
52
|
+
"""This class wraps any exception that does not contain results thrown while invoking dbt."""
|
|
53
|
+
|
|
54
|
+
def __init__(self, exception: Exception) -> None:
|
|
55
|
+
super().__init__(ExitCodes.UnhandledError)
|
|
56
|
+
self.exception = exception
|
dvt/cli/flags.py
ADDED
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from importlib import import_module
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from pprint import pformat as pf
|
|
8
|
+
from typing import Any, Callable, Dict, List, Optional, Set, Union
|
|
9
|
+
|
|
10
|
+
from click import Context, Parameter, get_current_context
|
|
11
|
+
from click.core import Command as ClickCommand
|
|
12
|
+
from click.core import Group, ParameterSource
|
|
13
|
+
from dvt.cli.exceptions import DbtUsageException
|
|
14
|
+
from dvt.cli.resolvers import default_log_path, default_project_dir
|
|
15
|
+
from dvt.cli.types import Command as CliCommand
|
|
16
|
+
from dvt.config.project import read_project_flags
|
|
17
|
+
from dvt.config.utils import normalize_warn_error_options
|
|
18
|
+
from dvt.contracts.project import ProjectFlags
|
|
19
|
+
from dvt.deprecations import fire_buffered_deprecations, renamed_env_var, warn
|
|
20
|
+
from dvt.events import ALL_EVENT_NAMES
|
|
21
|
+
|
|
22
|
+
from dbt_common import ui
|
|
23
|
+
from dbt_common.clients import jinja
|
|
24
|
+
from dbt_common.events import functions
|
|
25
|
+
from dbt_common.exceptions import DbtInternalError
|
|
26
|
+
from dbt_common.helper_types import WarnErrorOptionsV2
|
|
27
|
+
|
|
28
|
+
if os.name != "nt":
|
|
29
|
+
# https://bugs.python.org/issue41567
|
|
30
|
+
import multiprocessing.popen_spawn_posix # type: ignore # noqa: F401
|
|
31
|
+
|
|
32
|
+
FLAGS_DEFAULTS = {
|
|
33
|
+
"INDIRECT_SELECTION": "eager",
|
|
34
|
+
"TARGET_PATH": None,
|
|
35
|
+
"DEFER_STATE": None, # necessary because of retry construction of flags
|
|
36
|
+
"WARN_ERROR": None,
|
|
37
|
+
# Cli args without project_flags or env var option.
|
|
38
|
+
"FULL_REFRESH": False,
|
|
39
|
+
"STRICT_MODE": False,
|
|
40
|
+
"STORE_FAILURES": False,
|
|
41
|
+
"INTROSPECT": True,
|
|
42
|
+
"STATE_MODIFIED_COMPARE_VARS": False,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
DEPRECATED_PARAMS = {
|
|
46
|
+
"deprecated_defer": "defer",
|
|
47
|
+
"deprecated_favor_state": "favor_state",
|
|
48
|
+
"deprecated_print": "print",
|
|
49
|
+
"deprecated_state": "state",
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
DEPRECATED_FLAGS_TO_WARNINGS = {("--models", "--model", "-m"): "model-param-usage-deprecation"}
|
|
54
|
+
|
|
55
|
+
WHICH_KEY = "which"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def convert_config(config_name, config_value):
|
|
59
|
+
"""Convert the values from config and original set_from_args to the correct type."""
|
|
60
|
+
ret = config_value
|
|
61
|
+
if config_name.lower() == "warn_error_options" and type(config_value) == dict:
|
|
62
|
+
normalize_warn_error_options(ret)
|
|
63
|
+
ret = WarnErrorOptionsV2(
|
|
64
|
+
error=config_value.get("error", []),
|
|
65
|
+
warn=config_value.get("warn", []),
|
|
66
|
+
silence=config_value.get("silence", []),
|
|
67
|
+
valid_error_names=ALL_EVENT_NAMES,
|
|
68
|
+
)
|
|
69
|
+
return ret
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def args_to_context(args: List[str]) -> Context:
|
|
73
|
+
"""Convert a list of args to a click context with proper hierarchy for dbt commands"""
|
|
74
|
+
from dvt.cli.main import cli
|
|
75
|
+
|
|
76
|
+
cli_ctx = cli.make_context(cli.name, args)
|
|
77
|
+
# Split args if they're a comma separated string.
|
|
78
|
+
if len(args) == 1 and "," in args[0]:
|
|
79
|
+
args = args[0].split(",")
|
|
80
|
+
sub_command_name, sub_command, args = cli.resolve_command(cli_ctx, args)
|
|
81
|
+
# Handle source and docs group.
|
|
82
|
+
if isinstance(sub_command, Group):
|
|
83
|
+
sub_command_name, sub_command, args = sub_command.resolve_command(cli_ctx, args)
|
|
84
|
+
|
|
85
|
+
assert isinstance(sub_command, ClickCommand)
|
|
86
|
+
sub_command_ctx = sub_command.make_context(sub_command_name, args)
|
|
87
|
+
sub_command_ctx.parent = cli_ctx
|
|
88
|
+
return sub_command_ctx
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass(frozen=True)
|
|
92
|
+
class Flags:
|
|
93
|
+
"""Primary configuration artifact for running dbt"""
|
|
94
|
+
|
|
95
|
+
def __init__(
|
|
96
|
+
self, ctx: Optional[Context] = None, project_flags: Optional[ProjectFlags] = None
|
|
97
|
+
) -> None:
|
|
98
|
+
# Set the default flags.
|
|
99
|
+
for key, value in FLAGS_DEFAULTS.items():
|
|
100
|
+
object.__setattr__(self, key, value)
|
|
101
|
+
# Use to handle duplicate params in _assign_params
|
|
102
|
+
flags_defaults_list = list(FLAGS_DEFAULTS.keys())
|
|
103
|
+
|
|
104
|
+
if ctx is None:
|
|
105
|
+
ctx = get_current_context()
|
|
106
|
+
|
|
107
|
+
def _get_params_by_source(ctx: Context, source_type: ParameterSource):
|
|
108
|
+
"""Generates all params of a given source type."""
|
|
109
|
+
yield from [
|
|
110
|
+
name for name, source in ctx._parameter_source.items() if source is source_type
|
|
111
|
+
]
|
|
112
|
+
if ctx.parent:
|
|
113
|
+
yield from _get_params_by_source(ctx.parent, source_type)
|
|
114
|
+
|
|
115
|
+
# Ensure that any params sourced from the commandline are not present more than once.
|
|
116
|
+
# Click handles this exclusivity, but only at a per-subcommand level.
|
|
117
|
+
seen_params = []
|
|
118
|
+
for param in _get_params_by_source(ctx, ParameterSource.COMMANDLINE):
|
|
119
|
+
if param in seen_params:
|
|
120
|
+
raise DbtUsageException(
|
|
121
|
+
f"{param.lower()} was provided both before and after the subcommand, it can only be set either before or after.",
|
|
122
|
+
)
|
|
123
|
+
seen_params.append(param)
|
|
124
|
+
|
|
125
|
+
def _assign_params(
|
|
126
|
+
ctx: Context,
|
|
127
|
+
params_assigned_from_default: set,
|
|
128
|
+
params_assigned_from_user: set,
|
|
129
|
+
deprecated_env_vars: Dict[str, Callable],
|
|
130
|
+
):
|
|
131
|
+
"""Recursively adds all click params to flag object"""
|
|
132
|
+
for param_name, param_value in ctx.params.items():
|
|
133
|
+
# N.B. You have to use the base MRO method (object.__setattr__) to set attributes
|
|
134
|
+
# when using frozen dataclasses.
|
|
135
|
+
# https://docs.python.org/3/library/dataclasses.html#frozen-instances
|
|
136
|
+
|
|
137
|
+
# Handle deprecated env vars while still respecting old values
|
|
138
|
+
# e.g. DBT_NO_PRINT -> DBT_PRINT if DBT_NO_PRINT is set, it is
|
|
139
|
+
# respected over DBT_PRINT or --print.
|
|
140
|
+
new_name: Union[str, None] = None
|
|
141
|
+
if param_name in DEPRECATED_PARAMS:
|
|
142
|
+
# Deprecated env vars can only be set via env var.
|
|
143
|
+
# We use the deprecated option in click to serialize the value
|
|
144
|
+
# from the env var string.
|
|
145
|
+
param_source = ctx.get_parameter_source(param_name)
|
|
146
|
+
if param_source == ParameterSource.DEFAULT:
|
|
147
|
+
continue
|
|
148
|
+
elif param_source != ParameterSource.ENVIRONMENT:
|
|
149
|
+
raise DbtUsageException(
|
|
150
|
+
"Deprecated parameters can only be set via environment variables",
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Rename for clarity.
|
|
154
|
+
dep_name = param_name
|
|
155
|
+
new_name = DEPRECATED_PARAMS.get(dep_name)
|
|
156
|
+
try:
|
|
157
|
+
assert isinstance(new_name, str)
|
|
158
|
+
except AssertionError:
|
|
159
|
+
raise Exception(
|
|
160
|
+
f"No deprecated param name match in DEPRECATED_PARAMS from {dep_name} to {new_name}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Find param objects for their envvar name.
|
|
164
|
+
try:
|
|
165
|
+
dep_param = [x for x in ctx.command.params if x.name == dep_name][0]
|
|
166
|
+
new_param = [x for x in ctx.command.params if x.name == new_name][0]
|
|
167
|
+
except IndexError:
|
|
168
|
+
raise Exception(
|
|
169
|
+
f"No deprecated param name match in context from {dep_name} to {new_name}"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Remove param from defaulted set since the deprecated
|
|
173
|
+
# value is not set from default, but from an env var.
|
|
174
|
+
if new_name in params_assigned_from_default:
|
|
175
|
+
params_assigned_from_default.remove(new_name)
|
|
176
|
+
|
|
177
|
+
# Add the deprecation warning function to the set.
|
|
178
|
+
assert isinstance(dep_param.envvar, str)
|
|
179
|
+
assert isinstance(new_param.envvar, str)
|
|
180
|
+
deprecated_env_vars[new_name] = renamed_env_var(
|
|
181
|
+
old_name=dep_param.envvar,
|
|
182
|
+
new_name=new_param.envvar,
|
|
183
|
+
)
|
|
184
|
+
# end deprecated_params
|
|
185
|
+
|
|
186
|
+
# Set the flag value.
|
|
187
|
+
is_duplicate = (
|
|
188
|
+
hasattr(self, param_name.upper())
|
|
189
|
+
and param_name.upper() not in flags_defaults_list
|
|
190
|
+
)
|
|
191
|
+
# First time through, set as though FLAGS_DEFAULTS hasn't been set, so not a duplicate.
|
|
192
|
+
# Subsequent pass (to process "parent" params) should be treated as duplicates.
|
|
193
|
+
if param_name.upper() in flags_defaults_list:
|
|
194
|
+
flags_defaults_list.remove(param_name.upper())
|
|
195
|
+
# Note: the following determines whether parameter came from click default,
|
|
196
|
+
# not from FLAGS_DEFAULTS in __init__.
|
|
197
|
+
is_default = ctx.get_parameter_source(param_name) == ParameterSource.DEFAULT
|
|
198
|
+
is_envvar = ctx.get_parameter_source(param_name) == ParameterSource.ENVIRONMENT
|
|
199
|
+
|
|
200
|
+
flag_name = (new_name or param_name).upper()
|
|
201
|
+
|
|
202
|
+
# envvar flags are assigned in either parent or child context if there
|
|
203
|
+
# isn't an overriding cli command flag.
|
|
204
|
+
# If the flag has been encountered as a child cli flag, we don't
|
|
205
|
+
# want to overwrite with parent envvar, since the commandline flag takes precedence.
|
|
206
|
+
if (is_duplicate and not (is_default or is_envvar)) or not is_duplicate:
|
|
207
|
+
object.__setattr__(self, flag_name, param_value)
|
|
208
|
+
|
|
209
|
+
# Track default assigned params.
|
|
210
|
+
# For flags that are accepted at both 'parent' and 'child' levels,
|
|
211
|
+
# we need to track user-provided and default values across both,
|
|
212
|
+
# to support detection of mutually exclusive flags later on.
|
|
213
|
+
if not is_default:
|
|
214
|
+
params_assigned_from_user.add(param_name)
|
|
215
|
+
if param_name in params_assigned_from_default:
|
|
216
|
+
params_assigned_from_default.remove(param_name)
|
|
217
|
+
if is_default and param_name not in params_assigned_from_user:
|
|
218
|
+
params_assigned_from_default.add(param_name)
|
|
219
|
+
|
|
220
|
+
if ctx.parent:
|
|
221
|
+
_assign_params(
|
|
222
|
+
ctx.parent,
|
|
223
|
+
params_assigned_from_default,
|
|
224
|
+
params_assigned_from_user,
|
|
225
|
+
deprecated_env_vars,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
params_assigned_from_user = set() # type: Set[str]
|
|
229
|
+
params_assigned_from_default = set() # type: Set[str]
|
|
230
|
+
deprecated_env_vars: Dict[str, Callable] = {}
|
|
231
|
+
_assign_params(
|
|
232
|
+
ctx, params_assigned_from_default, params_assigned_from_user, deprecated_env_vars
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
# Set deprecated_env_var_warnings to be fired later after events have been init.
|
|
236
|
+
object.__setattr__(
|
|
237
|
+
self, "deprecated_env_var_warnings", [x for x in deprecated_env_vars.values()]
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Get the invoked command flags.
|
|
241
|
+
invoked_subcommand_name = (
|
|
242
|
+
ctx.invoked_subcommand if hasattr(ctx, "invoked_subcommand") else None
|
|
243
|
+
)
|
|
244
|
+
if invoked_subcommand_name is not None:
|
|
245
|
+
invoked_subcommand = getattr(import_module("dbt.cli.main"), invoked_subcommand_name)
|
|
246
|
+
invoked_subcommand.allow_extra_args = True
|
|
247
|
+
invoked_subcommand.ignore_unknown_options = True
|
|
248
|
+
invoked_subcommand_ctx = invoked_subcommand.make_context(None, sys.argv)
|
|
249
|
+
_assign_params(
|
|
250
|
+
invoked_subcommand_ctx,
|
|
251
|
+
params_assigned_from_default,
|
|
252
|
+
params_assigned_from_user,
|
|
253
|
+
deprecated_env_vars,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
if not project_flags:
|
|
257
|
+
project_dir = getattr(self, "PROJECT_DIR", str(default_project_dir()))
|
|
258
|
+
profiles_dir = getattr(self, "PROFILES_DIR", None)
|
|
259
|
+
if profiles_dir and project_dir:
|
|
260
|
+
project_flags = read_project_flags(project_dir, profiles_dir)
|
|
261
|
+
else:
|
|
262
|
+
project_flags = None
|
|
263
|
+
|
|
264
|
+
# Add entire invocation command to flags
|
|
265
|
+
object.__setattr__(self, "INVOCATION_COMMAND", "dbt " + " ".join(sys.argv[1:]))
|
|
266
|
+
|
|
267
|
+
if project_flags:
|
|
268
|
+
# Overwrite default assignments with project flags if available.
|
|
269
|
+
param_assigned_from_default_copy = params_assigned_from_default.copy()
|
|
270
|
+
for param_assigned_from_default in params_assigned_from_default:
|
|
271
|
+
project_flags_param_value = getattr(
|
|
272
|
+
project_flags, param_assigned_from_default, None
|
|
273
|
+
)
|
|
274
|
+
if project_flags_param_value is not None:
|
|
275
|
+
object.__setattr__(
|
|
276
|
+
self,
|
|
277
|
+
param_assigned_from_default.upper(),
|
|
278
|
+
convert_config(param_assigned_from_default, project_flags_param_value),
|
|
279
|
+
)
|
|
280
|
+
param_assigned_from_default_copy.remove(param_assigned_from_default)
|
|
281
|
+
params_assigned_from_default = param_assigned_from_default_copy
|
|
282
|
+
|
|
283
|
+
# Add project-level flags that are not available as CLI options / env vars
|
|
284
|
+
for (
|
|
285
|
+
project_level_flag_name,
|
|
286
|
+
project_level_flag_value,
|
|
287
|
+
) in project_flags.project_only_flags.items():
|
|
288
|
+
object.__setattr__(self, project_level_flag_name.upper(), project_level_flag_value)
|
|
289
|
+
|
|
290
|
+
# Set hard coded flags.
|
|
291
|
+
object.__setattr__(self, "WHICH", invoked_subcommand_name or ctx.info_name)
|
|
292
|
+
|
|
293
|
+
# Apply the lead/follow relationship between some parameters.
|
|
294
|
+
self._override_if_set("USE_COLORS", "USE_COLORS_FILE", params_assigned_from_default)
|
|
295
|
+
self._override_if_set("LOG_LEVEL", "LOG_LEVEL_FILE", params_assigned_from_default)
|
|
296
|
+
self._override_if_set("LOG_FORMAT", "LOG_FORMAT_FILE", params_assigned_from_default)
|
|
297
|
+
|
|
298
|
+
# Set default LOG_PATH from PROJECT_DIR, if available.
|
|
299
|
+
# Starting in v1.5, if `log-path` is set in `dbt_project.yml`, it will raise a deprecation warning,
|
|
300
|
+
# with the possibility of removing it in a future release.
|
|
301
|
+
if getattr(self, "LOG_PATH", None) is None:
|
|
302
|
+
project_dir = getattr(self, "PROJECT_DIR", str(default_project_dir()))
|
|
303
|
+
version_check = getattr(self, "VERSION_CHECK", True)
|
|
304
|
+
object.__setattr__(
|
|
305
|
+
self, "LOG_PATH", default_log_path(Path(project_dir), version_check)
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
# Support console DO NOT TRACK initiative.
|
|
309
|
+
if os.getenv("DO_NOT_TRACK", "").lower() in ("1", "t", "true", "y", "yes"):
|
|
310
|
+
object.__setattr__(self, "SEND_ANONYMOUS_USAGE_STATS", False)
|
|
311
|
+
|
|
312
|
+
# Check mutual exclusivity once all flags are set.
|
|
313
|
+
self._assert_mutually_exclusive(
|
|
314
|
+
params_assigned_from_default, ["WARN_ERROR", "WARN_ERROR_OPTIONS"]
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# Handle arguments mutually exclusive with INLINE
|
|
318
|
+
self._assert_mutually_exclusive(params_assigned_from_default, ["SELECT", "INLINE"])
|
|
319
|
+
self._assert_mutually_exclusive(params_assigned_from_default, ["SELECTOR", "INLINE"])
|
|
320
|
+
|
|
321
|
+
# Check event_time configs for validity
|
|
322
|
+
self._validate_event_time_configs()
|
|
323
|
+
|
|
324
|
+
# Support lower cased access for legacy code.
|
|
325
|
+
params = set(
|
|
326
|
+
x for x in dir(self) if not callable(getattr(self, x)) and not x.startswith("__")
|
|
327
|
+
)
|
|
328
|
+
for param in params:
|
|
329
|
+
object.__setattr__(self, param.lower(), getattr(self, param))
|
|
330
|
+
|
|
331
|
+
self.set_common_global_flags()
|
|
332
|
+
|
|
333
|
+
def __str__(self) -> str:
|
|
334
|
+
return str(pf(self.__dict__))
|
|
335
|
+
|
|
336
|
+
def _override_if_set(self, lead: str, follow: str, defaulted: Set[str]) -> None:
|
|
337
|
+
"""If the value of the lead parameter was set explicitly, apply the value to follow, unless follow was also set explicitly."""
|
|
338
|
+
if lead.lower() not in defaulted and follow.lower() in defaulted:
|
|
339
|
+
object.__setattr__(self, follow.upper(), getattr(self, lead.upper(), None))
|
|
340
|
+
|
|
341
|
+
def _assert_mutually_exclusive(
|
|
342
|
+
self, params_assigned_from_default: Set[str], group: List[str]
|
|
343
|
+
) -> None:
|
|
344
|
+
"""
|
|
345
|
+
Ensure no elements from group are simultaneously provided by a user, as inferred from params_assigned_from_default.
|
|
346
|
+
Raises click.UsageError if any two elements from group are simultaneously provided by a user.
|
|
347
|
+
"""
|
|
348
|
+
set_flag = None
|
|
349
|
+
for flag in group:
|
|
350
|
+
flag_set_by_user = (
|
|
351
|
+
hasattr(self, flag) and flag.lower() not in params_assigned_from_default
|
|
352
|
+
)
|
|
353
|
+
if flag_set_by_user and set_flag:
|
|
354
|
+
raise DbtUsageException(
|
|
355
|
+
f"{flag.lower()}: not allowed with argument {set_flag.lower()}"
|
|
356
|
+
)
|
|
357
|
+
elif flag_set_by_user:
|
|
358
|
+
set_flag = flag
|
|
359
|
+
|
|
360
|
+
def _validate_event_time_configs(self) -> None:
|
|
361
|
+
event_time_start: datetime = (
|
|
362
|
+
getattr(self, "EVENT_TIME_START") if hasattr(self, "EVENT_TIME_START") else None
|
|
363
|
+
)
|
|
364
|
+
event_time_end: datetime = (
|
|
365
|
+
getattr(self, "EVENT_TIME_END") if hasattr(self, "EVENT_TIME_END") else None
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
# only do validations if at least one of `event_time_start` or `event_time_end` are specified
|
|
369
|
+
if event_time_start is not None or event_time_end is not None:
|
|
370
|
+
|
|
371
|
+
# These `ifs`, combined with the parent `if` make it so that `event_time_start` and
|
|
372
|
+
# `event_time_end` are mutually required
|
|
373
|
+
if event_time_start is None:
|
|
374
|
+
raise DbtUsageException(
|
|
375
|
+
"The flag `--event-time-end` was specified, but `--event-time-start` was not. "
|
|
376
|
+
"When specifying `--event-time-end`, `--event-time-start` must also be present."
|
|
377
|
+
)
|
|
378
|
+
if event_time_end is None:
|
|
379
|
+
raise DbtUsageException(
|
|
380
|
+
"The flag `--event-time-start` was specified, but `--event-time-end` was not. "
|
|
381
|
+
"When specifying `--event-time-start`, `--event-time-end` must also be present."
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
# This `if` just is a sanity check that `event_time_start` is before `event_time_end`
|
|
385
|
+
if event_time_start >= event_time_end:
|
|
386
|
+
raise DbtUsageException(
|
|
387
|
+
"Value for `--event-time-start` must be less than `--event-time-end`"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
def fire_deprecations(self, ctx: Optional[Context] = None):
|
|
391
|
+
"""Fires events for deprecated env_var usage."""
|
|
392
|
+
[dep_fn() for dep_fn in self.deprecated_env_var_warnings]
|
|
393
|
+
# It is necessary to remove this attr from the class so it does
|
|
394
|
+
# not get pickled when written to disk as json.
|
|
395
|
+
object.__delattr__(self, "deprecated_env_var_warnings")
|
|
396
|
+
|
|
397
|
+
fire_buffered_deprecations()
|
|
398
|
+
|
|
399
|
+
# Handle firing deprecations of CLI aliases separately using argv or dbtRunner args
|
|
400
|
+
# because click doesn't make it possible to disambiguite which literal CLI option was used
|
|
401
|
+
# and only preserves the 'canonical' representation.
|
|
402
|
+
original_command_args = (
|
|
403
|
+
ctx.obj["dbt_runner_command_args"]
|
|
404
|
+
if (ctx and ctx.obj and "dbt_runner_command_args" in ctx.obj)
|
|
405
|
+
else sys.argv
|
|
406
|
+
)
|
|
407
|
+
for deprecated_flags, warning in DEPRECATED_FLAGS_TO_WARNINGS.items():
|
|
408
|
+
for deprecated_flag in deprecated_flags:
|
|
409
|
+
if deprecated_flag in original_command_args:
|
|
410
|
+
warn(warning)
|
|
411
|
+
|
|
412
|
+
@classmethod
|
|
413
|
+
def from_dict(cls, command: CliCommand, args_dict: Dict[str, Any]) -> "Flags":
|
|
414
|
+
command_arg_list = command_params(command, args_dict)
|
|
415
|
+
ctx = args_to_context(command_arg_list)
|
|
416
|
+
flags = cls(ctx=ctx)
|
|
417
|
+
flags.fire_deprecations(ctx=ctx)
|
|
418
|
+
return flags
|
|
419
|
+
|
|
420
|
+
def set_common_global_flags(self):
|
|
421
|
+
# Set globals for common.ui
|
|
422
|
+
if getattr(self, "PRINTER_WIDTH", None) is not None:
|
|
423
|
+
ui.PRINTER_WIDTH = getattr(self, "PRINTER_WIDTH")
|
|
424
|
+
if getattr(self, "USE_COLORS", None) is not None:
|
|
425
|
+
ui.USE_COLOR = getattr(self, "USE_COLORS")
|
|
426
|
+
|
|
427
|
+
# Set globals for common.events.functions
|
|
428
|
+
functions.WARN_ERROR = getattr(self, "WARN_ERROR", False)
|
|
429
|
+
if getattr(self, "WARN_ERROR_OPTIONS", None) is not None:
|
|
430
|
+
functions.WARN_ERROR_OPTIONS = getattr(self, "WARN_ERROR_OPTIONS")
|
|
431
|
+
|
|
432
|
+
# Set globals for common.jinja
|
|
433
|
+
if getattr(self, "MACRO_DEBUGGING", None) is not None:
|
|
434
|
+
jinja.MACRO_DEBUGGING = getattr(self, "MACRO_DEBUGGING")
|
|
435
|
+
|
|
436
|
+
# This is here to prevent mypy from complaining about all of the
|
|
437
|
+
# attributes which we added dynamically.
|
|
438
|
+
def __getattr__(self, name: str) -> Any:
|
|
439
|
+
return super().__getattribute__(name) # type: ignore
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
CommandParams = List[str]
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def command_params(command: CliCommand, args_dict: Dict[str, Any]) -> CommandParams:
|
|
446
|
+
"""Given a command and a dict, returns a list of strings representing
|
|
447
|
+
the CLI params for that command. The order of this list is consistent with
|
|
448
|
+
which flags are expected at the parent level vs the command level.
|
|
449
|
+
|
|
450
|
+
e.g. fn("run", {"defer": True, "print": False}) -> ["--no-print", "run", "--defer"]
|
|
451
|
+
|
|
452
|
+
The result of this function can be passed in to the args_to_context function
|
|
453
|
+
to produce a click context to instantiate Flags with.
|
|
454
|
+
"""
|
|
455
|
+
|
|
456
|
+
cmd_args = set(command_args(command))
|
|
457
|
+
prnt_args = set(parent_args())
|
|
458
|
+
default_args = set([x.lower() for x in FLAGS_DEFAULTS.keys()])
|
|
459
|
+
|
|
460
|
+
res = command.to_list()
|
|
461
|
+
for k, v in args_dict.items():
|
|
462
|
+
k = k.lower()
|
|
463
|
+
# if a "which" value exists in the args dict, it should match the command provided
|
|
464
|
+
if k == WHICH_KEY:
|
|
465
|
+
if v != command.value:
|
|
466
|
+
raise DbtInternalError(
|
|
467
|
+
f"Command '{command.value}' does not match value of which: '{v}'"
|
|
468
|
+
)
|
|
469
|
+
continue
|
|
470
|
+
|
|
471
|
+
# param was assigned from defaults and should not be included
|
|
472
|
+
if k not in (cmd_args | prnt_args) or (
|
|
473
|
+
k in default_args and v == FLAGS_DEFAULTS[k.upper()]
|
|
474
|
+
):
|
|
475
|
+
continue
|
|
476
|
+
|
|
477
|
+
# if the param is in parent args, it should come before the arg name
|
|
478
|
+
# e.g. ["--print", "run"] vs ["run", "--print"]
|
|
479
|
+
add_fn = res.append
|
|
480
|
+
if k in prnt_args:
|
|
481
|
+
|
|
482
|
+
def add_fn(x):
|
|
483
|
+
res.insert(0, x)
|
|
484
|
+
|
|
485
|
+
spinal_cased = k.replace("_", "-")
|
|
486
|
+
|
|
487
|
+
# MultiOption flags come back as lists, but we want to pass them as space separated strings
|
|
488
|
+
if isinstance(v, list):
|
|
489
|
+
if len(v) > 0:
|
|
490
|
+
v = " ".join(v)
|
|
491
|
+
else:
|
|
492
|
+
continue
|
|
493
|
+
|
|
494
|
+
if k == "macro" and command == CliCommand.RUN_OPERATION:
|
|
495
|
+
add_fn(v)
|
|
496
|
+
# None is a Singleton, False is a Flyweight, only one instance of each.
|
|
497
|
+
elif (v is None or v is False) and k not in (
|
|
498
|
+
# These are None by default but they do not support --no-{flag}
|
|
499
|
+
"defer_state",
|
|
500
|
+
"log_format",
|
|
501
|
+
):
|
|
502
|
+
add_fn(f"--no-{spinal_cased}")
|
|
503
|
+
elif v is True:
|
|
504
|
+
add_fn(f"--{spinal_cased}")
|
|
505
|
+
else:
|
|
506
|
+
add_fn(f"--{spinal_cased}={v}")
|
|
507
|
+
|
|
508
|
+
return res
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
ArgsList = List[str]
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def parent_args() -> ArgsList:
|
|
515
|
+
"""Return a list representing the params the base click command takes."""
|
|
516
|
+
from dvt.cli.main import cli
|
|
517
|
+
|
|
518
|
+
return format_params(cli.params)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def command_args(command: CliCommand) -> ArgsList:
|
|
522
|
+
"""Given a command, return a list of strings representing the params
|
|
523
|
+
that command takes. This function only returns params assigned to a
|
|
524
|
+
specific command, not those of its parent command.
|
|
525
|
+
|
|
526
|
+
e.g. fn("run") -> ["defer", "favor_state", "exclude", ...]
|
|
527
|
+
"""
|
|
528
|
+
import dvt.cli.main as cli
|
|
529
|
+
|
|
530
|
+
CMD_DICT: Dict[CliCommand, ClickCommand] = {
|
|
531
|
+
CliCommand.BUILD: cli.build,
|
|
532
|
+
CliCommand.CLEAN: cli.clean,
|
|
533
|
+
CliCommand.CLONE: cli.clone,
|
|
534
|
+
CliCommand.COMPILE: cli.compile,
|
|
535
|
+
CliCommand.DOCS_GENERATE: cli.docs_generate,
|
|
536
|
+
CliCommand.DOCS_SERVE: cli.docs_serve,
|
|
537
|
+
CliCommand.DEBUG: cli.debug,
|
|
538
|
+
CliCommand.DEPS: cli.deps,
|
|
539
|
+
CliCommand.INIT: cli.init,
|
|
540
|
+
CliCommand.LIST: cli.list,
|
|
541
|
+
CliCommand.PARSE: cli.parse,
|
|
542
|
+
CliCommand.RUN: cli.run,
|
|
543
|
+
CliCommand.RUN_OPERATION: cli.run_operation,
|
|
544
|
+
CliCommand.SEED: cli.seed,
|
|
545
|
+
CliCommand.SHOW: cli.show,
|
|
546
|
+
CliCommand.SNAPSHOT: cli.snapshot,
|
|
547
|
+
CliCommand.SOURCE_FRESHNESS: cli.freshness,
|
|
548
|
+
CliCommand.TEST: cli.test,
|
|
549
|
+
CliCommand.RETRY: cli.retry,
|
|
550
|
+
}
|
|
551
|
+
click_cmd: Optional[ClickCommand] = CMD_DICT.get(command, None)
|
|
552
|
+
if click_cmd is None:
|
|
553
|
+
raise DbtInternalError(f"No command found for name '{command.name}'")
|
|
554
|
+
return format_params(click_cmd.params)
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def format_params(params: List[Parameter]) -> ArgsList:
|
|
558
|
+
return [str(x.name) for x in params if not str(x.name).lower().startswith("deprecated_")]
|